3333 type : number
3434 default : 3600
3535 description : ' The assumed role duration in seconds, if assuming a role. Defaults to 1 hour (3600 seconds). Acceptable values range from 15 minutes (900 seconds) to 12 hours (43200 seconds).'
36- enable_version_check :
37- required : false
38- type : boolean
39- default : false
40- description : ' Enable min/max version checking and testing against both versions.'
4136 enable_plan :
4237 required : false
4338 type : boolean
4439 default : false
45- description : ' Enable terraform plan step .'
40+ description : ' Allow workflow to run terraform plan.'
4641 show_plan :
4742 required : false
4843 type : boolean
4944 default : false
50- description : ' Show full terraform plan output. If false, only shows summary (e.g. Plan: 4 to add, 1 to change).'
51- gcp_credentials :
52- required : false
53- type : string
54- default : false
55- description : ' GCP credentials to use.'
45+ description : ' Controls Terraform plan output. When true, displays full plan details. When false, shows only a concise summary (e.g., Plan: X to add, Y to change, Z to destroy).'
5646 token_format :
5747 required : false
5848 type : string
7262 type : string
7363 default : true
7464 description : ' If true, the action will securely generate a credentials file which can be used for authentication via gcloud and Google Cloud SDKs.'
65+
7566 secrets :
7667 AZURE_CREDENTIALS :
7768 required : false
@@ -108,120 +99,54 @@ on:
10899 description : ' The service account to be used'
109100
110101jobs :
111- # Terraform version extract as output (only if version check is enabled)
112- versionExtract :
113- if : ${{ inputs.enable_version_check }}
114- name : 🏷️ Get min/max versions
115- runs-on : ubuntu-latest
116-
117- outputs :
118- minVersion : ${{ steps.minMax.outputs.minVersion }}
119- maxVersion : ${{ steps.minMax.outputs.maxVersion }}
120102
121- steps :
122- - name : 📦 Checkout Repository
123- uses : actions/checkout@v6
124-
125- - name : 🧮 Terraform min/max versions
126- id : minMax
127- uses : clowdhaus/terraform-min-max@main
128-
129- # Evaluate terraform version based on version extract (only if version check is enabled)
130- versionEvaluate :
131- if : ${{ inputs.enable_version_check }}
132- name : 🧪 Evaluate Terraform versions
103+ terraform-checks :
104+ name : 🌎 Terraform Full Checks
133105 runs-on : ubuntu-latest
134- needs : versionExtract
106+ env :
107+ TF_PLUGIN_CACHE_DIR : /tmp/terraform-plugin-cache
108+
135109 strategy :
136110 fail-fast : false
137111 matrix :
138- version :
139- - ${{ needs.versionExtract.outputs.minVersion }}
140- - ${{ needs.versionExtract.outputs.maxVersion }}
141- directory :
142- - ${{ inputs.working_directory }}
112+ version : ["min", "max"]
143113
144114 steps :
145115 - name : 📦 Checkout Repository
146116 uses : actions/checkout@v6
147-
148- - name : ☁️ Install AWS CLI
149- if : ${{ inputs.provider == 'aws' }}
150- uses : aws-actions/configure-aws-credentials@v6
151- with :
152- aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
153- aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
154- aws-session-token : ${{ secrets.AWS_SESSION_TOKEN }}
155- role-to-assume : ${{ secrets.BUILD_ROLE }}
156- aws-region : ${{ inputs.aws_region }}
157- role-duration-seconds : ${{ inputs.role_duration_seconds }}
158- role-skip-session-tagging : true
159-
160- - name : ☁️ Install Azure CLI
161- if : ${{ inputs.provider == 'azurerm' }}
162- uses : azure/login@v2
163117 with :
164- creds : ${{ secrets.AZURE_CREDENTIALS }}
118+ fetch-depth : 1
165119
166- - name : ☁️ Authenticate to Google Cloud
167- if : ${{ inputs.provider == 'gcp' }}
168- uses : ' google-github-actions/auth@v3'
169- with :
170- credentials_json : ' ${{ secrets.GCP_CREDENTIALS }}'
171- create_credentials_file : ${{ inputs.create_credentials_file }}
172- token_format : ${{ inputs.token_format }}
173- workload_identity_provider : ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}
174- service_account : ${{ secrets.SERVICE_ACCOUNT }}
175- access_token_lifetime : ${{ inputs.access_token_lifetime }}
176- project_id : ${{ inputs.project_id }}
120+ - name : 📁 Create Terraform plugin cache dir
121+ run : mkdir -p "$TF_PLUGIN_CACHE_DIR"
177122
178- - name : 🛠️ Install Terraform v${{ inputs.terraform_version || matrix.version }}
179- uses : hashicorp/setup-terraform@v3
180- with :
181- terraform_version : ${{ inputs.terraform_version || matrix.version }}
123+ - name : 🧮 Get Terraform min/max versions
124+ id : minmax
125+ uses : clowdhaus/terraform-min-max@main
182126
183- - name : 🏗️ Init & validate v${{ matrix.version }}
127+ - name : 🎯 Set Terraform version
128+ id : set-version
184129 run : |
185- cd ${{ matrix.directory }}
186- terraform init
187- terraform validate
188-
189- # Format check job (runs if version check is enabled)
190- format :
191- if : ${{ inputs.enable_version_check }}
192- name : 🧹 Check code format
193- runs-on : ubuntu-latest
194- needs : [versionExtract, versionEvaluate]
195-
196- steps :
197- - name : 📦 Checkout Repository
198- uses : actions/checkout@v6
130+ if [ "${{ matrix.version }}" = "min" ]; then
131+ echo "tf_version=${{ steps.minmax.outputs.minVersion }}" >> $GITHUB_OUTPUT
132+ else
133+ if [ -n "${{ inputs.terraform_version }}" ]; then
134+ echo "tf_version=${{ inputs.terraform_version }}" >> $GITHUB_OUTPUT
135+ else
136+ echo "tf_version=${{ steps.minmax.outputs.maxVersion }}" >> $GITHUB_OUTPUT
137+ fi
138+ fi
199139
200- - name : 🛠️ Install Terraform v${{ inputs.terraform_version || needs.versionExtract.outputs.maxVersion }}
201- uses : hashicorp/setup-terraform@v3
140+ - name : ♻️ Cache Terraform plugins
141+ uses : actions/cache@v4
202142 with :
203- terraform_version : ${{ inputs.terraform_version || needs.versionExtract.outputs.maxVersion }}
204-
205- - name : 🧹 Check Terraform format changes
206- run : terraform fmt --recursive -check=true
207-
208- # Main terraform checks job (runs if version check is disabled)
209- terraform-checks :
210- if : ${{ !inputs.enable_version_check }}
211- name : ' 🌎 Terraform Validate, Init and Plan'
212- runs-on : ubuntu-latest
213- env :
214- # This is needed since we are running terraform with read-only permissions
215- ARM_SKIP_PROVIDER_REGISTRATION : true
216- outputs :
217- tfplanExitCode : ${{ steps.tf-plan.outputs.exitcode }}
218-
219- steps :
220- - name : 📦 Checkout Repository
221- uses : actions/checkout@v6
143+ path : ${{ env.TF_PLUGIN_CACHE_DIR }}
144+ key : terraform-${{ runner.os }}-${{ hashFiles('**/.terraform.lock.hcl') }}
145+ restore-keys : |
146+ terraform-${{ runner.os }}-
222147
223148 - name : ☁️ Install AWS CLI
224- if : ${{ inputs.provider == 'aws' }}
149+ if : ${{ inputs.provider == 'aws' && inputs.enable_plan }}
225150 uses : aws-actions/configure-aws-credentials@v6
226151 with :
227152 aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -233,20 +158,20 @@ jobs:
233158 role-skip-session-tagging : true
234159
235160 - name : ☁️ Install Azure CLI
236- if : ${{ inputs.provider == 'azurerm' }}
161+ if : ${{ inputs.provider == 'azurerm' && inputs.enable_plan }}
237162 uses : azure/login@v2
238163 with :
239164 creds : ${{ secrets.AZURE_CREDENTIALS }}
240165
241- - name : 🟦 Install doctl
166+ - name : ☁️ Install DigitalOcean CLI
242167 if : ${{ inputs.provider == 'digitalocean' }}
243168 uses : digitalocean/action-doctl@v2
244169 with :
245170 token : ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
246171
247172 - name : ☁️ Authenticate to Google Cloud
248- if : ${{ inputs.provider == 'gcp' }}
249- uses : ' google-github-actions/auth@v3'
173+ if : ${{ inputs.provider == 'gcp' && inputs.enable_plan }}
174+ uses : google-github-actions/auth@v3
250175 with :
251176 credentials_json : ' ${{ secrets.GCP_CREDENTIALS }}'
252177 create_credentials_file : ${{ inputs.create_credentials_file }}
@@ -260,45 +185,42 @@ jobs:
260185 uses : hashicorp/setup-terraform@v3
261186 with :
262187 terraform_wrapper : false
263- terraform_version : ${{ inputs.terraform_version }}
188+ terraform_version : ${{ steps.set-version.outputs.tf_version }}
264189
265190 - name : 🧹 Terraform Format
266- uses : ' dflook/terraform-fmt-check@v2'
267-
268- - name : 🏗️ Terraform Init
269- id : init
270- run : terraform init -input=false
191+ run : terraform fmt --recursive -check=true
271192
272- - name : 🔎 Terraform validate
273- uses : dflook/terraform-validate@v2
274- with :
275- path : ${{ inputs.working_directory }}
193+ - name : 🏗️ Terraform Init & Terraform Validate
194+ working-directory : ${{ inputs.working_directory }}
195+ run : |
196+ terraform init -input=false -no-color
197+ terraform validate -no-color
276198
277199 - name : 📋 Terraform Plan
278200 id : tf-plan
279201 if : ${{ inputs.enable_plan }}
202+ working-directory : ${{ inputs.working_directory }}
280203 run : |
281204 export exitcode=0
282- cd ${{ inputs.working_directory }}
283-
205+ terraform version | head -n 1
206+
284207 if [ -n "${{ inputs.var_file }}" ]; then
285208 terraform plan -detailed-exitcode -no-color -out=tfplan --var-file=${{ inputs.var_file }} > plan.txt 2>&1 || exitcode=$?
286209 else
287210 terraform plan -detailed-exitcode -no-color -out=tfplan > plan.txt 2>&1 || exitcode=$?
288211 fi
289-
212+
290213 if [ $exitcode -eq 1 ]; then
291214 echo "Terraform Plan Failed!"
292215 cat plan.txt
293216 exit 1
294217 fi
295-
218+
296219 echo "exitcode=$exitcode" >> $GITHUB_OUTPUT
297-
220+
298221 if [ "${{ inputs.show_plan }}" == "true" ]; then
299- # Show full plan
300222 cat plan.txt
301223 else
302- # Show only summary
303224 grep -E '^Plan:|^No changes' plan.txt || echo "No changes."
304225 fi
226+ ...
0 commit comments