Skip to content
Latchkey

How to Deploy to AWS With OIDC in CircleCI

CircleCI signs an OIDC token per job at $CIRCLE_OIDC_TOKEN_V2; AWS STS trades it for temporary credentials, so no static keys live in the project.

Configure an IAM role whose trust policy accepts the CircleCI OIDC provider, then call aws sts assume-role-with-web-identity with $CIRCLE_OIDC_TOKEN_V2 inside the job.

Steps

  • Add CircleCI as an OIDC provider in IAM (audience is your CircleCI org id).
  • Create a role whose trust policy allows the provider and your project.
  • Write the token to a file and call assume-role-with-web-identity.
  • Export the returned AccessKeyId, SecretAccessKey, and SessionToken.

Config

.circleci/config.yml
version: 2.1
jobs:
  deploy:
    docker:
      - image: amazon/aws-cli:2
    steps:
      - run:
          name: Assume role via OIDC
          command: |
            echo "$CIRCLE_OIDC_TOKEN_V2" > /tmp/token
            CREDS=$(aws sts assume-role-with-web-identity \
              --role-arn "$AWS_ROLE_ARN" \
              --role-session-name "circleci-$CIRCLE_WORKFLOW_ID" \
              --web-identity-token file:///tmp/token \
              --query Credentials --output text)
            export AWS_ACCESS_KEY_ID=$(echo "$CREDS" | awk '{print $1}')
            export AWS_SECRET_ACCESS_KEY=$(echo "$CREDS" | awk '{print $3}')
            export AWS_SESSION_TOKEN=$(echo "$CREDS" | awk '{print $4}')
            aws s3 ls
workflows:
  release:
    jobs:
      - deploy:
          context: aws-prod

Gotchas

  • The IAM trust policy aud must equal your CircleCI organization id, not the project name.
  • Use a Condition on the sub claim to restrict which project or branch can assume the role.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →