I want to pass temporary credentials for AssumeRole into the Docker runtime with AWS CodeBuild.
Short description
CodeBuild uses the CodeBuild service role as the default AWS credential in the build container. The Docker runtime running inside the build container doesn't get any AWS credentials and must be explicitly configured.
Export the AssumeRole credentials as environment variables. Then, pass these variables into the Docker runtime by using the --build-arg parameter for docker build. For more information, see docker build on the Docker Docs website.
Resolution
1. Create a new role for the Docker runtime. For example: Secretassumerole
2. Update the Trust Relationship Policy of Secretassumerole and add your CodeBuild service role permission for assume role. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::$account_id:role/service-role/codebuild-service-role"
},
"Action": "sts:AssumeRole"
}
]
}
3. Use the new role to get the secret AWSExampleSecret value from AWS Secrets Manager. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret",
"secretsmanager:ListSecretVersionIds"
],
"Resource": [
"arn:aws:secretsmanager:ap-northeast-1:$account_id:secret:tutorials/AWSExampleSecret-EHWYme"
]
}
]
}
Note: Replace $account_id with your account ID. You can give any operation permission during the Docker runtime.
4. Add sts:assumeRole permissions to your CodeBuild service role to allow AssumeRole operations. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::$account_id:role:role/Secretassumerole"
}
]
}
5. Use a build spec to export the AssumeRole credentials into an environment variable. Then, use the docker build command to pass the credentials into your Docker runtime. For example:
version: 0.2
phases:
install:
runtime-versions:
nodejs: 16
commands:
- ASSUME_ROLE_ARN="arn:aws:iam::$account_id:role/Secretassumerole"
- TEMP_ROLE=$(aws sts assume-role --role-arn $ASSUME_ROLE_ARN --role-session-name test)
- export TEMP_ROLE
- export AWS_ACCESS_KEY_ID=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.AccessKeyId')
- export AWS_SECRET_ACCESS_KEY=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SecretAccessKey')
- export AWS_SESSION_TOKEN=$(echo "${TEMP_ROLE}" | jq -r '.Credentials.SessionToken')
pre_build:
commands:
- echo Build started on 'date'
- echo Building the Docker image...
- docker build . --build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID --build-arg AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY --build-arg AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN
Note: You can use --duration-seconds to set the maximum session duration for the assume role. Because this process involves role chaining, the --duration-seconds option accepts a maximum value of 3600 seconds. If you set a value higher than 3600 seconds, then the operation fails. For more information, see the role chaining section of Roles terms and concepts.
6. In your Dockerfile, get the AssumeRole credentials when you build an image. For example:
FROM amazonlinux:latest
RUN yum -y install aws-cli
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ARG AWS_SESSION_TOKEN
RUN echo $AWS_ACCESS_KEY_ID
RUN echo $AWS_SECRET_ACCESS_KEY
RUN echo $AWS_SESSION_TOKEN
RUN aws sts get-caller-identity
RUN aws secretsmanager get-secret-value --secret-id tutorials/AWSExampleSecret --region ap-northeast-1
Note: You can add RUN aws secretsmanager get-secret-value --secret-id tutorials/AWSExampleSecret in DOCKERFILE to retrieve the secrets in build. Warning: Doing this can expose your secrets in build logs.
Output:
Step 8/11 : RUN echo $AWS_ACCESS_KEY_ID
---> Running in 1a1b1c1d1e1f
AKIAIOSFODNN7EXAMPLE
Removing intermediate container 2a3b4c5d6e7f
---> 32a8170f9697
Step 9/11 : RUN echo $AWS_SECRET_ACCESS_KEY
---> Running in 3a3b3c3d3e3f
KJq+JNqmnNq1JirNUBkxc+kRVavgZwhpFFIJjxD6
Removing intermediate container 3a3b3c3d3e3f
---> 4a4b4c4d4e4f
Step 10/11 : RUN echo $AWS_SESSION_TOKEN
---> Running in 5a5b5c5d5e5f
FQoGZXIvYXdzEJP//////////wEaDPTjooaOAaU8NDj5oyKkAjVwT4uQHTZJdCtfOZxa6wTZVOy0Zkw+laN1RRVZhvhdPOWhU8VgK2d7ZgTlqaXn4NSrdWlnub6g5JobP4o509t3VLdMUR5ZJJcpnSlJAY5YM7vlPndroGcV+Y689ztVzQ1uVxdtpjQK1qh87fw6m0dHt7Q8Y8TferRNVvCM4kOroxPzovTbO6IkLDcBp8PhOVgtVtxEpON6nZrN990zzUmhXjT0vrtpDtAi339hhs7fzDOrnllQHSAmSerT0NhMOYVqBH1HJOq3FYnG+TUbHENpSq3kwTiPL2uoTw7/Ufrrgz4i3ENHm3rIWlbD8VuleDl5yhooKifmKDPjQAHs5HbVjD9lnxQFrCIuyvZdmsqzgoIjPt6z5H8lzugLHAAmbgiOwDoo+Oba7QU=
Removing intermediate container 5a5b5c5d5e5f
---> 0cc838f3c865
Step 11/11 : RUN aws sts get-caller-identity
---> Running in 6a6b6c6d6e6f
{
"Account": "xxxxxxxxx",
"UserId": "AIDACKCEVSQ6C2EXAMPLE:test",
"Arn": "arn:aws:sts::$account_id:assumed-role/Secretassumerole/test"
}
Removing intermediate container 6d525393d667
---> 2da2f38adc77
Step 12/12 : RUN aws secretsmanager get-secret-value --secret-id tutorials/AWSExampleSecret --region ap-northeast-1
---> Running in 7a7b7c7d7e7f
{
"Name": "tutorials/AWSExampleSecret",
"VersionId": "1a23bb45-679c-1d2e-fg34-567891234hi5",
"SecretString": "{\"username\":\"myserviceusername\",\"password\":\"yourPassword\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": 1558616482.926,
"ARN": "arn:aws:secretsmanager:ap-northeast-1:$account_id:secret:tutorials/M-EHWYme"
}
Removing intermediate container 8a8b8c8d8e8f
---> 9a9b9c9d9e9f
Successfully built 9a9b9c9d9e9f