AWS CodeBuild VPC_CLIENT_ERROR: Unexpected EC2 error: UnauthorizedOperation

I created CodeBuild project in a custom VPC and in private subnet. Private subnet has internet access, also AWS console confirms that internet connection is for this code build project. I keep getting VPC_CLIENT_ERROR: Unexpected EC2 error: UnauthorizedOperation error in "Provisioning" phase of the build. There must be something missing in my service role policy but cant figure out what.

Here is CodeBuild project (terraform):

resource "aws_codebuild_project" "frontend" {
  name          = "frontend"
  build_timeout = "5"
  service_role  = "${aws_iam_role.frontend_build.arn}"

  artifacts {
    type = "S3"
    location = "frontend.myapp.com"
    namespace_type = "NONE"
    packaging = "NONE"
    path = "public"
  }

  environment {
    compute_type                = "BUILD_GENERAL1_SMALL"
    image                       = "aws/codebuild/standard:1.0"
    type                        = "LINUX_CONTAINER"
    image_pull_credentials_type = "CODEBUILD"

    environment_variable {
      name  = "SOME_KEY1"
      value = "SOME_VALUE1"
    }
  }

  logs_config {
    cloudwatch_logs {
      group_name = "build"
      stream_name = "frontend-build"
    }
  }

  source {
    type            = "GITHUB"
    location        = "https://github.com/MyOrg/my-repo.git"
    git_clone_depth = 1
    report_build_status = true
    auth {
      type = "OAUTH"
    }
  }

  vpc_config {
    vpc_id = module.vpc.vpc_id
    subnets = module.vpc.private_subnets
    security_group_ids = [aws_security_group.build.id]
  }
}

Here is service_role for this CodeBuild project:

resource "aws_iam_role" "frontend_build" {
  name = "frontend-build"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "codebuild.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

And here is policy for that role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:CreateNetworkInterfacePermission",
            "Resource": "arn:aws:ec2:us-east-1:371508653482:network-interface/*",
            "Condition": {
                "StringEquals": {
                    "ec2:AuthorizedService": "codebuild.amazonaws.com",
                    "ec2:Subnet": "subnet-124641af7a83bf872"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeVpcs",
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart",
                "ecs:RunTask",
                "iam:PassRole",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ssm:GetParameters"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:GetAuthorizationToken",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "ecr:BatchCheckLayerAvailability"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::xxx-frontend-build-logs",
                "arn:aws:s3:::xxx-frontend-build-logs/*"
            ]
        }
    ]
}

Here is security group for CodeBuild project:

resource "aws_security_group" "build" {
  name   = "build"
  vpc_id = module.vpc.vpc_id
}

resource "aws_security_group_rule" "build_egress" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.build.id
}

Answers 1

  • It looks to me that CodeBuild service role is unable to create the ENI in VPC. The problem seems to be with this line in the CodeBuild role policy:

    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": "ec2:CreateNetworkInterfacePermission",
        "Resource": "arn:aws:ec2:us-east-1:371508653482:network-interface/*",
        "Condition": {
            "StringEquals": {
                "ec2:AuthorizedService": "codebuild.amazonaws.com",
                "ec2:Subnet": "subnet-124641af7a83bf872"     <================= Need full ARN here
            }
        }
    },
    

    Instead of:

    "Condition": {
            "StringEquals": {
                "ec2:AuthorizedService": "codebuild.amazonaws.com",
                "ec2:Subnet": "subnet-124641af7a83bf872"
            }
    }
    

    try...

    "Condition": {
        "StringEquals": {
        "ec2:Subnet": [
            "arn:aws:ec2:region:account-id:subnet/subnet-124641af7a83bf872"
        ],
        "ec2:AuthorizedService": "codebuild.amazonaws.com"
    }
    

    Details here: [1]

    Ref: [1] Using Identity-Based Policies for CodeBuild - Allow CodeBuild Access to AWS Services Required to Create a VPC Network Interface - https://docs.aws.amazon.com/codebuild/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html#customer-managed-policies-example-create-vpc-network-interface


Related Articles