CodePipeline deployment to Beanstalk fails despite IAM properly set up - amazon-web-services

Context
This was a CodeStar project initially, and then it grew into something bigger. We reused the Beanstalk application to create the stage and prod environments and kept the initially-created dev environment as-is.
We updated the CodePipeline to deploy to our new environments using "Elastic Beanstalk" as the Provider. (While CodeStar had setup a deployment using CloudFormation for the environment it automatically provisioned in the Beanstalk application.)
The problem
The deployment fails due to an error which mentions autoscaling:DescribeAutoScalingGroups as not being authorized to be executed by the CodePipeline's IAM Role.
Here is the whole error message displayed in CodePipeline:
Insufficient permissions
Deployment failed.
The provided role does not have sufficient permissions: User:
arn:aws:sts::xxx:assumed-role/CodeStarWorker-xxx-on-cod-ToolChain/yyy
is not authorized to perform: autoscaling:DescribeAutoScalingGroups
(Service: AmazonAutoScaling; Status Code: 403; Error Code:
AccessDenied; Request ID: 905ee6ef-d75d-4cf8-b5f3-e6b16a5f6477)
Service:AmazonAutoScaling, Message:User:
arn:aws:sts::xxx:assumed-role/CodeStarWorker-xxx-on-cod-ToolChain/yyy
is not authorized to perform: autoscaling:DescribeAutoScalingGroups
Failed to deploy application.
Service:AmazonAutoScaling, Message:User:
arn:aws:sts::xxx:assumed-role/CodeStarWorker-xxx-on-cod-ToolChain/yyy
is not authorized to perform: autoscaling:DescribeAutoScalingGroups
IAM
Here is the CodePipeline Role's content (aka CodeStarWorker-xxx-on-cod-ToolChain):
And here is the associated Permission Boundary (originally generated by CodeStar, and eventually updated by us to try to get this whole thing to work):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ssm:GetParameters",
"Resource": "*",
"Condition": {
"StringEquals": {
"ssm:ResourceTag/awscodestar:projectArn": "arn:aws:codestar:yyy:xxx:project/xxx-on-cod"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:CreateBucket",
"iam:PassRole",
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:s3:::aws-codestar-yyy-xxx/xxx-on-cod/ssh/*",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx/*",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx",
"arn:aws:s3:::awscodestar-remote-access-yyy/*",
"arn:aws:s3:::awscodestar-remote-access-signatures-yyy/*",
"arn:aws:iam::xxx:role/CodeStarWorker-xxx-on-cod-CloudFormation",
"arn:aws:secretsmanager:yyy:xxx:secret:xxx"
]
},
{
"Sid": "VisualEditor4",
"Effect": "Allow",
"Action": [
"s3:*",
"codebuild:*",
"ec2:Describe*",
"ec2:*SecurityGroup*",
"iam:PassRole"
],
"Resource": [
"*"
]
},
{
"Sid": "VisualEditor14",
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": [
"arn:aws:logs:yyy:xxx:log-group:/aws/elasticbeanstalk/*"
]
},
{
"Sid": "VisualEditor6",
"Effect": "Allow",
"Action": [
"elasticbeanstalk:CreateApplicationVersion",
"elasticbeanstalk:UpdateEnvironment"
],
"Resource": [
"*"
]
},
{
"Sid": "VisualEditor5",
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:SuspendProcesses",
"autoscaling:ResumeProcesses",
"autoscaling:DescribeScalingActivities"
],
"Resource": [
"arn:aws:autoscaling:yyy:xxx:autoScalingGroup:*"
]
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"sns:Get*",
"sns:Publish",
"logs:DescribeLogGroups",
"cloudtrail:StartLogging",
"lambda:ListFunctions",
"cloudtrail:CreateTrail",
"sns:Subscribe",
"xray:Put*",
"logs:CreateLogGroup",
"logs:PutLogEvents",
"sns:List*"
],
"Resource": "*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": "*",
"Resource": [
"arn:aws:cloudformation:yyy:xxx:stack/awseb-e-mjdwv9ptcz-stack/2d588c80-5284-11ea-a1d4-068f4db663b8",
"arn:aws:cloudformation:yyy:xxx:stack/awseb-e-mjdwv9ptcz-stack/2d588c80-5284-11ea-a1d4-068f4db663b8/*",
"arn:aws:cloudformation:yyy:xxx:stack/awscodestar-xxx-on-cod-*",
"arn:aws:codebuild:yyy:xxx:project/xxx-on-cod",
"arn:aws:codecommit:yyy:xxx:xxx-on-codecommit",
"arn:aws:codepipeline:yyy:xxx:xxx-on-cod-Pipeline",
"arn:aws:elasticbeanstalk:yyy:xxx:*/xxx-on-cod*",
"arn:aws:s3:::aws-codestar-yyy-xxx-xxx-on-cod-pipe",
"arn:aws:s3:::aws-codestar-yyy-xxx-xxx-on-cod-pipe/*",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx/resources/environments/e-fp3mwptx9q",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx/resources/environments/e-fp3mwptx9q/*",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx/resources/environments/e-mjdwv9ptcz",
"arn:aws:s3:::elasticbeanstalk-yyy-xxx/resources/environments/e-mjdwv9ptcz/*"
]
}
]
}
Pipeline
As you can see, we have two CodeBuild because the first one is the one set up by CodeStar, and the second one is the one that slightly modifies the output artefact so that it is in the right format for a direct upload into Beanstalk.
The succeeded deployment is the one from CodeStar (using CloudFormation Provider), the next one is the failed one (using Beanstalk Provider).
CodeStar CodeBuild (buildspec.yml)
The output artefact is used by the CloudFormation deployment:
version: 0.2
phases:
install:
runtime-versions:
java: openjdk8
commands:
# Upgrade AWS CLI to the latest version
- pip install --upgrade awscli
pre_build:
commands:
- cd $CODEBUILD_SRC_DIR
- mvn clean compile test
build:
commands:
- mvn war:exploded
post_build:
commands:
- cp -r .ebextensions/ target/ROOT/
- aws cloudformation package --template template.yml --s3-bucket $S3_BUCKET --output-template-file template-export.yml
# Do not remove this statement. This command is required for AWS CodeStar projects.
# Update the AWS Partition, AWS Region, account ID and project ID in the project ARN on template-configuration.json file so AWS CloudFormation can tag project resources.
- sed -i.bak 's/\$PARTITION\$/'${PARTITION}'/g;s/\$AWS_REGION\$/'${AWS_REGION}'/g;s/\$ACCOUNT_ID\$/'${ACCOUNT_ID}'/g;s/\$PROJECT_ID\$/'${PROJECT_ID}'/g' template-configuration.json
artifacts:
type: zip
files:
- target/ROOT/**/*
- .ebextensions/**/*
- 'template-export.yml'
- 'template-configuration.json'
Our CodeBuild (buildspec-two.yml)
The output artefact is used by the (failing) Beanstalk deployment:
# Everything up to that point is the very same as the code from above
artifacts:
type: zip
base-directory: 'target/ROOT'
files:
- ./**/*
- .ebextensions/**/*
Conclusion
I've no idea how the deployment could fail since both the Permission Boundary and the base IAM Role mention that autoscaling:DescribeAutoScalingGroups.
Moreover, the deployment to the CodeStar environment is running fine, yet that particular environment which fails the deployment comes from an exact replicate (in terms of configuration).
Any ideas?
(Moreover, the initial dev environment, just as much as the newly-created stage environment, don't even have an AutoScalingGroup associated to them... so I have no idea why the deployment is even trying to do that.)
(And I've looked in S3 to make sure both Artefacts being deployed have the same structure.)

This is a tough one to troubleshoot, but from what I can see there are a couple of potential issues. One is that the 'DescribeAutoScalingGroups' action does not support a resource-level permission, so it must be an asterisk as the resource, and not the resource arn. You could try just removing the:
"Resource": [
"arn:aws:autoscaling:yyy:xxx:autoScalingGroup:*"
]
in the permissions boundary, and replace it with
"Resource": [
"*"
]
and see if that solves the issue.
Second, the 'AWSCodeDeployFullAccess' role does not contain the 'DescribeAutoScalingGroups' action in the policy. You may need to replace and/or add the 'AWSCodeDeployRole' to be able to use that action. That might solve it.
CodeStar projects are pretty locked down when it comes to permissions, so it can get pretty complex expanding the project. Check here:
https://docs.aws.amazon.com/codestar/latest/userguide/add-iam-role.html
and here:
https://docs.aws.amazon.com/codestar/latest/userguide/adh-policy-examples.html

Related

Pushing Docker Image to Another Account's ECR from AWS Codebuild

I'm trying to build a docker image from a Pipeline account and push it into the ECR of another account (Dev).
While I'm able to docker push from codebuild to an ECR repo within the same account (Pipeline), I'm having difficulty doing this for an external AWS account ECR.
The policy attached to the ECR repo on the Dev account:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<pipelineAccountID>:role/service-role/<codebuildRole>"
},
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
}
]
}
On my pipeline account, the service role running the build project matches the ARN on the policy above, and my buildspec contains the following snippet that pushes the image:
- $(aws ecr get-login --no-include-email --region us-east-1 --registry-ids <DevAccount>)
- docker tag <imageName>:latest $ECR_REPO_DEV:latest
- docker push $ECR_REPO_DEV:latest
Codebuild is able to log into ECR successfully, but when it tries to actually push the image, I get:
*denied: User: arn:aws:sts::<pipelineAccountID>:assumed-role/<codebuildRole>/AWSCodeBuild-413cfca0-133a-4f37-b505-a94668201e26 is not authorized to perform: ecr:InitiateLayerUpload on resource: arn:aws:ecr:us-east-1:<DevAccount>:repository/<repo>*
Additionally, I've gone ahead and made sure that the IAM policy for role (residing on the codepipeline account) has permissions for this repo:
{
"Sid": "CrossAccountRepo",
"Effect": "Allow",
"Action": "ecr:*",
"Resource": "arn:aws:ecr:us-east-1:<DevAccount>:repository/sg-api"
}
I have little idea now on what I could be missing. The only thing that comes to mind is having the build run with a cross-account role but I'm not even sure that's possible. My goal is to have the build pipeline separate from the dev. account as I hear that's best practice.
Suggestions?
Thanks in advance.
Based on my understanding of this and the error message above, the most common cause is that the ECR repository does not have a policy which would allow the CodeBuild IAM role to access it.
Please set this policy on the ECR Repo:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountPush",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<dev acount>:root"
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
}
]
}
Ref: https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-policy-examples.html#IAM_allow_other_accounts
Please add this policy on the CodeBuild service role:
{
"Sid": "CrossAccountRepo",
"Effect": "Allow",
"Action": "ecr:*",
"Resource": "*"
}

