AWS OIDC
With OpenID Connect (OIDC), the GitHub Actions job that runs your plan assumes an IAM role with a short-lived token from GitHub. You store no AWS access keys in your repository. It is the recommended method for production.
Setup has two steps:
- Create the OIDC provider and the IAM role in AWS. Do this one time, from your workstation with your own AWS credentials, not through Orchestration.
- Add an
oidchook to.stategraph/config.yml.
Quick setup
Create the provider and the role with Terraform, the AWS CLI, or the AWS Console. For a custom trust policy, use the manual setup. In each method, GITHUB_ORG is your GitHub organization or user name, and it is case-sensitive.
Terraform
The terraform-aws-terrateam-setup module creates every AWS resource that Orchestration needs. You need Terraform and AWS credentials on your workstation, from the AWS CLI or from environment variables.
- Create
main.tf:
module "stategraph_aws_setup" {
source = "github.com/terrateamio/terraform-aws-terrateam-setup"
github_org = "GITHUB_ORG"
aws_policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess"
aws_iam_role_name = "stategraph"
create_oidc_provider = true
}
- Apply it:
terraform apply
AWS CLI
Create a CloudFormation stack from the setup template:
aws cloudformation create-stack \
--stack-name stategraph-setup \
--template-url https://terrateam-io-public.s3.us-east-2.amazonaws.com/terrateam-setup-cloudformation.yml \
--parameters ParameterKey=GithubOrg,ParameterValue=GITHUB_ORG \
ParameterKey=RoleArn,ParameterValue=arn:aws:iam::aws:policy/PowerUserAccess \
ParameterKey=CreateGithubOIDCProvider,ParameterValue=true \
ParameterKey=RoleName,ParameterValue=stategraph \
--capabilities CAPABILITY_NAMED_IAM
AWS Console
- Open CloudFormation, choose Create stack, and enter this Amazon S3 URL as the template source:
https://terrateam-io-public.s3.us-east-2.amazonaws.com/terrateam-setup-cloudformation.yml
- Set
GithubOrg(case-sensitive). SetRoleArntoarn:aws:iam::aws:policy/PowerUserAccess, or to another IAM policy. - Keep the default stack options. Orchestration needs none of them.
- Review and create the stack.
Policy choice
PowerUserAccess is a starting point. For production, use a custom policy with fewer permissions.
Configure Orchestration for OIDC
Add an oidc hook to .stategraph/config.yml at the root of your repository. Replace AWS_ACCOUNT_ID with your AWS account ID.
hooks:
all:
pre:
- type: oidc
provider: aws
role_arn: "arn:aws:iam::AWS_ACCOUNT_ID:role/stategraph"
Before each operation, the hook calls aws sts assume-role-with-web-identity with the GitHub token. It exports AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN for the rest of the run. For region, duration, assume_role_arn, and the other keys, see the hooks reference.
Manual setup
Use these steps for a custom configuration, or to see each resource that the quick setup creates.
- Create the OIDC provider, so that AWS trusts the GitHub identity provider:
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 1c58a3a8518e8759bf075b76b750d4f2df264fcd
- Create
trustpolicy.jsonon your workstation. ReplaceAWS_ACCOUNT_IDandGITHUB_ORGwith your values.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:GITHUB_ORG/*"
},
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
}
}
}
]
}
There are example trust policies for one repository and for more than one repository. For tighter subject conditions, see Hardening AWS OIDC.
- Create the IAM role with the trust policy:
aws iam create-role \
--role-name stategraph \
--assume-role-policy-document file://trustpolicy.json
- Attach a permissions policy to the role.
PowerUserAccessis a starting point. For production, use a custom policy.
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/PowerUserAccess \
--role-name stategraph
- Add the
oidchook, as in Configure Orchestration for OIDC.
Multiple environments
To use one IAM role per environment, put the oidc step in workflows, not in hooks. Each workflow selects directories with a tag_query and runs its own steps.
workflows:
- tag_query: "dir:terraform/production/**"
plan:
- type: oidc
provider: aws
role_arn: "arn:aws:iam::PROD_ACCOUNT_ID:role/stategraph-prod"
- type: init
- type: plan
apply:
- type: oidc
provider: aws
role_arn: "arn:aws:iam::PROD_ACCOUNT_ID:role/stategraph-prod"
- type: init
- type: apply
- tag_query: "dir:terraform/staging/**"
plan:
- type: oidc
provider: aws
role_arn: "arn:aws:iam::STAGING_ACCOUNT_ID:role/stategraph-staging"
- type: init
- type: plan
apply:
- type: oidc
provider: aws
role_arn: "arn:aws:iam::STAGING_ACCOUNT_ID:role/stategraph-staging"
- type: init
- type: apply
The role ARN can also come from a repository secret, as ${AWS_ROLE_ARN}. For more patterns, see Cloud credentials.
Next Steps
- Hardening AWS OIDC: restrict the trust policy to specific repositories, branches, and environments
- Multi-environment: structure directories and workflows per environment
- Apply requirements: require approvals and passing checks before an apply