Skip to content

Instantly share code, notes, and snippets.

@mikerochip
Last active July 3, 2025 23:45
Show Gist options
  • Save mikerochip/289e3689a7e5b61339331003a4f27134 to your computer and use it in GitHub Desktop.
Save mikerochip/289e3689a7e5b61339331003a4f27134 to your computer and use it in GitHub Desktop.
Terraform: enable GitHub Actions OIDC for AWS with sample ECR push IAM Policy
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
data "aws_caller_identity" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
github_oidc_provider = "token.actions.githubusercontent.com"
github_repo_owner = "MyOrgOrUserName"
}
# https://github.com/aws-actions/configure-aws-credentials/issues/357#issuecomment-1012109466
# https://github.com/aws-actions/configure-aws-credentials/issues/357#issuecomment-1626357333
resource "aws_iam_openid_connect_provider" "github" {
url = "https://${local.github_oidc_provider}"
client_id_list = ["sts.amazonaws.com"]
}
# https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
resource "aws_iam_role" "github_actions_role" {
name_prefix = "github-actions-"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Principal = {
Federated = "arn:aws:iam::${local.account_id}:oidc-provider/${local.github_oidc_provider}"
},
Effect = "Allow",
Action = "sts:AssumeRoleWithWebIdentity",
Condition = {
StringEquals = {
"${local.github_oidc_provider}:aud" = "sts.amazonaws.com"
},
StringLike = {
"${local.github_oidc_provider}:sub" = "repo:${local.github_repo_owner}/*"
}
}
}]
})
}
resource "aws_iam_role_policy" "github_ecr_push_policy" {
name_prefix = "github-ecr-push-"
role = aws_iam_role.github_actions_role.name
policy = jsonencode({
Version = "2012-10-17",
Statement = [{
Effect = "Allow",
Resource = "*",
# https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelasticcontainerregistry.html
Action = [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:BatchImportUpstreamImage",
"ecr:CompleteLayerUpload",
"ecr:DescribeImageReplicationStatus",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetAccountSetting",
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr:GetImageCopyStatus",
"ecr:InitiateLayerUpload",
"ecr:ListImages",
"ecr:ListTagsForResource",
"ecr:PutImage",
"ecr:ReplicateImage",
"ecr:StartImageScan",
"ecr:TagResource",
"ecr:UntagResource",
"ecr:UploadLayerPart"
]
}]
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment