1- name : Azure Template Validation
2- on :
3- workflow_dispatch :
4- push :
5- branches :
6- - main
7- - vee-pipeline-fixes
1+ name : Azure Template Validation
2+ on :
3+ # workflow_dispatch:
4+ push :
5+ branches :
6+ - main
87permissions :
98 contents : read
109 id-token : write
1110 pull-requests : write
12- jobs :
13- template_validation_job :
14- runs-on : ubuntu-latest
15- environment : validation
16- name : Template validation
17- env :
18- AZURE_CLIENT_SECRET : ${{ secrets.AZURE_CLIENT_SECRET }}
19- steps :
20- - name : Checkout code
21- uses : actions/checkout@v4
22-
23- - name : Pre-flight secret check
24- id : secret_check
25- run : |
26- # GitHub Actions expressions are evaluated before the shell loop runs, so we cannot
27- # index into secrets dynamically like secrets[format('{0}', var)]. Instead, check each explicitly.
28- missing=0
29- if [ -z "${{ secrets.AZURE_CLIENT_ID }}" ]; then echo "::error::Required secret AZURE_CLIENT_ID is missing." >&2; missing=1; fi
30- if [ -z "${{ secrets.AZURE_TENANT_ID }}" ]; then echo "::error::Required secret AZURE_TENANT_ID is missing." >&2; missing=1; fi
31- if [ -z "${{ secrets.AZURE_SUBSCRIPTION_ID }}" ]; then echo "::error::Required secret AZURE_SUBSCRIPTION_ID is missing." >&2; missing=1; fi
32- if [ -z "${{ secrets.AZURE_LOCATION }}" ]; then echo "::warning::AZURE_LOCATION not set; defaulting to eastus for validation context."; echo "AZURE_LOCATION=eastus" >> $GITHUB_ENV; else echo "AZURE_LOCATION=${{ secrets.AZURE_LOCATION }}" >> $GITHUB_ENV; fi
33- if [ "$missing" -eq 1 ]; then
34- echo "Missing required secrets. Failing early." >&2
35- exit 1
36- fi
37- echo "All required auth secrets present (client secret not required for OIDC)."
38-
39- - name : Ensure Bicep CLI installed
40- run : |
41- az bicep install || true
42- - name : Azure Login (Service Principal Client Secret)
43- if : ${{ env.AZURE_CLIENT_SECRET != '' }}
44- run : |
45- echo "Using service principal client secret authentication path."
46- az login --service-principal \
47- -u ${{ secrets.AZURE_CLIENT_ID }} \
48- -p ${{ secrets.AZURE_CLIENT_SECRET }} \
49- --tenant ${{ secrets.AZURE_TENANT_ID }}
50- az account set --subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
51- --tenant ${{ secrets.AZURE_TENANT_ID }}
52- - name : Azure Login (OIDC) (no client secret present)
53- if : ${{ env.AZURE_CLIENT_SECRET == '' }}
54- uses : azure/login@v1
55- with :
56- client-id : ${{ secrets.AZURE_CLIENT_ID }}
57- tenant-id : ${{ secrets.AZURE_TENANT_ID }}
58- subscription-id : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
59- continue-on-error : false
60-
61- - name : Auth Mode Announcement
62- run : |
63- if [ -n "${{ secrets.AZURE_CLIENT_SECRET }}" ]; then
64- echo "Auth mode: client secret (SP). OIDC skipped."
65- else
66- echo "Auth mode: OIDC (no client secret set). Ensure federated credential exists for environment 'validation'."
67- fi
68-
69- - name : Post-login diagnostics
70- if : always()
71- run : |
72- echo "Login diagnostics:"
73- az account show || echo "Account show failed" >&2
74- echo "Listing subscriptions (top 5):"; az account list --query '[].{name:name,id:id}' -o table | head -n 7 || true
75- echo "Active tenant: ${{ secrets.AZURE_TENANT_ID }}"
76- echo "Client ID suffix: $(echo '${{ secrets.AZURE_CLIENT_ID }}' | tail -c 6)"
77-
78- - name : Debug Azure context
79- run : |
80- az account show || echo "Could not show account (ensure privileges)" >&2
81- echo "Listing bicep version:"; az bicep version || true
82- echo "Listing repo root:"; ls -1 . || true
83- echo "Infra directory content:"; ls -1 infra || true
84- echo "Resolved AZURE_LOCATION: ${AZURE_LOCATION:-unset}"
85-
86- - name : Validate Azure Template
87- id : validation
88- uses : microsoft/template-validation-action@main
89- env :
90- AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
91- AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
92- AZURE_SUBSCRIPTION_ID : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
93- AZURE_LOCATION : ${{ secrets.AZURE_LOCATION }}
94- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
95- continue-on-error : true
96-
97- - name : Capture validation output
98- id : capture
99- run : |
100- out="${{ steps.validation.outputs.resultFile }}"
101- if [ -n "$out" ] && [ -f "$out" ]; then
102- cp "$out" validation-result.json
103- else
104- echo '{"warning":"No resultFile produced by action"}' > validation-result.json
105- fi
106- echo "result_path=validation-result.json" >> $GITHUB_OUTPUT
107-
108- - name : Print validation result
109- if : always()
110- run : |
111- echo "--- validation-result.json ---"
112- cat validation-result.json || echo "No validation-result.json present" >&2
113-
114- - name : Upload validation result artifact
115- if : always()
116- uses : actions/upload-artifact@v4
117- with :
118- name : validation-result
119- path : validation-result.json
120- retention-days : 7
121-
122- - name : Fail if validation errors detected
123- run : |
124- file='validation-result.json'
125- if [ ! -f "$file" ]; then
126- echo "No validation result file produced; failing." >&2
127- exit 1
128- fi
129- if grep -Ei '"(status|level)" *: *"error"' "$file" || grep -Ei '\b(error|failed)\b' "$file"; then
130- echo "Errors detected in template validation output." >&2
131- cat "$file"
132- exit 1
133- fi
134- # Also treat underlying action non-zero exit as failure even if heuristic passes.
135- if [ "${{ steps.validation.outcome }}" = "failure" ]; then
136- echo "Underlying validation action reported failure (steps.validation.outcome)." >&2
137- exit 1
138- fi
139- echo "No blocking errors detected in validation output."
11+ jobs :
12+ template_validation_job :
13+ runs-on : ubuntu-latest
14+ environment : dev
15+ name : Template validation
16+ steps :
17+ # Step 1: Checkout the code from your repository
18+ - name : Checkout code
19+ uses : actions/checkout@v4
20+ # Step 2: Validate the Azure template using microsoft/template-validation-action
21+ - name : Validate Azure Template
22+ uses : microsoft/template-validation-action@v0.3.5
23+ id : validation
24+ env :
25+ AZURE_CLIENT_ID : ${{ secrets.AZURE_CLIENT_ID }}
26+ AZURE_CLIENT_SECRET : ${{ secrets.AZURE_CLIENT_SECRET }}
27+ AZURE_TENANT_ID : ${{ secrets.AZURE_TENANT_ID }}
28+ AZURE_SUBSCRIPTION_ID : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
29+ AZURE_ENV_NAME : ${{ secrets.AZURE_ENV_NAME }}
30+ AZURE_LOCATION : ${{ secrets.AZURE_LOCATION }}
31+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
32+ # Step 3: Print the result of the validation
33+ - name : Print result
34+ run : cat ${{ steps.validation.outputs.resultFile }}
0 commit comments