Browse the Repo

file-type-icon.circleci
file-type-icon.github
file-type-icon.patcher
file-type-icon_ci
file-type-icon_docs
file-type-iconcodegen
file-type-iconexamples
file-type-iconmodules
file-type-icon_deprecated
file-type-iconauto-update
file-type-iconaws-auth
file-type-iconaws-config-bucket
file-type-iconaws-config-multi-region
file-type-iconaws-config-rules
file-type-iconaws-config
file-type-iconaws-organizations
file-type-iconcloudtrail-bucket
file-type-iconcloudtrail
file-type-iconcross-account-iam-roles
file-type-iconcustom-iam-entity
file-type-iconebs-encryption-multi-region
file-type-iconebs-encryption
file-type-iconfail2ban
file-type-icongithub-actions-iam-role
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf
file-type-iconguardduty-multi-region
file-type-iconguardduty
file-type-iconiam-access-analyzer-multi-region
file-type-iconiam-groups
file-type-iconiam-policies
file-type-iconiam-user-password-policy
file-type-iconiam-users
file-type-iconip-lockdown
file-type-iconkms-cmk-replica
file-type-iconkms-grant-multi-region
file-type-iconkms-master-key-multi-region
file-type-iconkms-master-key
file-type-iconntp
file-type-iconos-hardening
file-type-iconprivate-s3-bucket
file-type-iconsaml-iam-roles
file-type-iconsecrets-manager-resource-policies
file-type-iconssh-grunt-selinux-policy
file-type-iconssh-grunt
file-type-iconssh-iam
file-type-iconssm-healthchecks-iam-permissions
file-type-icontls-cert-private
file-type-icontest
file-type-icon.editorconfig
file-type-icon.gitignore
file-type-icon.pre-commit-config.yaml
file-type-iconCODEOWNERS
file-type-iconLICENSE.txt
file-type-iconREADME.adoc
file-type-iconterraform-cloud-enterprise-private-module-...

Browse the Repo

file-type-icon.circleci
file-type-icon.github
file-type-icon.patcher
file-type-icon_ci
file-type-icon_docs
file-type-iconcodegen
file-type-iconexamples
file-type-iconmodules
file-type-icon_deprecated
file-type-iconauto-update
file-type-iconaws-auth
file-type-iconaws-config-bucket
file-type-iconaws-config-multi-region
file-type-iconaws-config-rules
file-type-iconaws-config
file-type-iconaws-organizations
file-type-iconcloudtrail-bucket
file-type-iconcloudtrail
file-type-iconcross-account-iam-roles
file-type-iconcustom-iam-entity
file-type-iconebs-encryption-multi-region
file-type-iconebs-encryption
file-type-iconfail2ban
file-type-icongithub-actions-iam-role
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf
file-type-iconguardduty-multi-region
file-type-iconguardduty
file-type-iconiam-access-analyzer-multi-region
file-type-iconiam-groups
file-type-iconiam-policies
file-type-iconiam-user-password-policy
file-type-iconiam-users
file-type-iconip-lockdown
file-type-iconkms-cmk-replica
file-type-iconkms-grant-multi-region
file-type-iconkms-master-key-multi-region
file-type-iconkms-master-key
file-type-iconntp
file-type-iconos-hardening
file-type-iconprivate-s3-bucket
file-type-iconsaml-iam-roles
file-type-iconsecrets-manager-resource-policies
file-type-iconssh-grunt-selinux-policy
file-type-iconssh-grunt
file-type-iconssh-iam
file-type-iconssm-healthchecks-iam-permissions
file-type-icontls-cert-private
file-type-icontest
file-type-icon.editorconfig
file-type-icon.gitignore
file-type-icon.pre-commit-config.yaml
file-type-iconCODEOWNERS
file-type-iconLICENSE.txt
file-type-iconREADME.adoc
file-type-iconterraform-cloud-enterprise-private-module-...
ssh-grunt

ssh-grunt

Manage SSH access to EC2 Instances using groups in AWS IAM or your Identity Provider (e.g., ADFS, Google, Okta, etc).

Code Preview

Preview the Code

mobile file icon

README.md

down

IAM Role for GitHub Actions

This Terraform module can be used to create Assume Role policies and IAM Roles such that they can be used with GitHub Actions. This requires you to provision an IAM OpenID Connect Provider for GitHub Actions in your account. By using OpenID Connect, GitHub Actions can directly exchange credentials to access AWS without having to store and provide GitHub with permanent AWS access credentials. This is useful to prevent credential leaks from progressing undetected.

You can either use the account-baseline-app or account-baseline-security modules (setting enable_github_actions_access = true) or by adding the following resource to your Terraform module:

resource "aws_iam_openid_connect_provider" "github_actions" {
  url             = "https://token.actions.githubusercontent.com"
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.oidc_thumbprint.certificates[0].sha1_fingerprint]
}

