-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathaction.yml
More file actions
325 lines (318 loc) · 13.8 KB
/
Copy pathaction.yml
File metadata and controls
325 lines (318 loc) · 13.8 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
name: "Run Terraform via Terragrunt"
description: "This action runs terraform or terragrunt including install, setup and caches"
author: Datadrivers GmbH
branding:
icon: "terminal"
color: "blue"
inputs:
terraform-version:
description: "terraform version to setup. Use 'disabled' to skip. Leave empty string to let tenv auto-detect (from .terraform-version / .tool-versions)."
required: false
default: ""
tenv-version:
description: "tenv version to setup."
required: false
default: "latest"
terragrunt-version:
description: "terragrunt version to setup. Use 'disabled' to skip. Leave empty string to let tenv auto-detect (from .terragrunt-version / .tool-versions)."
required: false
default: "disabled"
working-directory:
description: "working-directory for github step to run terragrunt/terraform command"
required: false
default: "."
terragrunt-cache-extra-key:
description: "string appended to terragrunt cache key "
required: false
default: ""
commands:
description: "commands execution line. For multiple commands use | multi line syntax; required to generate plan within commands files for pr comments"
required: false
use-aws-auth:
description: "Toggle to log in to aws"
required: false
default: "false"
aws-region:
description: "AWS Region for Login"
required: false
default: "eu-central-1"
aws-role-to-assume:
description: "AWS IAM Role for github action to access aws api"
required: false
default: ""
aws-role-duration-seconds:
description: "AWS session time"
required: false
default: "1800"
use-gcloud-auth:
description: "Toggle to log in via gcloud to aws"
required: false
default: "false"
gcp-workload-identity-provider:
description: |-
The full identifier of the Workload Identity Provider, including the
project number, pool name, and provider name. If provided, this must be
the full identifier which includes all parts, for example:
"projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider".
This is required if "use-gcloud-auth" is true.
required: false
default: ""
gcp-service-account-email:
description: |-
Email address or unique identifier of the Google Cloud service account for
which to generate credentials. This is required if
"workload_identity_provider" is specified and "use-gcloud-auth" is true.
required: false
default: ""
gcp-project-id:
description: |-
ID of the default project to use for future API calls and invocations. This is required if
"use-gcloud-auth" is true.
required: false
terragrunt-download:
description: "path to terragrunt cache dir storage"
required: false
default: "$HOME/.terragrunt-cache/"
skip-caches:
description: "Toggle to skip caches"
required: false
default: "false"
cache-terraform-plugins:
description: "Toggle to cache Terraform provider plugins independently from other caches"
required: false
default: "true"
cache-terragrunt-caches:
description: "Toggle to cache Terragrunt download/cache directory independently from other caches"
required: false
default: "true"
enable-debug:
description: "Add debug output to steps"
required: false
default: "false"
cache-tenv-tools:
description: "Enable caching of tenv managed tool versions (~/.tenv). Speeds up repeated runs by avoiding re-download of identical Terraform/Terragrunt versions."
required: false
default: "true"
outputs:
terragrunt-download-dir:
description: "Path to the terragrunt cache directory"
value: ${{ steps.config-caches.outputs.TG_DOWNLOAD_DIR }}
terraform-plugin-cache-dir:
description: "Path to the terraform plugin cache directory"
value: ${{ steps.config-caches.outputs.TF_PLUGIN_CACHE_DIR }}
terragrunt-provider-cache-dir:
description: "Path to the terragrunt provider cache directory (used with --provider-cache)"
value: ${{ steps.config-caches.outputs.TG_PROVIDER_CACHE_DIR }}
runs:
using: "composite"
steps:
- name: Resolve tenv version
id: resolve-tenv-version
shell: bash
if: inputs.terraform-version != 'disabled' || inputs.terragrunt-version != 'disabled'
env:
INPUT_TENV_VERSION: ${{ inputs.tenv-version }}
run: |
RESOLVED_VERSION=$(bash "${{ github.action_path }}/scripts/resolve-tenv-version.sh")
echo "resolved_version=$RESOLVED_VERSION" >> "$GITHUB_OUTPUT"
echo "TENV_VERSION=$RESOLVED_VERSION" >> "$GITHUB_ENV"
echo "Resolved tenv version: $RESOLVED_VERSION"
echo "TENV_INSTALLER_CACHE_DIR=$HOME/.cache/tenv-installer" >> "$GITHUB_ENV"
- name: Cache tenv installer
if: inputs.skip-caches == 'false' && inputs.cache-tenv-tools == 'true' && (inputs.terraform-version != 'disabled' || inputs.terragrunt-version != 'disabled')
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ env.TENV_INSTALLER_CACHE_DIR }}
key: ${{ runner.os }}-${{ runner.arch }}-tenv-installer-${{ steps.resolve-tenv-version.outputs.resolved_version }}
- name: Install tenv
if: inputs.terraform-version != 'disabled' || inputs.terragrunt-version != 'disabled'
shell: bash
env:
INPUT_TENV_VERSION: ${{ env.TENV_VERSION }}
run: |
bash "${{ github.action_path }}/scripts/install-tenv.sh"
- name: Set tenv root path
if: inputs.terraform-version != 'disabled' || inputs.terragrunt-version != 'disabled'
shell: bash
run: |
# Determine tenv root (allow override via TENV_ROOT env, else default)
TENV_ROOT_DIR="${TENV_ROOT:-$HOME/.tenv}"
echo "TENV_ROOT_DIR=$TENV_ROOT_DIR" >> "$GITHUB_ENV"
- name: Detect terraform/terragrunt versions (tenv)
shell: bash
run: |
tf_input="${{ inputs.terraform-version }}"
tg_input="${{ inputs.terragrunt-version }}"
workdir="${{ inputs.working-directory }}"
tf_ver="$tf_input"
tg_ver="$tg_input"
parse_version(){ # $1=tool name
awk -v tool="$1" 'tolower($1)==tolower(tool) && $2 ~ /^[0-9v]/ {gsub(/^v/,"",$2); print $2; exit}'
}
detect_tool(){ # $1=tool alias (tf/tg), $2=tool name for parse
local alias="$1" name="$2" out
out=$(pushd $workdir; tenv "$alias" detect 2>&1 || true)
printf '%s\n' "$out" | parse_version "$name"
}
# Terraform auto-detect
if [[ "$tf_input" != "disabled" && -z "$tf_input" ]]; then
detected_tf=$(detect_tool tf Terraform) || true
if [[ -n "$detected_tf" ]]; then
tf_ver="$detected_tf"
echo "Detected terraform version: $tf_ver"
fi
fi
# Terragrunt auto-detect
if [[ "$tg_input" != "disabled" && -z "$tg_input" ]]; then
detected_tg=$(detect_tool tg Terragrunt) || true
if [[ -n "$detected_tg" ]]; then
tg_ver="$detected_tg"
echo "Detected terragrunt version: $tg_ver"
fi
fi
# Export final values (could be explicit, detected, blank or 'disabled')
echo "tf_ver=$tf_ver" >> "$GITHUB_ENV"
echo "tg_ver=$tg_ver" >> "$GITHUB_ENV"
- name: Compute terraform plugin cache scope (by lockfile hash)
id: plugin-scope
if: inputs.skip-caches == 'false'
shell: bash
run: |
# Scope hashFiles to working-directory to ensure each stack has independent cache
workdir="${{ inputs.working-directory }}"
# Normalize path (remove trailing slash, handle '.')
workdir="${workdir%/}"
# Build scoped glob patterns for hashFiles
if [[ "$workdir" == "." || -z "$workdir" ]]; then
# Root directory - use standard glob
LOCK_HASH="${{ hashFiles('**/.terraform.lock.hcl', '**/versions.tf') }}"
else
# Scoped directory - prefix glob with working-directory path
LOCK_HASH="${{ hashFiles(format('{0}/**/.terraform.lock.hcl', inputs.working-directory), format('{0}/**/versions.tf', inputs.working-directory)) }}"
fi
[[ -z "$LOCK_HASH" ]] && LOCK_HASH="no-lock"
echo "lock_hash=$LOCK_HASH" >> "$GITHUB_OUTPUT"
- name: Build tenv cache paths
if: inputs.skip-caches == 'false' && inputs.cache-tenv-tools == 'true'
shell: bash
run: |
paths=()
# Terraform path logic
if [[ "${{ env.tf_ver }}" != "disabled" ]]; then
if [[ "${{ env.tf_ver }}" == "latest" || -z "${{ env.tf_ver }}" ]]; then
paths+=("${{ env.TENV_ROOT_DIR }}/Terraform/")
else
paths+=("${{ env.TENV_ROOT_DIR }}/Terraform/${{ env.tf_ver }}")
fi
fi
# Terragrunt path logic
if [[ "${{ env.tg_ver }}" != "disabled" ]]; then
if [[ "${{ env.tg_ver }}" == "latest" || -z "${{ env.tg_ver }}" ]]; then
paths+=("${{ env.TENV_ROOT_DIR }}/Terragrunt/")
else
paths+=("${{ env.TENV_ROOT_DIR }}/Terragrunt/${{ env.tg_ver }}")
fi
fi
# OpenTofu (always included for now)
paths+=("${{ env.TENV_ROOT_DIR }}/OpenTofu/")
# Join paths with newline and export
cache_paths=$(printf '%s\n' "${paths[@]}")
echo "TENV_CACHE_PATHS<<EOF" >> "$GITHUB_ENV"
echo "$cache_paths" >> "$GITHUB_ENV"
echo "EOF" >> "$GITHUB_ENV"
- name: Cache tenv managed tool versions
if: inputs.skip-caches == 'false' && inputs.cache-tenv-tools == 'true'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: ${{ env.TENV_CACHE_PATHS }}
key: ${{ runner.os }}-tenv-${{ env.tf_ver }}-${{ env.tg_ver }}-${{ hashFiles('**/.terraform-version','**/.terragrunt-version','**/.opentofu-version') }}
restore-keys: |
${{ runner.os }}-tenv-${{ env.tf_ver }}-${{ env.tg_ver }}
- name: Installs terraform
if: inputs.terraform-version != 'disabled'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
# Terraform install logic
if [[ "${tf_ver}" != "disabled" ]]; then
if [[ -z "${tf_ver}" ]]; then
export TENV_AUTO_INSTALL=true
tenv tf install
else
tenv tf install "${tf_ver}"
fi
fi
- name: Install terragrunt
if: inputs.terragrunt-version != 'disabled'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
# Terragrunt install logic
if [[ "${tg_ver}" != "disabled" ]]; then
if [[ -z "${tg_ver}" ]]; then
export TENV_AUTO_INSTALL=true
tenv tg install
else
tenv tg install "${tg_ver}"
fi
fi
- name: Configure caches
id: config-caches
if: inputs.skip-caches == 'false'
env:
INPUT_TERRAGRUNT_DOWNLOAD: ${{ inputs.terragrunt-download }}
shell: bash
run: |
TF_PLUGIN_CACHE_BASE="$HOME/.terraform.d/plugin-cache"
# Scope plugin cache to lockfile hash to avoid accumulating old provider versions
TF_PLUGIN_CACHE_DIR="$TF_PLUGIN_CACHE_BASE/${{ steps.plugin-scope.outputs.lock_hash }}"
echo "TF_PLUGIN_CACHE_DIR=$TF_PLUGIN_CACHE_DIR" >> $GITHUB_ENV
echo "TF_PLUGIN_CACHE_DIR=$TF_PLUGIN_CACHE_DIR" >> $GITHUB_OUTPUT
mkdir --parents "$TF_PLUGIN_CACHE_DIR"
TG_DOWNLOAD_DIR=${INPUT_TERRAGRUNT_DOWNLOAD//\$HOME/$HOME} # make sure $HOME is expanded
echo "TG_DOWNLOAD_DIR=$TG_DOWNLOAD_DIR" >> $GITHUB_ENV
echo "TG_DOWNLOAD_DIR=$TG_DOWNLOAD_DIR" >> $GITHUB_OUTPUT
mkdir --parents $TG_DOWNLOAD_DIR
# Configure Terragrunt provider cache directory (used with --provider-cache)
TG_PROVIDER_CACHE_DIR="${TG_DOWNLOAD_DIR}/terragrunt/providers/"
echo "TG_PROVIDER_CACHE_DIR=$TG_PROVIDER_CACHE_DIR" >> $GITHUB_ENV
echo "TG_PROVIDER_CACHE_DIR=$TG_PROVIDER_CACHE_DIR" >> $GITHUB_OUTPUT
mkdir --parents "$TG_PROVIDER_CACHE_DIR"
# clean up to make sure self-hosted runner dirs are clean
shopt -s dotglob
cd "${TG_DOWNLOAD_DIR:?}" && rm -rf *
- name: Cache Terraform plugins
if: inputs.skip-caches == 'false' && inputs.cache-terraform-plugins == 'true' && steps.plugin-scope.outputs.lock_hash != 'no-lock'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
${{ env.TF_PLUGIN_CACHE_DIR }}
key: ${{ runner.os }}-terraform-${{ steps.plugin-scope.outputs.lock_hash }}
- name: Cache Terragrunt caches
if: inputs.skip-caches == 'false' && inputs.cache-terragrunt-caches == 'true'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
with:
path: |
${{ env.TG_DOWNLOAD_DIR }}
key: ${{ runner.os }}-${{ env.TG_DOWNLOAD_DIR }}-${{ hashFiles('**/terragrunt.hcl','**/.terraform.lock.hcl', '**/versions.tf') }}${{ inputs.terragrunt-cache-extra-key }}
- id: "gcloud-auth"
if: inputs.use-gcloud-auth == 'true'
name: "Authenticate to GCP"
uses: "google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093" # v3
with:
project_id: ${{ inputs.gcp-project-id }}
workload_identity_provider: ${{ inputs.gcp-workload-identity-provider }}
service_account: ${{ inputs.gcp-service-account-email }}
- id: "aws-auth"
if: inputs.use-aws-auth == 'true'
name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6
with:
aws-region: ${{ inputs.aws-region }}
role-to-assume: ${{ inputs.aws-role-to-assume }}
role-duration-seconds: ${{ inputs.aws-role-duration-seconds }}
- name: Run Terraform
shell: bash
working-directory: ${{ inputs.working-directory }}
if: inputs.commands != ''
run: ${{ inputs.commands }}