The provided role does not have sufficient permissions to access CodeDeploy

I am implementing CodePipeline; using GitHub, CodeBuild and Amazon ECS (blue/green). The role I am using, is the one generated by the Pipeline: ecsTaskExecutionRole
When generated, it is equipped with the following policies:
AmazonECSTaskExecutionRolePolicy (containing the following actions):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]}
And the following Trust relationships:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"codebuild.amazonaws.com",
"ecs-tasks.amazonaws.com",
]
},
"Action": "sts:AssumeRole"
}
]
}
Given that the role is auto-generated, one would assume that either it would have ALL the necessary permissions (for the pipeline to function) OR AWS would have a guide on which permissions to assign (to either a policy OR the trust relationship configuration).
Despite, updating the trust relationship to include:
"Service": [
"codebuild.amazonaws.com",
"ecs-tasks.amazonaws.com",
"ec2.amazonaws.com",
"codedeploy.amazonaws.com",
"codepipeline.amazonaws.com",
"s3.amazonaws.com"
]
I still get the error:
I have seen this issue raised in multiple blogs/forum, spanning the past 1-2 years; it's incredible that this is still not properly documented as part of the AWS tutorials (or relative blogs).
"The provided role does not have sufficient permissions to access CodeDeploy"
This error suggests the CodePipeline role is missing "codedeploy:" related permissions.
Can you please add
codedeploy:*
to the role and try again.
If you do not want to add all CodeDeploy permissions, you will need to investigate 'AccessDenied' calls in Cloudtrail and allow just those. Usually these are the required ones:
{
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetApplication",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:RegisterApplicationRevision"
],
"Resource": "*",
"Effect": "Allow"
},
The default "CodePipeline Service Role Policy" is documented here:
[1] Manage the CodePipeline Service Role - Review the Default CodePipeline Service Role Policy - https://docs.aws.amazon.com/codepipeline/latest/userguide/how-to-custom-role.html#view-default-service-role-policy

