Example IAM and Policies for Terraform
The below code is used to define AWS IAM roles which are going to be used for federated access, which means another application can assume the role. In this case it's Github and a specific repository is enable to assume the role which has a number of IAM policies assigned.
# GitHub Deployer Role
resource "aws_iam_role" "iam-oidc-role" {
name = "prd-clops-net-ss-nhs-uk-iam-dep-role"
max_session_duration = 3600
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::588554574523:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:emisgroup/emissharedservice_nhs-uk_route53:*"
}
}
}
]
}
EOF
}
resource "aws_iam_policy" "iam-gh-deployer-policy-1" {
name = "prd-clops-net-ss-nhs-uk-iam-dep-pol-1"
path = "/"
description = "Prod NHS.UK Domain Deployer Policy 1"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
"Sid" : "VisualEditor0",
"Effect" : "Allow",
"Action" : [
"dynamodb:PutItem",
"dynamodb:DescribeTable",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:DescribeContinuousBackups",
"dynamodb:Scan",
"dynamodb:ListTagsOfResource",
"dynamodb:Query",
"dynamodb:UpdateItem",
"dynamodb:DescribeTimeToLive"
],
"Resource" : "arn:aws:dynamodb:eu-west-2:${var.aws_account}:table/${var.dynamodb-statelock}"
},
{
"Sid" : "VisualEditor1",
"Effect" : "Allow",
"Action" : [
"iam:CreateInstanceProfile",
"iam:GetPolicyVersion",
"iam:TagRole",
"iam:RemoveRoleFromInstanceProfile",
"iam:DeletePolicy",
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:AddRoleToInstanceProfile",
"iam:ListInstanceProfilesForRole",
"iam:PassRole",
"iam:DetachRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:CreatePolicyVersion",
"iam:ListPolicies",
"iam:DeleteInstanceProfile",
"iam:GetRole",
"iam:GetInstanceProfile",
"iam:GetPolicy",
"iam:DeleteRole",
"iam:TagPolicy",
"iam:CreatePolicy",
"iam:CreateServiceLinkedRole",
"iam:ListPolicyVersions",
"iam:GetRolePolicy",
"iam:TagInstanceProfile"
],
"Resource" : "*"
},
{
"Sid" : "VisualEditor3",
"Effect" : "Allow",
"Action" : [
"s3:ListBucket",
"s3:*Object"
],
"Resource" : "arn:aws:s3:::${var.s3-statefile}/state/*"
},
{
"Sid" : "VisualEditor4",
"Action" : "s3:ListBucket",
"Effect" : "Allow",
"Resource" : "arn:aws:s3:::${var.s3-statefile}"
},
{
"Sid" : "VisualEditor5",
"Effect" : "Allow",
"Action" : "ssm:GetParameters",
"Resource" : "*"
}
]
})
}
# Network Stuff
# GitHub Deployer Role Policy
resource "aws_iam_policy" "iam-gh-deployer-policy-2" {
name = "prd-clops-net-ss-nhs-uk-iam-dep-pol-2"
path = "/"
description = "Prod NHS.UK Domain Deployer Policy 2"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
"Sid" : "VisualEditor0",
"Effect" : "Allow",
"Action" : [
"ec2:CreateTransitGatewayConnect",
"ec2:CreateTransitGatewayRouteTable",
"ec2:ModifyTransitGateway",
"ec2:DescribeTransitGatewayRouteTableAnnouncements",
"ec2:RejectTransitGatewayMulticastDomainAssociations",
"ec2:CreateTransitGatewayConnectPeer",
"ec2:AcceptTransitGatewayVpcAttachment",
"ec2:DescribeTransitGatewayConnectPeers",
"ec2:CreateTransitGateway",
"ec2:CreateTransitGatewayPrefixListReference",
"ec2:SearchTransitGatewayRoutes",
"ec2:CreateTransitGatewayPeeringAttachment",
"ec2:DeleteTransitGatewayVpcAttachment",
"ec2:ModifyTransitGatewayPrefixListReference",
"ec2:CreateTransitGatewayMulticastDomain",
"ec2:AssociateTransitGatewayRouteTable",
"ec2:DescribeTransitGatewayMulticastDomains",
"ec2:RejectTransitGatewayVpcAttachment",
"ec2:DeleteTransitGatewayRouteTableAnnouncement",
"ec2:DisassociateTransitGatewayRouteTable",
"ec2:DisassociateTransitGatewayPolicyTable",
"ec2:DisableTransitGatewayRouteTablePropagation",
"ec2:DeleteTransitGatewayPeeringAttachment",
"ec2:DeregisterTransitGatewayMulticastGroupMembers",
"ec2:CreateTransitGatewayRouteTableAnnouncement",
"ec2:GetTransitGatewayAttachmentPropagations",
"ec2:CreateTransitGatewayPolicyTable",
"ec2:DeleteTransitGatewayRouteTable",
"ec2:CreateTransitGatewayRoute",
"ec2:DeleteTransitGatewayRoute",
"ec2:DescribeTransitGatewayAttachments",
"ec2:CreateTransitGatewayVpcAttachment",
"ec2:GetTransitGatewayRouteTablePropagations",
"ec2:EnableTransitGatewayRouteTablePropagation",
"ec2:DeleteTransitGateway",
"ec2:DescribeTransitGatewayPeeringAttachments",
"ec2:DescribeTransitGatewayPolicyTables",
"ec2:DeleteTransitGatewayPrefixListReference",
"ec2:ExportTransitGatewayRoutes",
"ec2:DeleteTransitGatewayPolicyTable",
"ec2:AcceptTransitGatewayPeeringAttachment",
"ec2:DescribeTransitGateways",
"ec2:ReplaceTransitGatewayRoute",
"ec2:DeleteTransitGatewayMulticastDomain",
"ec2:GetTransitGatewayPolicyTableEntries",
"ec2:RejectTransitGatewayPeeringAttachment",
"ec2:RegisterTransitGatewayMulticastGroupSources",
"ec2:DescribeTransitGatewayRouteTables",
"ec2:DeregisterTransitGatewayMulticastGroupSources",
"ec2:SearchTransitGatewayMulticastGroups",
"ec2:GetTransitGatewayRouteTableAssociations",
"ec2:DeleteTransitGatewayConnectPeer",
"ec2:ModifyTransitGatewayVpcAttachment",
"ec2:DisassociateTransitGatewayMulticastDomain",
"ec2:AssociateTransitGatewayMulticastDomain",
"ec2:GetTransitGatewayPrefixListReferences",
"ec2:DescribeTransitGatewayConnects",
"ec2:RegisterTransitGatewayMulticastGroupMembers",
"ec2:AssociateTransitGatewayPolicyTable",
"ec2:DeleteTransitGatewayConnect",
"ec2:DescribeTransitGatewayVpcAttachments",
"ec2:GetTransitGatewayPolicyTableAssociations",
"ec2:GetTransitGatewayMulticastDomainAssociations",
"ec2:AcceptTransitGatewayMulticastDomainAssociations",
"ec2:CreateFlowLogs"
],
"Resource" : "*"
},
{
"Sid" : "VisualEditor1",
"Effect" : "Allow",
"Action" : [
"ec2:DeleteSubnet",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DescribeInstances",
"ec2:DeleteVpcEndpoints",
"ec2:CreateTransitGatewayRouteTable",
"ec2:AttachInternetGateway",
"ec2:CreateTransitGateway",
"ec2:DeleteRouteTable",
"ec2:AssociateRouteTable",
"ec2:DescribeInternetGateways",
"ec2:SearchTransitGatewayRoutes",
"ec2:DeleteTransitGatewayVpcAttachment",
"ec2:CreateRoute",
"ec2:CreateInternetGateway",
"ec2:RevokeSecurityGroupEgress",
"ec2:DescribeVolumes",
"ec2:AssociateTransitGatewayRouteTable",
"ec2:DeleteInternetGateway",
"ec2:DeleteVpnConnection",
"ec2:DescribeNetworkAcls",
"ec2:DescribeRouteTables",
"ec2:DisassociateTransitGatewayRouteTable",
"ec2:DisableTransitGatewayRouteTablePropagation",
"ec2:DescribeVpnConnections",
"ec2:CreateTags",
"ec2:CreateRouteTable",
"ec2:DeleteNetworkInterface",
"ec2:RunInstances",
"ec2:CreateCustomerGateway",
"ec2:DetachInternetGateway",
"ec2:DescribePrefixLists",
"ec2:DisassociateRouteTable",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DeleteTransitGatewayRouteTable",
"ec2:CreateNetworkInterface",
"ec2:CreateTransitGatewayRoute",
"ec2:DeleteTransitGatewayRoute",
"ec2:CreateTransitGatewayVpcAttachment",
"ec2:DescribeTransitGatewayAttachments",
"ec2:DescribeSecurityGroupRules",
"ec2:GetTransitGatewayRouteTablePropagations",
"ec2:DescribeInstanceTypes",
"ec2:DescribeVpcEndpoints",
"ec2:DeleteVpc",
"ec2:EnableTransitGatewayRouteTablePropagation",
"ec2:CreateSubnet",
"ec2:DeleteTransitGateway",
"ec2:AssociateAddress",
"ec2:DescribeSubnets",
"ec2:ModifyVpcEndpoint",
"ec2:CreateVpnConnection",
"ec2:DisassociateAddress",
"ec2:DescribeAddresses",
"ec2:DeleteTags",
"ec2:DescribeInstanceAttribute",
"ec2:ModifyVpnConnection",
"ec2:CreateVpc",
"ec2:DescribeTransitGateways",
"ec2:DescribeAddressesAttribute",
"ec2:DescribeVpcAttribute",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeTransitGatewayRouteTables",
"ec2:CreateSecurityGroup",
"ec2:ModifyVpcAttribute",
"ec2:ModifyInstanceAttribute",
"ec2:GetTransitGatewayRouteTableAssociations",
"ec2:ReleaseAddress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:TerminateInstances",
"ec2:DetachNetworkInterface",
"ec2:DescribeTags",
"ec2:DescribeCustomerGateways",
"ec2:DescribeSecurityGroups",
"ec2:AllocateAddress",
"ec2:DeleteCustomerGateway",
"ec2:CreateVpcEndpoint",
"ec2:DescribeVpcs",
"ec2:DeleteSecurityGroup",
"ec2:AttachNetworkInterface",
"ec2:DescribeTransitGatewayVpcAttachments",
"ec2:RevokeSecurityGroupIngress"
],
"Resource" : "*"
}
]})
}
# DNS Stuff
resource "aws_iam_policy" "iam-gh-deployer-policy-3" {
name = "prd-clops-net-ss-nhs-uk-iam-dep-pol-3"
path = "/"
description = "Prod NHS.UK Domain Deployer Policy 3"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Route53HostedZoneAndRecords"
Effect = "Allow"
Action = [
"route53:CreateHostedZone",
"route53:DeleteHostedZone",
"route53:GetHostedZone",
"route53:ListHostedZones",
"route53:UpdateHostedZoneComment",
"route53:ListHostedZonesByName",
"route53:GetHostedZoneCount",
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
]
Resource = "*"
},
{
Sid = "Route53ResolverManagement"
Effect = "Allow"
Action = [
"route53resolver:CreateResolverEndpoint",
"route53resolver:DeleteResolverEndpoint",
"route53resolver:GetResolverEndpoint",
"route53resolver:ListResolverEndpoints",
"route53resolver:UpdateResolverEndpoint",
"route53resolver:AssociateResolverRule",
"route53resolver:DisassociateResolverRule",
"route53resolver:CreateResolverRule",
"route53resolver:DeleteResolverRule",
"route53resolver:GetResolverRule",
"route53resolver:ListResolverRules",
"route53resolver:UpdateResolverRule"
]
Resource = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "iam-attach-perms-policy-1" {
role = aws_iam_role.iam-oidc-role.name
policy_arn = aws_iam_policy.iam-gh-deployer-policy-1.arn
}
resource "aws_iam_role_policy_attachment" "iam-attach-perms-policy-2" {
role = aws_iam_role.iam-oidc-role.name
policy_arn = aws_iam_policy.iam-gh-deployer-policy-2.arn
}
resource "aws_iam_role_policy_attachment" "iam-attach-perms-policy-3" {
role = aws_iam_role.iam-oidc-role.name
policy_arn = aws_iam_policy.iam-gh-deployer-policy-3.arn
}
Last updated