Problem:
We had three separate AWS accounts for dev, staging and production. We have a master account and we used role assumption to access the rest of the accounts for the development stages. We needed CircleCI to deploy to different stages using AWS Role Assumption.
Note: This article assumes you already have the working knowledge of CircleCI and how to setup CircleCI for your project.
Solution:
We solved the problem using aws config, CircleCI contexts and some yml magic.
Step1:
Create a config file aws_config
and add it to the .circleci folder.
[default]
region = us-east-1
output = json
[profile dev]
role_arn = arn:aws:iam::<account_id>:role/CircleCi-role
source_profile = default
[profile staging]
role_arn = arn:aws:iam::<account_id>:role/CircleCi-role
source_profile = default
[profile production]
role_arn = arn:aws:iam::<account_id>:role/CircleCi-role
source_profile = default
Step2:
CircleCI supports environment variables by context.
- Login to CircleCI and go to Settings
- Create a org-global context and add AWS_ACCESS_KEY and AWS_SECRET_KEY.
- Create three contexts for each stage and add AWS_PROFILEenv variable. Set the variable to 'dev', 'staging' and 'production' in respective contexts.
Step3:
Add a step in CircleCI config.yml to setup the credentials and config file under the org-default context. You only need to do this once. The .aws folder could be persisted and shared across jobs.
Note: I am using python executor and pipenv has already installed awscli as a dependency.
- run:
name: AWS configure
command: |
pipenv run aws configure set aws_access_key_id $AWS_ACCESS_KEY
pipenv run aws configure set aws_secret_access_key $AWS_SECRET_KEY
cp .circleci/aws_config ~/.aws/config
This step creates a credentials file with the key_id and access_key for the default profile.
The config file in the previous step uses the profile from the credentials file.
Step4:
Pass profile name in parameter to aws cli commands in your CircleCI deployment.
aws s3 sync ./local s3://bucket --profile dev
AWSCLI commands can also read from the env variable directly
aws s3 sync ./local s3://bucket
In case, you have a custom script or a Serverless Framework, you can pass the profile.
sls deploy --aws-profile $AWS_PROFILE
Complete example:
Recommended reading: Set up AWSCLI using RoleAssumption and MFA.
Top comments (0)