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: 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