@@ -11,6 +11,13 @@ variables:
1111 TOFU_VERSION : " 1.6.0"
1212 VAULT_ADDR : ${VAULT_ADDR}
1313 # Non inserire qui valori sensibili, usare le variabili CI/CD di GitLab
14+
15+ # Configurazione per ambienti
16+ # Queste variabili possono essere sovrascritte per ogni ambiente
17+ TF_VAR_default_node : " pve-node1"
18+ TF_VAR_default_datastore : " local-lvm"
19+ TF_VAR_network_bridge : " vmbr0"
20+ TF_VAR_proxmox_endpoint : " https://proxmox.example.com:8006/api2/json"
1421
1522# Cache terraform modules between runs
1623cache :
@@ -21,16 +28,47 @@ cache:
2128# Base container image for all jobs
2229image : alpine:3.19
2330
24- # Base configuration
31+ # Dichiarazione degli ambienti
32+ .environments :
33+ development :
34+ variables :
35+ CI_ENVIRONMENT_NAME : dev
36+ TF_VAR_default_node : " pve-dev-node"
37+ TF_VAR_proxmox_endpoint : " https://proxmox-dev.example.com:8006/api2/json"
38+ # Path Vault per l'ambiente di sviluppo
39+ TF_VAR_vault_proxmox_credentials_path : " terraform/dev/proxmox/api_credentials"
40+ TF_VAR_vault_ssh_keys_path : " terraform/dev/ssh_keys/ubuntu"
41+
42+ staging :
43+ variables :
44+ CI_ENVIRONMENT_NAME : staging
45+ TF_VAR_default_node : " pve-staging-node"
46+ TF_VAR_proxmox_endpoint : " https://proxmox-staging.example.com:8006/api2/json"
47+ # Path Vault per l'ambiente di staging
48+ TF_VAR_vault_proxmox_credentials_path : " terraform/staging/proxmox/api_credentials"
49+ TF_VAR_vault_ssh_keys_path : " terraform/staging/ssh_keys/ubuntu"
50+
51+ production :
52+ variables :
53+ CI_ENVIRONMENT_NAME : prod
54+ TF_VAR_default_node : " pve-prod-node"
55+ TF_VAR_proxmox_endpoint : " https://proxmox-prod.example.com:8006/api2/json"
56+ # Path Vault per l'ambiente di produzione
57+ TF_VAR_vault_proxmox_credentials_path : " terraform/prod/proxmox/api_credentials"
58+ TF_VAR_vault_ssh_keys_path : " terraform/prod/ssh_keys/ubuntu"
59+
60+ # Base configuration with Vault authentication
2561.tofu_base :
2662 before_script :
2763 # Install OpenTofu, curl, jq and other dependencies
2864 - apk add --no-cache curl unzip jq git bash ca-certificates
65+
2966 # Install OpenTofu
3067 - |
3168 curl -SL "https://github.com/opentofu/opentofu/releases/download/v${TOFU_VERSION}/tofu_${TOFU_VERSION}_linux_amd64.zip" -o /tmp/tofu.zip
3269 unzip /tmp/tofu.zip -d /usr/local/bin/
3370 rm /tmp/tofu.zip
71+
3472 # Configure OpenTofu state backend
3573 - |
3674 cat > backend.tf << EOF
@@ -47,14 +85,41 @@ image: alpine:3.19
4785 }
4886 }
4987 EOF
50- # Login in Vault e recupera i token necessari
88+
89+ # Login in Vault con AppRole (metodo consigliato per CI/CD)
5190 - |
52- if [ -n "$VAULT_TOKEN" ]; then
91+ if [ -n "${VAULT_APPROLE_ROLE_ID}" ] && [ -n "${VAULT_APPROLE_SECRET_ID}" ]; then
92+ echo "Logging into Vault with AppRole"
93+ export VAULT_TOKEN=$(curl -s --request POST \
94+ --data "{\"role_id\":\"${VAULT_APPROLE_ROLE_ID}\",\"secret_id\":\"${VAULT_APPROLE_SECRET_ID}\"}" \
95+ "${VAULT_ADDR}/v1/auth/approle/login" | jq -r '.auth.client_token')
96+
97+ # Verifica che il token sia stato ottenuto correttamente
98+ if [ -z "${VAULT_TOKEN}" ] || [ "${VAULT_TOKEN}" = "null" ]; then
99+ echo "Failed to obtain Vault token using AppRole"
100+ exit 1
101+ fi
102+
103+ # Configura le variabili per Terraform/OpenTofu
104+ export TF_VAR_vault_approle_enabled=true
105+ export TF_VAR_vault_approle_role_id=${VAULT_APPROLE_ROLE_ID}
106+ export TF_VAR_vault_approle_secret_id=${VAULT_APPROLE_SECRET_ID}
107+
108+ elif [ -n "${VAULT_TOKEN}" ]; then
53109 echo "Using provided VAULT_TOKEN"
54110 else
55- echo "Logging into Vault with CI role"
56- export VAULT_TOKEN=$(curl -s --request POST --data "{\"role\":\"ci-role\",\"jwt\":\"$CI_JOB_JWT\"}" "${VAULT_ADDR}/v1/auth/jwt/login" | jq -r '.auth.client_token')
111+ echo "No Vault authentication method available. Trying to use CI JWT token"
112+ export VAULT_TOKEN=$(curl -s --request POST \
113+ --data "{\"role\":\"ci-role\",\"jwt\":\"${CI_JOB_JWT}\"}" \
114+ "${VAULT_ADDR}/v1/auth/jwt/login" | jq -r '.auth.client_token')
115+
116+ if [ -z "${VAULT_TOKEN}" ] || [ "${VAULT_TOKEN}" = "null" ]; then
117+ echo "Failed to obtain Vault token using JWT"
118+ exit 1
119+ fi
57120 fi
121+
122+ # Inizializza OpenTofu
58123 - tofu init
59124
60125# Validate stage
@@ -67,8 +132,8 @@ validate:
67132 - if : $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
68133 when : always
69134
70- # Plan stage
71- plan :
135+ # Plan stage for different environments
136+ .plan_template : &plan_definition
72137 extends : .tofu_base
73138 stage : plan
74139 script :
@@ -77,20 +142,51 @@ plan:
77142 - tofu show -json plan.tfplan > plan.json
78143 # Extract a readable summary for the MR comment
79144 - jq -r '.resource_changes[] | "\(.address) will be \(.change.actions[0])"' plan.json > plan_summary.txt
145+ # Mostra un riassunto delle modifiche
146+ - echo "Plan summary:"
147+ - cat plan_summary.txt
80148 artifacts :
81149 paths :
82150 - plan.tfplan
83151 - plan.json
84152 - plan_summary.txt
85153 expire_in : 1 week
154+ allow_failure : false
155+
156+ # Plan per ambiente di sviluppo
157+ plan:dev :
158+ << : *plan_definition
159+ extends : .environments.development
160+ environment :
161+ name : dev
86162 rules :
87163 - if : $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
88164 when : always
89- - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
165+ - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "merge_request_event"
90166 when : always
91167
168+ # Plan per ambiente di staging
169+ plan:staging :
170+ << : *plan_definition
171+ extends : .environments.staging
172+ environment :
173+ name : staging
174+ rules :
175+ - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
176+ when : manual
177+
178+ # Plan per ambiente di produzione
179+ plan:production :
180+ << : *plan_definition
181+ extends : .environments.production
182+ environment :
183+ name : prod
184+ rules :
185+ - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
186+ when : manual
187+
92188# Apply stage - only on the default branch
93- apply :
189+ .apply_template : &apply_definition
94190 extends : .tofu_base
95191 stage : apply
96192 script :
@@ -100,16 +196,52 @@ apply:
100196 tofu apply plan.tfplan
101197 else
102198 echo "No plan found, creating and applying"
103- tofu apply -auto-approve
199+ tofu plan -out=new_plan.tfplan
200+ tofu apply new_plan.tfplan
104201 fi
105202 artifacts :
106203 paths :
107204 - terraform.tfstate
205+ reports :
206+ terraform : terraform.tfstate
207+ allow_failure : false
208+
209+ # Apply per ambiente di sviluppo
210+ apply:dev :
211+ << : *apply_definition
212+ extends : .environments.development
213+ environment :
214+ name : dev
215+ dependencies :
216+ - plan:dev
217+ rules :
218+ - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
219+ when : manual
220+
221+ # Apply per ambiente di staging
222+ apply:staging :
223+ << : *apply_definition
224+ extends : .environments.staging
225+ environment :
226+ name : staging
227+ dependencies :
228+ - plan:staging
229+ rules :
230+ - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
231+ when : manual
232+
233+ # Apply per ambiente di produzione
234+ apply:production :
235+ << : *apply_definition
236+ extends : .environments.production
237+ environment :
238+ name : prod
108239 dependencies :
109- - plan
240+ - plan:production
110241 rules :
111242 - if : $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
112243 when : manual
244+ allow_failure : false
113245
114246# Clean cached files periodically
115247cleanup :
@@ -125,4 +257,4 @@ cleanup:
125257 key : ${CI_COMMIT_REF_SLUG}
126258 paths :
127259 - .terraform
128- policy : pull
260+ policy : pull
0 commit comments