data "tls_certificate" "oidc_thumbprint" {
  url = "https://token.actions.githubusercontent.com"
}

How do you use this module?

  • See the root README for instructions on using Terraform modules.
  • See variables.tf for all the variables you can set on this module.
  • See outputs.tf for all the variables that are outputed by this module.

Creating the IAM Role

module "iam_role" {
  # Update <VERSION> with latest version of the module
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/github-actions-iam-role?ref=<VERSION>"

  github_actions_openid_connect_provider_arn = aws_iam_openid_connect_provider.github_actions.arn
  github_actions_openid_connect_provider_url = aws_iam_openid_connect_provider.github_actions.url

  allowed_sources = {
    "gruntwork-io/terraform-aws-security" = ["main"]
  }

  iam_role_name                  = "example-iam-role"
  permitted_full_access_services = ["ec2"]
}

The above example will configure the IAM role example-iam-role such that it is available to be assumed by GitHub Actions if it is run from the main branch of the gruntwork-io/terraform-aws-security repository. The IAM role would then have the ability to call any API in the ec2 namespace.

You can further customize the IAM role using the following variables:

  • permitted_full_access_services: List of AWS services that the IAM role will have full access to (set to SERVICE_NAME:*).
  • iam_policy: IAM policy statements that should be directly attached (inline) to the IAM role.
  • iam_policy_arns: List of IAM Policy ARNs that should be attached to the IAM role.
  • iam_customer_managed_policy_names: List of customer managed IAM policies that should be attached to the IAM role.
  • iam_aws_managed_policy_names: List of AWS managed IAM policies that should be attached to the IAM role.

Extend the allowed_sources map if you want to allow additional repositories or branches. For example, if you want to allow the dev branch on terraform-aws-security, as well as the main branch from terraform-aws-service-catalog:

module "iam_role" {
  # Update <VERSION> with latest version of the module
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/github-actions-iam-role?ref=<VERSION>"

  github_actions_openid_connect_provider_arn = aws_iam_openid_connect_provider.github_actions.arn
  github_actions_openid_connect_provider_url = aws_iam_openid_connect_provider.github_actions.url

  allowed_sources = {
    "gruntwork-io/terraform-aws-security"              = ["main", "dev"]
    "gruntwork-io/terraform-aws-service-catalog" = ["main"]
  }

  iam_role_name                  = "example-iam-role"
  permitted_full_access_services = ["ec2"]
}

You can also use the module to only manage the assume role policy. This is useful if you want more control over the IAM role creation. For example:

module "assume_role_policy" {
  # Update <VERSION> with latest version of the module
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/github-actions-iam-role?ref=<VERSION>"

  github_actions_openid_connect_provider_arn = aws_iam_openid_connect_provider.github_actions.arn
  github_actions_openid_connect_provider_url = aws_iam_openid_connect_provider.github_actions.url

  allowed_sources = {
    "gruntwork-io/terraform-aws-security"              = ["main", "dev"]
    "gruntwork-io/terraform-aws-service-catalog" = ["main"]
  }

  create_iam_role = false
}

resource "aws_iam_role" "example" {
  name               = "example-iam-role"
  assume_role_policy = module.assume_role_policy.assume_role_policy_json
}

Using created IAM Role in GitHub Actions Workflow

To use the created IAM role in your GitHub Actions Workflow, you need to configure the following:

  1. Attach permissions to write id-token at the workflow or job level. To add this permission, add the following as a top level key, or under the job:

    permissions: id-token: write

  2. Add the aws-actions/configure-aws-credentials to your step. This retrieves a JWT from the GitHub OIDC provider, and then requests an access token from AWS. For more information, see the AWS documentation.

    - name: configure aws credentials
      uses: aws-actions/configure-aws-credentials@master
      with:
        role-to-assume: IAM_ROLE_ARN_OUTPUT_OF_MODULE
        role-session-name: ANY_CUSTOM_SESSION_NAME
        aws-region: DEFAULT_REGION_TO_USE
    

With these two settings, your GitHub Action should now be able to assume the IAM role you created in this module. The following is a full GitHub Action Workflow example that lists EC2 instances on every push:

# Sample workflow to access AWS resources when workflow is tied to branch
name: AWS example workflow
on:
  push
permissions:
  id-token: write
jobs:
  ReadEC2Instances:
    runs-on: ubuntu-latest
    steps:
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          role-to-assume: IAM_ROLE_ARN_OUTPUT_OF_MODULE
          role-session-name: ANY_CUSTOM_SESSION_NAME
          aws-region: us-east-1
      - name: Whoami?
        run: |
          aws sts get-caller-identity
      - name: Read EC2 Instances
        run: |
          aws ec2 describe-instances

Questions? Ask away.

We're here to talk about our services, answer any questions, give advice, or just to chat.

Ready to hand off the Gruntwork?