Recently, I have been using Terraform for application infrastructure modifications.
https://dev.to/suzuki0430/terraform-beginners-aws-security-group-management-3pl3
It was quite a hassle to have reviewers run terraform plan
during PR reviews, so I created a workflow in GitHub Actions to automatically post the results of terraform plan
as comments.
Overview of the workflow
This workflow (.github/workflows/infrastructure-checks.yml
) is executed every time a PR for master is created or updated.
The following is a description of the workflow.
name: 'Infrastructure Checks'
on:
pull_request:
branches:
- master
types: [opened, synchronize]
jobs:
terraform:
name: 'Terraform Checks'
runs-on: ubuntu-latest
strategy:
matrix:
# stg, prodは未使用のため一旦コメントアウト
# directory: ['environments/dev', 'environments/stg', 'environments/prod']
directory: ['environments/dev']
defaults:
run:
working-directory: ${{ matrix.directory }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Setup AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Terraform Format
id: fmt
run: terraform fmt -check
- name: Check if directory is not empty
id: check
run: |
if [ "$(ls -A .)" ]; then
echo "Directory is not empty"
else
echo "Directory is empty"
exit 1
fi
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Plan
id: plan
run: terraform plan -no-color
continue-on-error: true
- name: Comment PR
uses: actions/github-script@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outputs.stdout }}\`
#### Terraform Initialization ⚙️\`${{ steps.init.outputs.stdout }}\`
#### Terraform Plan 📖\`${{ steps.plan.outputs.stdout }}\``;
github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Terraform checks in directory '${{ matrix.directory }}'\n` + output
})
```
## Workflow Details
1. Checkout: Check out the repository (download the code to the GitHub execution environment).
2. Setup Terraform: Enables the workflow to use Terraform commands.
3. Setup AWS Credentials: Setup AWS credentials so Terraform can manage AWS resources.
4. Terraform Format: Check Terraform formatting. Consistent formatting improves code readability and maintainability.
5. Check if directory is not empty: Check if the directory `environments/dev` is not empty.
6. Terraform Init: Initialize Terraform so that Terraform can manage resources in subsequent steps.
7. Terraform Plan: Execute the `terraform plan`. The changes are posted to the PR as comments.
8. Comment PR: Post the results of each step of Terraform as a comment in the PR.
### Tip.
To ensure that the workflow is executed even when changes occur in the push after the PR is created, we have added `synchronize` to types.
```yml
on:
pull_request:
branches:
- master
types: [opened, synchronize]
```
Also, if you want to perform Terraform checks for each configuration per environment (dev, stg, prod, etc.), use `strategy.matrix` to enumerate each directory.
```yml
terraform:
name: 'Terraform Checks'
runs-on: ubuntu-latest
strategy:
matrix:
directory: ['environments/dev', 'environments/stg', 'environments/prod']
run:
working-directory: ${{ matrix.directory }}
```
The AWS credentials (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`) that you set up in step 3 will be registered in GitHub Secrets after creating the IAM user.
1. Navigate to the target repository on GitHub.
2. Click on the "Settings" tab in the upper right corner of the repository's main page.
3. Select "Secrets" from the menu on the left.
4. Click on the "New repository secret" button.
5. Enter a name for the secret in the "Name" field.
6. Enter the value of the secret in the "Value" field.
7. Click the "Add secret" button to save the secret.
Also, set the IAM policy to be attached to the IAM user according to the resource to be managed by Terraform.
Since `terraform plan` is a read-only operation, if you are managing EC2 resources, attach a managed policy such as `AmazonEC2ReadOnlyAccess`.
## What's in the Comments
When you create or update a PR, the following comments will be posted with it.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3h0l8ryels5jrl970m7l.png)
Top comments (0)