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.
We solved the problem using aws config, CircleCI contexts and some yml magic.
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
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.
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.
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
Recommended reading: Set up AWSCLI using RoleAssumption and MFA.