Skip to content

Commit 1bc7e47

Browse files
committed
opentofu
1 parent 5b1d90e commit 1bc7e47

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

.gitlab/ci/opentofu.yml

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# GitLab CI configuration for OpenTofu/Terraform with GitOps approach
2+
3+
stages:
4+
- validate
5+
- plan
6+
- apply
7+
- cleanup
8+
9+
# Variables
10+
variables:
11+
TOFU_VERSION: "1.6.0"
12+
VAULT_ADDR: ${VAULT_ADDR}
13+
# Non inserire qui valori sensibili, usare le variabili CI/CD di GitLab
14+
15+
# Cache terraform modules between runs
16+
cache:
17+
key: ${CI_COMMIT_REF_SLUG}
18+
paths:
19+
- .terraform
20+
21+
# Base container image for all jobs
22+
image: alpine:3.19
23+
24+
# Base configuration
25+
.tofu_base:
26+
before_script:
27+
# Install OpenTofu, curl, jq and other dependencies
28+
- apk add --no-cache curl unzip jq git bash ca-certificates
29+
# Install OpenTofu
30+
- |
31+
curl -SL "https://github.com/opentofu/opentofu/releases/download/v${TOFU_VERSION}/tofu_${TOFU_VERSION}_linux_amd64.zip" -o /tmp/tofu.zip
32+
unzip /tmp/tofu.zip -d /usr/local/bin/
33+
rm /tmp/tofu.zip
34+
# Configure OpenTofu state backend
35+
- |
36+
cat > backend.tf << EOF
37+
terraform {
38+
backend "http" {
39+
address = "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}"
40+
lock_address = "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}/lock"
41+
unlock_address = "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}-${CI_ENVIRONMENT_NAME}/lock"
42+
username = "gitlab-ci-token"
43+
password = "${CI_JOB_TOKEN}"
44+
lock_method = "POST"
45+
unlock_method = "DELETE"
46+
retry_wait_min = 5
47+
}
48+
}
49+
EOF
50+
# Login in Vault e recupera i token necessari
51+
- |
52+
if [ -n "$VAULT_TOKEN" ]; then
53+
echo "Using provided VAULT_TOKEN"
54+
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')
57+
fi
58+
- tofu init
59+
60+
# Validate stage
61+
validate:
62+
extends: .tofu_base
63+
stage: validate
64+
script:
65+
- tofu validate
66+
rules:
67+
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
68+
when: always
69+
70+
# Plan stage
71+
plan:
72+
extends: .tofu_base
73+
stage: plan
74+
script:
75+
- tofu plan -out=plan.tfplan
76+
# Convert the plan to JSON for the approval
77+
- tofu show -json plan.tfplan > plan.json
78+
# Extract a readable summary for the MR comment
79+
- jq -r '.resource_changes[] | "\(.address) will be \(.change.actions[0])"' plan.json > plan_summary.txt
80+
artifacts:
81+
paths:
82+
- plan.tfplan
83+
- plan.json
84+
- plan_summary.txt
85+
expire_in: 1 week
86+
rules:
87+
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
88+
when: always
89+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
90+
when: always
91+
92+
# Apply stage - only on the default branch
93+
apply:
94+
extends: .tofu_base
95+
stage: apply
96+
script:
97+
- |
98+
if [ -f plan.tfplan ]; then
99+
echo "Applying existing plan"
100+
tofu apply plan.tfplan
101+
else
102+
echo "No plan found, creating and applying"
103+
tofu apply -auto-approve
104+
fi
105+
artifacts:
106+
paths:
107+
- terraform.tfstate
108+
dependencies:
109+
- plan
110+
rules:
111+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
112+
when: manual
113+
114+
# Clean cached files periodically
115+
cleanup:
116+
stage: cleanup
117+
script:
118+
- rm -rf .terraform
119+
- echo "Removed cached files"
120+
when: manual
121+
rules:
122+
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
123+
when: manual
124+
cache:
125+
key: ${CI_COMMIT_REF_SLUG}
126+
paths:
127+
- .terraform
128+
policy: pull

0 commit comments

Comments
 (0)