The issue
Testing AWS CodeBuild jobs locally using the AWS CodeBuild agent can save you a lot of time. But I couldn’t find a solution how to use the “famous” API call assumeRole inside of a local AWS CodeBuild run. This can be needed, e.g. if you want to build a Docker image inside of AWS CodeBuild and then upload the image to AWS ECR using temporary credentials. When running such a AWS CodeBuild job in AWS this is not a problem as you can attach an IAM Role to you AWS CodeBuild. On local machine this looks differently as your not running the commands inside of AWS.
The solution
Run assumeRole on your local machine (where you are already logged in to AWS). Then pass the AWS STS credentials to the AWS CodeBuild agent via text file which will be parsed as environment variables then.
Note: passing credentials as environment variables to a Docker image is not secure and suggested. But only for local short-term testing as it was in my case I found this solution acceptable as the credentials didn’t leave my local machine.
So let’s start:
This snippet runs assumeRole and then saves the AWS STS credentials in a textfile creds.txt.
TEMP_ROLE=$(aws sts assume-role \ --role-arn "arn:aws:iam::123456789:role/Role123" \ --role-session-name "ECR" \ --profile NEEDED_IF_NON_DEFAULT_PROFILE_SHOULD_BE_USED) echo "AWS_ACCESS_KEY_ID=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.AccessKeyId')" > creds.txt echo "AWS_SECRET_ACCESS_KEY=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SecretAccessKey')" >> creds.txt echo "AWS_SESSION_TOKEN=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SessionToken')" >> creds.txt
Now you can run CodeBuild and pass the txt file, e.g.:
./codebuild_build.sh -i public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0 -a /tmp/tmp_dir -e creds.txt
As the AWS STS credentials are available as environment variables you just have to run the usual command to log in to AWS ECR, e.g.:
aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.eu-west-1.amazonaws.com
Then you can build and push your image, e.g.
docker build -t abc:test . docker tag abc:test 123456789.dkr.ecr.eu-west-1.amazonaws.com/abc:test docker push 123456789.dkr.ecr.eu-west-1.amazonaws.com/abc:test
FYI: You can find all supported parameters for the shell script from AWS at: https://github.com/aws/aws-codebuild-docker-images/blob/master/local_builds/codebuild_build.sh