Skip to content

About

Terraform module that creates an IAM role with OIDC trust policy for GitHub Actions workflows with customizable permissions and repo/branch restrictions.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

135 Commits

Folders and files

Repository files navigation

terraform-aws-github-role

Need Help? Docs Registry Release AWS IAM GitHub Actions Security License

This Terraform module creates an AWS IAM role that a GitHub Actions workflow can assume through OpenID Connect (OIDC). Workflows in the repository you name exchange their short-lived OIDC token for temporary AWS credentials — no access keys stored as repository secrets, nothing to rotate.

The module creates the role and its trust policy only. It attaches no permission policies; you attach exactly what your workflow needs to the returned role.

Why This Module?

Writing the trust policy by hand is where GitHub OIDC setups usually go wrong: the federated principal, the aud condition, and the sub pattern all have to be exactly right, and a single typo produces an opaque Not authorized to perform sts:AssumeRoleWithWebIdentity. This module:

  • Gets the trust policy right — federated principal, audience, and repository subject in one place
  • Handles GitHub's immutable subject claims — matches both repo:org/repo:* and the newer repo:org@<org_id>/repo@<repo_id>:* format that new and renamed repositories receive from 2026-07-15
  • Narrows who can assume the role — subject_claims limits it to, say, the default branch or one environment, in both claim formats
  • Stays unopinionated about permissions — no bundled policies means no accidental over-privilege
  • Names roles predictably — ih-tf-<repo_name>-github by default, so roles are easy to audit across accounts
  • Tags what it creates — created_by_module and module_version tags make provenance obvious

Features

  • IAM role with a GitHub Actions OIDC trust policy, scoped to one org/repo
  • Support for legacy and immutable GitHub subject claims
  • Optional subject-claim narrowing (subject_claims; any workflow in the repository by default)
  • Optional custom role name (role_name)
  • Configurable session length (max_session_duration, 1 hour by default)
  • Outputs the role name and ARN for policy attachment and workflow configuration
  • Works with AWS provider 5.11+ and 6.x

Quick Start

module "github_role" {
  source  = "registry.infrahouse.com/infrahouse/github-role/aws"
  version = "1.6.0"

  gh_org_name = "infrahouse"
  repo_name   = "aws-control"
}

# The role has no permissions until you attach a policy.
resource "aws_iam_role_policy_attachment" "github_role_s3" {
  role       = module.github_role.github_role_name
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}

output "github_role_arn" {
  value = module.github_role.github_role_arn
}

The module looks up an existing GitHub OIDC identity provider in the account (https://token.actions.githubusercontent.com). Create it once per AWS account with terraform-aws-gh-identity-provider:

module "github_identity_provider" {
  source  = "registry.infrahouse.com/infrahouse/gh-identity-provider/aws"
  version = "1.1.1"
}

Then use the role in a workflow — id-token: write is what lets the runner request an OIDC token:

name: Deploy to AWS
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v5

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v5
        with:
          role-to-assume: ${{ vars.AWS_ROLE_ARN }}
          aws-region: us-west-2

      - name: Verify access
        run: aws sts get-caller-identity

Documentation

Full documentation is available at infrahouse.github.io/terraform-aws-github-role.

Security Best Practices

⚠️ Important: do not grant AdministratorAccess to a GitHub Actions role. Anyone who can run a workflow in the repository then effectively owns the AWS account.

  • Least privilege — attach resource-scoped policies for the exact actions the workflow performs
  • One role per repository and environment — separate staging and production, ideally in separate accounts
  • Protect privileged workflows — the role trusts every branch of the repository, so gate deployments with GitHub environments and required reviewers
  • Short sessions — keep max_session_duration as low as the job allows
  • Audit regularly — AssumeRoleWithWebIdentity events in CloudTrail record which repository and ref used the role

More detail: Security.

Usage

Requirements

Name Version
terraform ~> 1.5
aws >= 5.11, < 7.0

Providers

Name Version
aws >= 5.11, < 7.0

Modules

No modules.

Resources

Name Type
aws_iam_role.github resource
aws_iam_openid_connect_provider.github data source
aws_iam_policy_document.github-trust data source

Inputs

Name Description Type Default Required
gh_org_name GitHub organization name. string n/a yes
max_session_duration Maximum session duration in seconds for the IAM role. number 3600 no
repo_name Repository name in GitHub. Without the organization part. string n/a yes
role_name Name of the role. If left unset, the role name will be ih-tf-var.repo_name-github. string null no
subject_claims Subject claim suffixes allowed to assume the role: the part of the OIDC sub claim after repo:<org>/<repo>:.
The default ["*"] lets any workflow in the repository assume it. Narrow it for a role with production
access, e.g. ["ref:refs/heads/main"] or ["environment:production"]. A job that names an environment gets
an environment:<name> subject, not a ref: one. The module matches each suffix in both the legacy and the
immutable repository-name format.
list(string)
[
"*"
]
no

Outputs

Name Description
github_role_arn ARN of the IAM role created for GitHub Actions
github_role_name Name of the IAM role created for GitHub Actions

Examples

See the examples/ directory for complete working examples:

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the Apache 2.0 License — see the LICENSE file for details.

About

Terraform module that creates an IAM role with OIDC trust policy for GitHub Actions workflows with customizable permissions and repo/branch restrictions.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages