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
ordestroy
). Default isapply
. -
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: ${{ secrets.AWS_ROLE_ARN_DEVELOP }}
aws-region: us-east-1
- 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_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: ${{ secrets.AWS_ROLE_ARN_DEVELOP }}
aws-region: us-east-1
- 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
Top comments (1)
Great write-up! We also have a bunch of articles on Github Actions in our Newsletter, check it out - packagemain.tech/p/github-actions-...