Hmm… Let me try to better explain what’s happening.
Workflow is something like this:
From Github: (not working)
-
terraform init
: GithubActions → OIDC Connection to AWS → github-oidc
role in each account → terraform-backend-role
(PROD account) > DynamoDB|S3
-
terraform plan
: GithubActions → OIDC Connection to AWS → github-oidc
role in each account → DynamoDB|S3 ← It doesn’t know it needs to assume the terraform-backend-role
role in order for it to get access to the DynamoDB table and S3 bucket.
From local: (working)
-
terraform init
: Local laptop → aws sso login
credentials → terraform-assume-role
role in each account → terraform-backend-role
(PROD account) > DynamoDB|S3
-
terraform plan
: Local laptop → aws sso login
credentials → terraform-assume-role
role in each account → terraform-backend-role
(PROD account) > DynamoDB|S3
prod account:
- DynamoDB Table for TF locks
- S3 Bucket for TF state files
-
github-oidc
role for Github Actions
-
terraform-assume-role
for local TF development (When running TF locally you assume that role)
-
terraform-backend-role
when running terraform init
you assume this role
test account:
-
github-oidc
role for Github Actions
-
terraform-assume-role
for local TF development (When running TF locally you assume that role)
dev account:
-
github-oidc
role for Github Actions
-
terraform-assume-role
for local TF development (When running TF locally you assume that role)
Role github-oidc
:
-
AdministratorAccess
AWS managed policy
- Custom policy to allow it assume the
terraform-backend-role
role
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::<PROD AWS ACCOUNT-ID>:role/terraform-backend-role"
],
"Effect": "Allow"
}
]
}
- Trust policy to allow Github Actions assume this role via OIDC connection
{
"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:aud": "sts.amazonaws.com"
}
}
}
]
}
terraform-assume-role
:
-
AdministratorAccess
AWS managed policy
- Custom policy to allow it assume the
terraform-backend-role
role
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::<PROD AWS ACCOUNT-ID>:role/terraform-backend-role"
],
"Effect": "Allow"
}
]
}
Trust relationship allows SSO users to assume this role. This is used when running terraform init
or terraform plan
locally:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS ACCOUNT-ID>:saml-provider/*"
},
"Action": [
"sts:AssumeRole",
"sts:AssumeRoleWithSAML"
]
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<AWS ACCOUNT-ID>:root"
},
"Action": "sts:AssumeRole"
}
]
}
terraform-backend-role
:
- custom policy to allow access to the DynamoDB table:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:GetItem",
"dynamodb:DeleteItem",
"dynamodb:PutItem"
],
"Resource": [
"arn:aws:dynamodb:ap-southeast-2:<AWS ACCOUNT-ID>:table/terraform-state-lock",
"arn:aws:dynamodb:ap-southeast-2:<AWS ACCOUNT-ID>:table/terraform-state-lock/*"
],
"Effect": "Allow"
}
]
}
- custom policy to allow access to the S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::foo-terraform-backend-tfstate",
"arn:aws:s3:::foo-terraform-backend-tfstate/*"
],
"Effect": "Allow"
}
]
}
Trust policy allows the terraform-assume-role
and github-actions-oidc-role
to assume it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<PROD AWS ACCOUNT-ID>:role/terraform-assume-role",
"arn:aws:iam::<PROD AWS ACCOUNT-ID>:root",
"arn:aws:iam::<DEV AWS ACCOUNT-ID>:root",
"arn:aws:iam::<TEST AWS ACCOUNT-ID>:role/terraform-assume-role",
"arn:aws:iam::<TEST AWS ACCOUNT-ID>:root",
"arn:aws:iam::<DEV AWS ACCOUNT-ID>:role/terraform-assume-role"
]
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<PROD AWS ACCOUNT-ID>:role/github-actions-oidc-role",
"arn:aws:iam::<TEST AWS ACCOUNT-ID>:role/github-actions-oidc-role",
"arn:aws:iam::<DEV AWS ACCOUNT-ID>:role/github-actions-oidc-role"
]
},
"Action": [
"sts:AssumeRole",
"sts:AssumeRoleWithWebIdentity"
]
}
]
}