Terraform – Multiple AWS Accounts
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
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