@@ -3,14 +3,6 @@ name: Terraform Apply from PR
33on :
44 push :
55 branches : [main]
6-
7- workflow_dispatch :
8- inputs :
9- environment :
10- description : ' Environment to apply (e.g., dev, shared)'
11- required : true
12- default : ' dev'
13-
146env :
157 TF_VAR_aws_account_id : ${{ secrets.AWS_ACCOUNT_ID }}
168 TF_VAR_aws_region : ${{ secrets.AWS_REGION }}
@@ -29,7 +21,6 @@ permissions:
2921
3022jobs :
3123 detect :
32- if : github.event_name != 'workflow_dispatch'
3324 runs-on : ubuntu-latest
3425 outputs :
3526 matrix : ${{ steps.set-matrix.outputs.matrix }}
@@ -47,42 +38,26 @@ jobs:
4738
4839 - name : Detect changed Terraform directories from PR
4940 if : steps.get_pr.outputs.pr_number
50- id : set-matrix
41+ id : detect_changes
5142 run : |
52- set -x # Enable shell tracing for debug
5343 PR_NUMBER=${{ steps.get_pr.outputs.pr_number }}
5444
5545 FILES=$(gh pr view $PR_NUMBER --json files --jq '.files[].path')
5646 echo "Changed files from PR $PR_NUMBER:"
5747 echo "$FILES"
5848
59- MATRIX="[]"
60-
6149 # Check for dev environment changes (terraform/env/dev/)
6250 if echo "$FILES" | grep -q "^terraform/env/dev/"; then
63- echo "Detected changes in terraform/env/dev/"
64- MATRIX=$(echo "$MATRIX" | jq -c '. + [{"dir":"terraform/env/dev","env":"dev","pr":"'$PR_NUMBER'"}]')
51+ echo "has_dev=true" >> $GITHUB_OUTPUT
6552 fi
6653
6754 # Check for shared infrastructure changes (top-level terraform/, excluding terraform/env/)
6855 if echo "$FILES" | grep "^terraform/" | grep -v "^terraform/env/" | grep -q .; then
69- echo "Detected changes in shared terraform/ (excluding env/)"
70- MATRIX=$(echo "$MATRIX" | jq -c '. + [{"dir":"terraform","env":"shared","pr":"'$PR_NUMBER'"}]')
71- fi
72-
73- echo "matrix={\"include\":$MATRIX}" >> $GITHUB_OUTPUT
74- echo "Matrix: {\"include\":$MATRIX}"
75-
76- # Set has_changes flag based on matrix length
77- if [ "$(echo "$MATRIX" | jq 'length')" -gt 0 ]; then
78- echo "has_changes=true" >> $GITHUB_OUTPUT
79- else
80- echo "has_changes=false" >> $GITHUB_OUTPUT
56+ echo "has_shared=true" >> $GITHUB_OUTPUT
8157 fi
8258
8359 apply :
84- needs : detect
85- if : github.event_name != 'workflow_dispatch' && needs.detect.outputs.has_changes == 'true'
60+ needs : detect_changes
8661 runs-on : ubuntu-latest
8762 steps :
8863 - uses : actions/checkout@v5
@@ -95,149 +70,16 @@ jobs:
9570 aws-region : ${{ env.TF_VAR_aws_region }}
9671 role-session-name : TerraformApplySession
9772
98- - name : Parse environments
99- id : parse
100- run : |
101- set -x # Enable shell tracing for debug
102- MATRIX='${{ needs.detect.outputs.matrix }}'
103- echo "Parsed matrix: $MATRIX"
104-
105- # Check if shared exists in matrix
106- SHARED=$(echo "$MATRIX" | jq -c '.include[] | select(.env == "shared")')
107- if [ -n "$SHARED" ]; then
108- echo "has_shared=true" >> $GITHUB_OUTPUT
109- echo "shared_dir=$(echo "$SHARED" | jq -r '.dir')" >> $GITHUB_OUTPUT
110- echo "shared_pr=$(echo "$SHARED" | jq -r '.pr')" >> $GITHUB_OUTPUT
111- echo "Shared entry: $SHARED"
112- else
113- echo "has_shared=false" >> $GITHUB_OUTPUT
114- fi
115-
116- # Check if dev exists in matrix
117- DEV=$(echo "$MATRIX" | jq -c '.include[] | select(.env == "dev")')
118- if [ -n "$DEV" ]; then
119- echo "has_dev=true" >> $GITHUB_OUTPUT
120- echo "dev_dir=$(echo "$DEV" | jq -r '.dir')" >> $GITHUB_OUTPUT
121- echo "dev_pr=$(echo "$DEV" | jq -r '.pr')" >> $GITHUB_OUTPUT
122- echo "Dev entry: $DEV"
123- else
124- echo "has_dev=false" >> $GITHUB_OUTPUT
125- fi
126-
12773 - name : Apply Shared Infrastructure
128- if : steps.parse.outputs.has_shared == 'true'
129- run : |
130- set -euxo pipefail
131- echo "Dumping environment variables for debug:"
132- env | sort
133-
134- echo "========================================="
135- echo "Applying Terraform for: shared"
136- echo "========================================="
137-
138- cd ${{ steps.parse.outputs.shared_dir }}
139-
140- terraform init -input=false -upgrade=false
141-
142- aws s3 cp s3://${{ env.TFPLAN_S3_BUCKET }}/shared/${{ steps.parse.outputs.shared_pr }}/tfplan tfplan
143-
144- terraform plan -input=false -out=tfplan-new
145-
146- terraform show -no-color tfplan > plan-old.txt
147- terraform show -no-color tfplan-new > plan-new.txt
148-
149- echo "--- plan-old.txt ---"
150- head -40 plan-old.txt || true
151- echo "--- plan-new.txt ---"
152- head -40 plan-new.txt || true
153-
154- if ! diff -q plan-old.txt plan-new.txt > /dev/null; then
155- echo "ERROR: Plans differ for shared - state has changed since PR"
156- diff plan-old.txt plan-new.txt || true
157- exit 1
158- fi
159-
160- if grep -q "No changes" plan-old.txt; then
161- echo "No changes detected in plan for shared, skipping apply"
162- else
163- echo "Applying changes for shared..."
164- terraform apply -input=false tfplan
165- echo "✅ Apply completed for shared"
166- fi
74+ if : steps.detect_changes.outputs.has_shared == 'true'
75+ uses : ./.github/actions/tf_apply
76+ with :
77+ working-directory : " terraform"
78+ env : shared
16779
16880 - name : Apply Dev Environment
169- if : steps.parse.outputs.has_dev == 'true'
170- run : |
171- set -euxo pipefail
172- echo "Dumping environment variables for debug:"
173- env | sort
174-
175- echo "========================================="
176- echo "Applying Terraform for: dev"
177- echo "========================================="
178-
179- cd ${{ steps.parse.outputs.dev_dir }}
180-
181- terraform init -input=false -upgrade=false
182-
183- aws s3 cp s3://${{ env.TFPLAN_S3_BUCKET }}/dev/${{ steps.parse.outputs.dev_pr }}/tfplan tfplan
184-
185- terraform plan -input=false -out=tfplan-new
186-
187- terraform show -no-color tfplan > plan-old.txt
188- terraform show -no-color tfplan-new > plan-new.txt
189-
190- echo "--- plan-old.txt ---"
191- head -40 plan-old.txt || true
192- echo "--- plan-new.txt ---"
193- head -40 plan-new.txt || true
194-
195- if ! diff -q plan-old.txt plan-new.txt > /dev/null; then
196- echo "ERROR: Plans differ for dev - state has changed since PR"
197- diff plan-old.txt plan-new.txt || true
198- exit 1
199- fi
200-
201- if grep -q "No changes" plan-old.txt; then
202- echo "No changes detected in plan for dev, skipping apply"
203- else
204- echo "Applying changes for dev..."
205- terraform apply -input=false tfplan
206- echo "✅ Apply completed for dev"
207- fi
208-
209- apply-dispatch :
210- needs : detect
211- if : github.event_name == 'workflow_dispatch'
212- runs-on : ubuntu-latest
213- steps :
214- - uses : actions/checkout@v5
215-
216- - uses : hashicorp/setup-terraform@v3
217-
218- - uses : aws-actions/configure-aws-credentials@v4
81+ if : steps.detect_changes.outputs.has_dev == 'true'
82+ uses : ./.github/actions/tf_apply
21983 with :
220- role-to-assume : ${{ env.TF_VAR_github_actions_role_arn }}
221- aws-region : ${{ env.TF_VAR_aws_region }}
222- role-session-name : TerraformApplySession
223-
224- - name : Apply Environment
225- run : |
226- set -euo pipefail
227- echo "========================================="
228- echo "Applying Terraform for: ${{ github.event.inputs.environment }}"
229- echo "========================================="
230-
231- if [ "${{ github.event.inputs.environment }}" == "shared" ]; then
232- cd terraform
233- else
234- cd terraform/env/${{ github.event.inputs.environment }}
235- fi
236-
237- terraform init -input=false -upgrade=false
238-
239- terraform plan -input=false -out=tfplan
240-
241- terraform apply -input=false tfplan
242-
243- echo "✅ Apply completed for dev"
84+ working-directory : " terraform/env/dev"
85+ env : dev
0 commit comments