Unsettled Promises in AWS Lambda from SSM Parameters

I am using the serverless framework to deploy and program my aws lambda function and since my function is ready for production I need to remove the sensitive keys and decided to use aws systems manager (ssm parameter store) to use these keys in a secure manner, but on deployment, I receive the following error message related to the use of these keys. I thought it might be something related to the Iam Role that I manually associated with the lambda, but I'm not sure what would be off with it.
Error:
Serverless Information ----------------------------------
##########################################################################################
# 47555: 0 of 2 promises have settled
# 47555: 2 unsettled promises:
# 47555: ssm:mg-production-domain~true waited on by: undefined
# 47555: ssm:mg-production-api-key~true waited on by: undefined
# This can result from latent connections but may represent a cyclic variable dependency
##########################################################################################
YAML:
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-1
environment:
MG_PRODUCTION_DOMAIN: ${ssm:mg-production-domain~true}
MG_PRODUCTION_API_KEY: ${ssm:mg-production-api-key~true}
Here is the Iam Role policy I added to the lambda, but I believe there is probably a better way to do this by adding the Iam Role via the YAML file:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ssm:DescribeParameters",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ssm:GetParameters",
"Resource": "arn:aws:ssm:us-east-1:*account-id*:parameter/*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "ssm:GetParameter",
"Resource": "arn:aws:ssm:us-east-1:*account-id*:parameter/*"
}
]
}

Code Build Access denied while downloading artifact from S3

