Github Actions — Terraform — CI/CD Multiple Accounts AWS

This repository contains a GitHub Actions workflow for managing Terraform deployments across multiple AWS accounts. The workflow allows for planning, manual approval, and applying or destroying Terraform configurations.

Workflow: Terraform Plan, Approval, and Deploy

Workflow Dispatch Inputs

  • action: Specifies the action to perform (apply or destroy). Default is apply.
  • aws_account: Specifies the AWS account to deploy to (shared, network, production, stage, develop).
  • terraform_version: Specifies the version of Terraform to use. Default is 1.8.0.

Workflow Jobs

1. Plan

  • Runs on: ubuntu-latest
  • Permissions:

    • actions: read
    • issues: write
    • id-token: write
    • contents: write
  • Timeout: 5 minutes
  • Steps:

    • Checkout the code.
    • Configure AWS credentials based on the selected AWS account.
    • Install and run tflint for linting Terraform files.
    • Setup Terraform with the specified version.
    • Initialize Terraform.
    • Plan Terraform changes and save the plan.
    • Cache Terraform files.
    • Upload the Terraform plan as an artifact.

2. Approval

  • Needs: plan
  • Runs on: ubuntu-latest
  • Permissions:

    • actions: read
    • issues: write
    • id-token: write
    • contents: write
  • Steps:

    • Request manual approval from the specified approvers.

3. Deploy

  • Needs: approval
  • Runs on: ubuntu-latest
  • Permissions:

    • id-token: write
    • contents: write
  • Timeout: 20 minutes
  • Steps:

    • Checkout the code.
    • Configure AWS credentials based on the selected AWS account.
    • Setup Terraform with the specified version.
    • Download the Terraform plan artifact.
    • Move the Terraform plan.
    • Initialize Terraform.
    • Apply or destroy the Terraform plan based on the specified action.

Usage

To trigger the workflow, go to the Actions tab in your GitHub repository, select the Terraform - Multiple AWS Accounts workflow, and click on Run workflow. Fill in the required inputs and run the workflow.

Secrets

The following secrets need to be configured in your GitHub repository:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_ROLE_ARN_NETWORK
  • AWS_ROLE_ARN_PROD
  • AWS_ROLE_ARN_DEVELOP
  • AWS_ROLE_ARN_STAGE
  • GITHUB_TOKEN (automatically provided by GitHub)

Notes

  • Ensure the roles specified in the AWS credentials have the necessary permissions to perform the Terraform actions.
  • Modify the role ARNs and other configurations as per your AWS setup.

For more information on GitHub Actions and Terraform, refer to the GitHub Actions documentation and Terraform documentation.


Code : deploy-to-terraform.yml


name: Terraform - Multiple AWS Accounts on: workflow_dispatch: inputs: action: description: 'Action to perform (apply or destroy)' required: true default: 'apply' aws_account: description: 'AWS Account to deploy to (shared, network, production, stage, develop)' required: true terraform_version: description: 'Version of Terraform to use' required: true default: '1.8.0' jobs: plan: runs-on: ubuntu-latest permissions: actions: read issues: write id-token: write # This is required for requesting the JWT contents: write # This is required for actions/checkout timeout-minutes: 5 steps: - name: Checkout Code uses: actions/checkout@v2 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'network' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_NETWORK }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'prod' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_PROD }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'stage' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_STAGE }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'develop' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::000000000:role/TESTE-GITHUB-ACTIONS aws-region: us-east-1 aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Install TFLint run: | curl -L https://github.com/terraform-linters/tflint/releases/latest/download/tflint_linux_amd64.zip -o tflint.zip unzip tflint.zip sudo mv tflint /usr/local/bin/ rm tflint.zip - name: Lint Terraform files run: tflint - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: ${{ github.event.inputs.terraform_version }} env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: us-east-1 - name: Initialize Terraform run: terraform init -reconfigure - name: Plan Terraform changes run: terraform plan -out=tfplan - name: Cache Terraform files uses: actions/cache@v2 with: path: | .terraform .terraform.lock.hcl key: ${{ runner.os }}-terraform-${{ hashFiles('**/*.tf') }} - name: Upload Terraform plan uses: actions/upload-artifact@v2 with: name: tfplan path: tfplan approval: needs: plan runs-on: ubuntu-latest permissions: actions: read issues: write id-token: write # This is required for requesting the JWT contents: write # This is required for actions/checkout steps: - name: Request Manual Approval uses: trstringer/manual-approval@v1 with: secret: ${{ secrets.GITHUB_TOKEN }} approvers: alerabello minimum-approvals: 1 additional-approved-words: 'Approve, Approved, approve, approved' timeout-minutes: 10 deploy: needs: approval runs-on: ubuntu-latest permissions: id-token: write # This is required for requesting the JWT contents: write # This is required for actions/checkout timeout-minutes: 20 steps: - name: Checkout Code uses: actions/checkout@v2 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'network' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_NETWORK }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'prod' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_PROD }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'stage' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_ROLE_ARN_STAGE }} aws-region: us-east-1 - name: Configure AWS Credentials if: ${{ github.event.inputs.aws_account == 'develop' }} uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::000000000:role/TESTE-GITHUB-ACTIONS aws-region: us-east-1 aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: ${{ github.event.inputs.terraform_version }} - name: Download repository artifact uses: actions/download-artifact@v2 with: name: tfplan path: ./tfplan - name: Move Terraform plan run: mv ./tfplan/tfplan ./tfplan.tfplan - name: Initialize Terraform run: terraform init -reconfigure - name: Apply or Destroy Terraform run: | if [ "${{ github.event.inputs.action }}" == "apply" ]; then terraform apply -auto-approve ./tfplan.tfplan elif [ "${{ github.event.inputs.action }}" == "destroy" ]; then terraform destroy -auto-approve else echo "Invalid action specified: ${{ github.event.inputs.action }}" exit 1 fi
Enter fullscreen mode
Exit fullscreen mode

Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top
Wordpress custom apps. Allows using the site with your screen reader.