Terraform automation with Github
Step 1. Create repository
In this example I am creating repo called github-action-aws-tf
Step 2. S3 bucket to store state file
In S3 create a new bucket with versioning
enabled
Step 3. Configure OIDC
- In IAM -> Identity providers -> add provider
- Select
OpenIDConnect
- Provider URL
token.actions.githubusercontent.com
- Audience
sts.amazonaws.com
- Add provider
Step 3. IAM role with permission
Create a new IAM roles - Select Custom Policy and paste below trust policy by updating repo name and account ID - Create custom policy allowing write access terraform state bucket and attach it. - Add any additional permissions required like ec2, LoadBalancer etc.
trustpolicy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<ACCOUNT ID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"ForAnyValue:StringLike": {
"token.actions.githubusercontent.com:sub": "repo:<NAME>/<REPONAME>:*"
}
}
}
]
}
Now you are ready to create Github actions and execute.
Step 4. Simple github action
Here is a very simple github action that will trigger plan up on pull request creation, and apply when merged to main.
```yaml name: "Terraform Build" on: push: branches: - main pull_request: permissions: contents: read pull-requests: write # id-token: write env: TF_LOG: INFO
jobs: terraforms-build: runs-on: ubuntu-latest steps: - name: Git checkout uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::<ACCOUNTID>:role/<ROLE NAME>
role-session-name: githubaction-session
aws-region: eu-west-1
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform fmt
id: fmt
run: terraform fmt -check
continue-on-error: true
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Validate
id: validate
run: terraform validate -no-color
- name: Terraform Plan
id: plan
run: terraform plan -no-color
if: (github.event_name == 'pull_request') || (github.event_name == 'push' && github.ref == 'refs/heads/main')
continue-on-error: true
- name: Terraform Apply
id: apply
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.plan.conclusion == 'success'
run: terraform apply -auto-approve -input=false
- name: Terraform Apply Status
if: steps.apply.outcome == 'failure'
run: exit
```