My CodeBuild is configured with CodePipeline. S3 is my artifact store. I continue to get an Access denied message despite having attached IAM roles with sufficient access.
Screenshot of the error message
I have already checked the service role associated with Codebuild. It has the following policy attached to it.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"arn:aws:logs:ap-southeast-1:682905754632:log-group:/aws/codebuild/Build",
"arn:aws:logs:ap-southeast-1:682905754632:log-group:/aws/codebuild/Build:*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::codepipeline-ap-southeast-1-*"
],
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion"
]
}
]
}
But when I test it using the IAM policy validator I get the following error message.
Based on the accepted answer to this question the policy that I currently have should allow me to get the artifacts from S3 without any problems - AWS Codebuild fails while downloading source. Message: Access Denied
How do I get rid of the access denied message?
This generally happens when you have a CodeBuild project already and you integrate it to a CodePipeline pipeline. When you integrate a Codebuild project with CodePipeline, the project will retrieve it's source from the CodePipeline Source output. Source output will be stored in the artifact store location, which is an S3 bucket, either a default bucket created by CodePipeline or one you specify upon pipeline creation.
So, you will need to provide permissions to the CodeBuild Service role to access the CodePipline bucket in S3. The role will require permissions to put S3 objects in the bucket, as well as get objects.
Policy which i tried and same is working:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CodeBuildDefaultPolicy",
"Effect": "Allow",
"Action": [
"codebuild:*",
"iam:PassRole"
],
"Resource": "*"
},
{
"Sid": "CloudWatchLogsAccessPolicy",
"Effect": "Allow",
"Action": [
"logs:FilterLogEvents",
"logs:GetLogEvents"
],
"Resource": "*"
},
{
"Sid": "S3AccessPolicy",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:GetObject",
"s3:List*",
"s3:PutObject"
],
"Resource": "*"
}
]
}
Policy Simulator
AWS Reference

Serveless Framework and CodeBuild : Missing required key 'Bucket' in params

I'm having problems getting AWS CodeBuild to Build and Deploy a project created using Serverless Framework.
Here is the story so far.
Initialise the project
I've followed the docs to create the beginnings of a Serverless project and left "as is" - basically, "Hello World".
I've then put the project in a git repo.
Test deploy from CLI
Then, from the CLI, I've called...
serverless deploy
...and as expected the lambda has been deployed. A good start.
CodeBuild
Next on the agenda was to have a go at building and deploying using AWS CodeBuild.
I've added a buildspec.yml file in the root of the project:
version: 0.1
phases:
install:
commands:
- npm install
- npm install -g serverless
- echo install done
build:
commands:
- serverless deploy
- echo build done
Then, using the AWS Console/Web Interface, I've defined a code build project which references the git repo.
When doing so AWS created an IAM Role with the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"arn:aws:logs:eu-west-1:************:log-group:/aws/codebuild/my-api-build",
"arn:aws:logs:eu-west-1:************:log-group:/aws/codebuild/my-api-build:*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::codepipeline-eu-west-1-*"
],
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion"
]
},
{
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-api-artifacts/*"
],
"Action": [
"s3:PutObject"
]
}
]
}
Let's do this...
So I pressed "Start Build" on the CodeBuild project and got the following errors:
Error 1:
ServerlessError: User: arn:aws:sts::************:assumed-role/codebuild-my-api-build-service-role/AWSCodeBuild-********-****-****-****-************ is not authorized to perform: cloudformation:DescribeStackResources on resource: arn:aws:cloudformation:eu-west-1:************:stack/my-api-development/*
which I "fixed" by adding the following to the policy created by code build...
{
"Effect": "Allow",
"Resource": [
"arn:aws:cloudformation:eu-west-1:*"
],
"Action": [
"cloudformation:*"
]
}
Error 2:
Pressed Start Build again and got:
An error occurred while provisioning your stack: ServerlessDeploymentBucket - API: s3:CreateBucket Access Denied.
which I "fixed" by adding the following to the policy created by code build...
{
"Effect": "Allow",
"Resource": [
"arn:aws:cloudformation:eu-west-1:*"
],
"Action": [
"cloudformation:*"
]
}
Error 3:
Serverless Error ---------------------------------------
Missing required key 'Bucket' in params
Finally: My actual question(s)
What does Missing required key 'Bucket' in params mean? Where should I be looking?
Are my "fixes" to Error 1 and 2 OK? I'm Bit of an AWS and therefore IAM newbie so I'm not that confident when editing policies.
#Unsigned - Thanks for the comment.
Although your recommendation to delete and redeploy didn't work the link you posted did mention having S3 privileges.
I added Full S3 Access to my code build role and k'boom, it worked.
I solved this problem, by adding(editing) stage: prod into serverless.yml.
finally, it looks like this.
provider:
name: aws
runtime: python3.6
stage: prod
credentials:
accessKeyId: <your-access-id>
secretAccessKey: <your-secret-access-key>