#----------------------------------------------------------------------- # Common AssumeRole policy for these codebuild roles #----------------------------------------------------------------------- data "aws_iam_policy_document" "codebuild_role_assume_role_policy" { statement { effect = "Allow" actions = [ "sts:AssumeRole" ] principals { type = "Service" identifiers = [ "codebuild.amazonaws.com", "events.amazonaws.com" ] } } } #----------------------------------------------------------------------- # "Basic" Codebuild Role - not capable to make EC2 images / run Packer #----------------------------------------------------------------------- resource "aws_iam_role" "codebuild_basic_role" { name = "codebuild_basic_role" path = "/aws_services/" assume_role_policy = data.aws_iam_policy_document.codebuild_role_assume_role_policy.json } resource "aws_iam_role_policy_attachment" "codebuild_basic_role_basic_policy_attach" { role = aws_iam_role.codebuild_basic_role.name policy_arn = aws_iam_policy.codebuild_basic_policy.arn } #----------------------------------------------------------------------- # "Packer" Codebuild Role #----------------------------------------------------------------------- resource "aws_iam_role" "codebuild_packer_role" { name = "codebuild_packer_role" path = "/aws_services/" assume_role_policy = data.aws_iam_policy_document.codebuild_role_assume_role_policy.json } # Packer role needs basic role too for things like cloudwatch resource "aws_iam_role_policy_attachment" "codebuild_packer_role_basic_policy_attach" { role = aws_iam_role.codebuild_packer_role.name policy_arn = aws_iam_policy.codebuild_basic_policy.arn } resource "aws_iam_role_policy_attachment" "codebuild_packer_role_packer_policy_attach" { role = aws_iam_role.codebuild_packer_role.name policy_arn = aws_iam_policy.codebuild_build_ec2_amis_policy.arn } #----------------------------------------------------------------------- # "Basic" Policy for codebuild - can make artifacts and ECR images but not EC2 # FIXME: Not sure about this policy # 2. Lets codebuild (apparently) write to ANY ECR repo # 4. Latest codebuild policies (from AWS console) have report-group resources and actions #----------------------------------------------------------------------- resource "aws_iam_policy" "codebuild_basic_policy" { name = "codebuild_basic_policy" path = "/aws_services/" description = "Policy for AWS codebuild to build AMIs" policy = data.aws_iam_policy_document.codebuild_base_policy.json } data "aws_iam_policy_document" "codebuild_base_policy" { # checkov:skip=CKV_AWS_111: see tfsec aws-iam-no-policy-wildcard ignore comment statement { sid = "WriteCodebuildLogsToCloudwatchLogs" effect = "Allow" resources = [ "arn:${local.aws_partition}:logs:${local.aws_region}:${local.aws_account}:log-group:/aws/codebuild/*" ] actions = [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "StoreArtifactsInBucket" effect = "Allow" resources = [ "arn:${local.aws_partition}:s3:::xdr-codebuild-artifacts/*" ] actions = [ "s3:PutObject", "s3:GetObject*", "s3:ListBucket" ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "UpdateECRRepos" effect = "Allow" resources = [ "*" ] actions = [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:CompleteLayerUpload", "ecr:GetAuthorizationToken", "ecr:InitiateLayerUpload", "ecr:PutImage", "ecr:UploadLayerPart" ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "LetEventBridgeTriggerABuild" effect = "Allow" resources = [ "*" ] actions = [ "codebuild:StartBuild", "codebuild:StopBuild", "codebuild:BatchGet*", "codebuild:Get*", "codebuild:List*" ] } } #----------------------------------------------------------------------- # "EC2" Policy for codebuild - able to build EC2 images / SGs / etc # FIXME: too powerful # # Parts of this are Lifted from # https://www.packer.io/plugins/builders/amazon#iam-task-or-instance-role and # converted from JSON to a terraform data source NOT AUDITED - taking Packer # docs at word that these are "minimal permissions necessary" # # The rest is for EBS+KMS support cobbled from AWS docs #----------------------------------------------------------------------- resource "aws_iam_policy" "codebuild_build_ec2_amis_policy" { name = "codebuild_build_ami_policy" path = "/aws_services/" description = "Policy for AWS codebuild to build AMIs" policy = data.aws_iam_policy_document.codebuild_build_ec2_amis.json } data "aws_iam_policy_document" "codebuild_build_ec2_amis" { # checkov:skip=CKV_AWS_107: IAM policies does not allow credentials exposure for ECR # checkov:skip=CKV_AWS_109: see tfsec aws-iam-no-policy-wildcard ignore comment # checkov:skip=CKV_AWS_110: IAM policies does not allow privilege escalation # checkov:skip=CKV_AWS_111: see tfsec aws-iam-no-policy-wildcard ignore comment # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "BuildEC2AMIFromPackerDocs" effect = "Allow" resources = [ "*" ] actions = [ "ec2:AttachVolume", "ec2:AuthorizeSecurityGroupIngress", "ec2:CopyImage", "ec2:CreateImage", "ec2:CreateKeypair", "ec2:CreateSecurityGroup", "ec2:CreateSnapshot", "ec2:CreateTags", "ec2:CreateVolume", "ec2:CreateNetworkInterface", "ec2:CreateNetworkInterfacePermission", "ec2:DeleteKeyPair", "ec2:DeleteNetworkInterface", "ec2:DeleteSecurityGroup", "ec2:DeleteSnapshot", "ec2:DeleteVolume", "ec2:DeregisterImage", "ec2:Describe*", "ec2:DetachVolume", "ec2:GetPasswordData", "ec2:ModifyImageAttribute", "ec2:ModifyInstanceAttribute", "ec2:ModifySnapshotAttribute", "ec2:RegisterImage", "ec2:RunInstances", "ec2:StopInstances", "ec2:TerminateInstances" ] } statement { sid = "BuildEC2WithInstanceRole" effect = "Allow" # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account resources = [ "*" ] actions = [ "iam:PassRole" ] } statement { sid = "PullFromSecretsManager" effect = "Allow" resources = [ "arn:${local.aws_partition}:secretsmanager:${local.aws_region}:${local.aws_account}:secret:msoc-build*", "arn:${local.aws_partition}:secretsmanager:${local.aws_region}:${local.aws_account}:secret:mdr-aws-codebuild*" ] actions = [ "secretsmanager:GetSecretValue" ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "KMSAccessNeededForEBS" effect = "Allow" resources = [ "*" ] actions = [ "kms:RevokeGrant", "kms:ListGrants", "kms:Decrypt", "kms:DescribeKey", "kms:GenerateDataKeyWithoutPlainText", "kms:ReEncrypt*", ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "SSMCodeBuildPause" effect = "Allow" resources = [ "*" ] actions = [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ] } # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account statement { sid = "CreateGrantForEBS" effect = "Allow" resources = ["*"] actions = [ "kms:CreateGrant", ] condition { test = "Bool" variable = "kms:GrantIsForAWSResource" values = ["true"] } } }