-
-
Notifications
You must be signed in to change notification settings - Fork 21
159 lines (140 loc) · 5.88 KB
/
terraform.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
name: Terraform Reusable
# This is a reusable workflow to run terraform plan and apply on
# 'pull_request' and 'push' events using matrix strategy. Learn more:
# https://github.com/o11y-top/aws-terraform-multiple-environments/#readme
on:
workflow_call:
secrets:
env:
description: Input environment variables required by terraform
required: true
# Allow only one of this workflow to run at a time per branch.
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
# Allow read repository contents, write deployments and pull requests.
permissions:
contents: read
pull-requests: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
# Query GitHub API to return a list of labels on the PR or commit
# then output the list of 'tf' prefixed labels for subsequent use
# in the format: [['tf', 'label1'], ['tf_auto_approve', 'label2']]
labels:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.labels.outputs.result }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
# List changed environment directories when PR is opened or updated by bots.
- name: Get changed environments once
if: contains(github.event.action, 'opened') || contains(github.actor, '[bot]')
id: changed
uses: tj-actions/changed-files@v35
with:
dir_names_max_depth: 2
dir_names: true
files: environments/**
json_raw_format: true
json: true
# Add 'tf' prefixed labels for changed environments when PR is opened or updated by bots.
- name: Add changed environment labels once
if: steps.changed.outcome == 'success' && toJSON(fromJSON(steps.changed.outputs.all_modified_files)) != '[]'
uses: actions/github-script@v6
env:
changed: ${{ steps.changed.outputs.all_modified_files }}
with:
script: |
// Parse changed environment directory paths then add labels
// in the format: ['tf:label1', 'tf:label2']
const labels = JSON.parse(process.env.changed).map((str) => {
return 'tf:' + str.substring(str.indexOf('/') + 1);
});
github.rest.issues.addLabels({
issue_number: context.issue.number,
labels: labels,
owner: context.repo.owner,
repo: context.repo.repo,
});
# Output a list of 'tf' prefixed labels.
- name: Get labels
uses: actions/github-script@v6
id: labels
with:
script: |
return (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
// Short-circuit evaluation to get a SHA from any change event
commit_sha: context.payload.after || context.payload.pull_request.head.sha || context.sha,
owner: context.repo.owner,
repo: context.repo.repo,
})
).data[0].labels
.filter((label) => label.name.startsWith('tf'))
.map((label) => {
let [head, body] = label.name.split(':');
return [head, body];
});
run:
# Run terraform if one or more 'tf' prefixed labels are present.
needs: [labels]
if: toJSON(fromJSON(needs.labels.outputs.matrix)) != '[]'
runs-on: ubuntu-latest
# Run for each label and continue through to release state lock.
strategy:
fail-fast: false
matrix:
path: ${{ fromJSON(needs.labels.outputs.matrix) }}
# Update environment deployment status.
environment: ${{ matrix.path[1] }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Set environment variables.
- name: Environment variables
run: |
# Add terraform environment and workspace variables to GITHUB_ENV
string='${{ matrix.path[1] }}'
if [[ $string == *'--'* ]]; then
echo tf_environment=${string/--*/} >> $GITHUB_ENV
echo tf_workspace=${string/*--/} >> $GITHUB_ENV
else
echo tf_environment=${string} >> $GITHUB_ENV
echo tf_workspace='default' >> $GITHUB_ENV
fi
# Add input environment variables to GITHUB_ENV
for i in '${{ secrets.env }}'; do printf '%s\n' $i >> $GITHUB_ENV; done
# Initialise terraform workspace if one is specified.
- name: Terraform workspace
if: env.tf_workspace != 'default'
uses: dflook/terraform-new-workspace@v1
with:
workspace: ${{ env.tf_workspace }}
path: environments/${{ env.tf_environment }}
backend_config_file: environments/backend.tfvars
backend_config: key=environments/${{ env.tf_environment }}/terraform.tfstate
# Run terraform plan on 'pull_request' event.
- name: Terraform plan
if: github.event_name == 'pull_request'
uses: dflook/terraform-plan@v1
with:
label: ${{ matrix.path[1] }}
destroy: ${{ contains(matrix.path[0], 'destroy') }}
workspace: ${{ env.tf_workspace }}
path: environments/${{ env.tf_environment }}
backend_config_file: environments/backend.tfvars
backend_config: key=environments/${{ env.tf_environment }}/terraform.tfstate
# Run terraform apply on 'push' event or if 'auto_approve' label is present.
- name: Terraform apply
if: github.event_name == 'push' || contains(matrix.path[0], 'auto_approve')
uses: dflook/terraform-apply@v1
with:
label: ${{ matrix.path[1] }}
destroy: ${{ contains(matrix.path[0], 'destroy') }}
workspace: ${{ env.tf_workspace }}
path: environments/${{ env.tf_environment }}
backend_config_file: environments/backend.tfvars
backend_config: key=environments/${{ env.tf_environment }}/terraform.tfstate