1+ name : Terraform CI/CD
2+
3+ on :
4+ pull_request :
5+ branches : [deploy]
6+ push :
7+ branches : [deploy]
8+
9+ permissions :
10+ id-token : write # Required for Azure OIDC
11+ contents : write # Needed to commit manifest updates
12+ pull-requests : write # Needed to open PRs
13+
14+ env :
15+ TF_VAR_application_name : ${{ vars.APPLICATION_NAME }}
16+ TF_VAR_application_oauth_client_id : ${{ secrets.APPLICATION_OAUTH_CLIENT_ID }}
17+ TF_VAR_application_oauth_client_secret : ${{ secrets.APPLICATION_OAUTH_CLIENT_SECRET }}
18+ TF_VAR_location : ${{ vars.AZURE_LOCATION }}
19+ TF_VAR_execution_mode : ci
20+ ACR_NAME : ${{ vars.ACR_NAME }}
21+
22+ jobs :
23+ terraform :
24+ runs-on : ubuntu-latest
25+
26+ steps :
27+ # Checkout repo
28+ - name : Checkout repository
29+ uses : actions/checkout@v4
30+
31+ # Install Terraform
32+ - name : Setup Terraform
33+ uses : hashicorp/setup-terraform@v2
34+ with :
35+ terraform_version : 1.10.5
36+
37+ # Temporarily remove repo provider configuration
38+ - name : Disable repo azurerm provider
39+ working-directory : terraform/azure
40+ run : mv providers.tf providers.tf.bak
41+
42+ # Create CI-only backend + OIDC provider
43+ - name : Create CI Azure backend/provider
44+ working-directory : terraform/azure
45+ run : |
46+ cat <<EOF > azure_ci.tf
47+ terraform {
48+ backend "azurerm" {}
49+ }
50+
51+ provider "azurerm" {
52+ features {}
53+ }
54+ EOF
55+
56+ - name : Configure Azure OIDC environment
57+ run : |
58+ echo "ARM_USE_OIDC=true" >> $GITHUB_ENV
59+ echo "ARM_CLIENT_ID=${{ secrets.AZURE_CLIENT_ID }}" >> $GITHUB_ENV
60+ echo "ARM_TENANT_ID=${{ secrets.AZURE_TENANT_ID }}" >> $GITHUB_ENV
61+ echo "ARM_SUBSCRIPTION_ID=${{ secrets.AZURE_SUBSCRIPTION_ID }}" >> $GITHUB_ENV
62+
63+ - name : Azure Login
64+ uses : azure/login@v1
65+ with :
66+ client-id : ${{ secrets.AZURE_CLIENT_ID }}
67+ tenant-id : ${{ secrets.AZURE_TENANT_ID }}
68+ subscription-id : ${{ secrets.AZURE_SUBSCRIPTION_ID }}
69+
70+ - name : Login to ACR
71+ run : |
72+ TOKEN=$(az acr login --name ${{ env.ACR_NAME }} --expose-token --output tsv --query accessToken)
73+ docker login -u 00000000-0000-0000-0000-000000000000 --password-stdin ${{ env.ACR_NAME }}.azurecr.io <<< $TOKEN
74+
75+ - name : Terraform Init
76+ working-directory : terraform/azure
77+ run : |
78+ terraform init -upgrade -reconfigure\
79+ -backend-config="resource_group_name=${{ vars.AZURE_RG }}" \
80+ -backend-config="storage_account_name=${{ vars.AZURE_STORAGE_ACCOUNT }}" \
81+ -backend-config="container_name=${{ vars.AZURE_CONTAINER }}" \
82+ -backend-config="key=${{ vars.AZURE_TFSTATE_KEY }}" \
83+ -backend-config="use_oidc=true"
84+
85+ - name : Debug backend values
86+ run : |
87+ terraform state pull | head -20
88+ echo "RG=${{ vars.AZURE_RG }}"
89+ echo "SA=${{ vars.AZURE_STORAGE_ACCOUNT }}"
90+ echo "CONTAINER=${{ vars.AZURE_CONTAINER }}"
91+ echo "KEY=${{ vars.AZURE_TFSTATE_KEY }}"
92+
93+ # Terraform plan (PR only)
94+ - name : Terraform Plan
95+ if : github.event_name == 'pull_request'
96+ working-directory : terraform/azure
97+ run : terraform plan -out=tfplan
98+
99+ # Terraform apply (merge to main only)
100+ - name : Terraform Apply
101+ if : github.event_name == 'push'
102+ working-directory : terraform/azure
103+ run : |
104+ terraform plan -out=tfplan
105+ terraform apply -auto-approve tfplan
106+
107+ # Cleanup CI-only files
108+ - name : Cleanup CI Terraform files
109+ working-directory : terraform/azure
110+ run : |
111+ rm -f azure_ci.tf
112+ mv providers.tf.bak providers.tf
0 commit comments