OpenTofu pipeline
Ten pipeline realizuje standardowy przepływ IaC dla OpenTofu (Terraform-compatible) w GitLab CI:
- Walidacja formatowania (
tofu fmt) - Walidacja konfiguracji (
tofu validate) - Linting (
tflint) - Plan (
tofu plan) - Apply (
tofu apply) – kontrolowane regułami oraz zależne od publikacji wersji
Pipeline wykorzystuje GitLab Terraform State jako backend dla OpenTofu.
Wymagania
Section titled “Wymagania”-
Repozytorium zawiera kod OpenTofu (np.
*.tf). -
Dostęp do obrazu:
registry.rachuna-net.pl/pl.rachuna-net/containers/opentofu:1.0.0
-
Repozytorium ma dostęp do API GitLab (standardowo zapewnia
CI_JOB_TOKEN). -
Zdefiniowane etapy w
.gitlab-ci.ymlobejmują co najmniej:validateunit-testdeploy
-
W pipeline istnieje job
📍 Publish Version(wymagany przezneedswopentofu apply).
Struktura pipeline
Section titled “Struktura pipeline”Zmienne
Section titled “Zmienne”| Zmienna | Domyślna wartość | Opis |
|---|---|---|
OPENTOFU_IMAGE | registry.rachuna-net.pl/pl.rachuna-net/containers/opentofu:1.0.0 | Obraz kontenera z OpenTofu oraz narzędziami (tflint). |
TF_STATE_NAME | production (fallback) | Nazwa stanu w GitLab Terraform State; używana w adresie backendu. |
Uwaga: TF_STATE_NAME nie jest wymagane — jeśli nie ustawisz, pipeline użyje production.
Include: tofu-init.sh.yml
Section titled “Include: tofu-init.sh.yml”Pipeline dołącza lokalny plik:
include:
- local: "pipelines/opentofu/tofu-init.sh.yml"W nim znajduje się snippet .!tofu-init.sh.yml, który wykonuje tofu init skonfigurowany pod GitLab Terraform State.
Co robi .tofu-init.sh.yml
Section titled “Co robi .tofu-init.sh.yml”- wypisuje wersję OpenTofu (
tofu version) - wykonuje
tofu initz parametrami backendu GitLab:
Backend URL (state):
address=${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME:-production}
Locking:
lock_address=.../lockunlock_address=.../locklock_method=POSTunlock_method=DELETE
Autoryzacja:
username=gitlab-ci-tokenpassword=${CI_JOB_TOKEN}
Retry:
retry_wait_min=5
Dlaczego to jest ważne
Section titled “Dlaczego to jest ważne”Dzięki temu:
- stan Terraform/OpenTofu jest przechowywany centralnie w GitLab (zamiast lokalnie lub w S3),
- lock działa przez GitLab API, co ogranicza ryzyko równoległych
apply.
Joby: opis i zachowanie
Section titled “Joby: opis i zachowanie”1) 🕵 opentofu fmt (stage: validate)
Section titled “1) 🕵 opentofu fmt (stage: validate)”Cel: Weryfikacja formatowania plików OpenTofu bez modyfikacji kodu.
Komenda:
tofu fmt -recursive -checkKiedy się uruchamia: zawsze (na sukces), na każdym pipeline.
Efekt: pipeline failuje, jeśli formatowanie nie jest zgodne.
2) ✅ opentofu validate (stage: validate)
Section titled “2) ✅ opentofu validate (stage: validate)”Cel: Walidacja składni i spójności konfiguracji.
Wymaga init: tak (żeby pobrać providerów/moduły).
Komenda:
tofu validateEfekt: pipeline failuje, jeśli konfiguracja jest błędna.
3) ✅ tflint (stage: validate)
Section titled “3) ✅ tflint (stage: validate)”Cel: Linting kodu IaC (wykrywanie antywzorców i problemów jakościowych).
Wymaga init: tak (często potrzebne do kontekstu providerów/modułów).
Komenda:
tflintWażne: jeśli tflint ma być użyte sensownie, repo zwykle posiada .tflint.hcl lub konfigurację domyślną.
4) 🧪 opentofu plan (stage: unit-test)
Section titled “4) 🧪 opentofu plan (stage: unit-test)”Cel: Wygenerowanie planu zmian dla infrastruktury.
Komenda:
tofu planZachowanie: plan jest generowany, ale w aktualnej konfiguracji:
- nie jest zapisywany jako artifact,
- nie jest publikowany jako raport,
applynie konsumuje planu (wykonuje niezależneapply).
Rekomendacja (opcjonalna): Jeśli chcesz deterministycznego wdrożenia, rozważ:
tofu plan -out=plan.bin- artifact
plan.bin tofu apply plan.bin
5) 💥 opentofu apply (stage: deploy)
Section titled “5) 💥 opentofu apply (stage: deploy)”Cel: Zastosowanie zmian w infrastrukturze.
Komenda:
tofu apply -auto-approveZależności:
needs:
- job: 📍 Publish VersionTo wymusza, aby apply wykonało się dopiero po ukończeniu joba publikującego wersję (np. release/tagging).
Reguły uruchomienia (rules)
Section titled “Reguły uruchomienia (rules)”-
Jeżeli pipeline jest uruchomiony z taga (
CI_COMMIT_TAG) → apply jest blokowane:- if: $CI_COMMIT_TAG when: neverSkutek: nie ma wdrożeń „z taga”.
-
Jeżeli branch = domyślny (
main/master) → apply odpala się automatycznie:- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH when: on_success -
Jeżeli są otwarte MR (
CI_OPEN_MERGE_REQUESTS) → apply jest manualne:- if: $CI_OPEN_MERGE_REQUESTS when: manualSkutek: dla gałęzi z MR nie ma automatycznego wdrażania; ktoś musi ręcznie kliknąć job.
Jak ustawić nazwę stanu (TF_STATE_NAME)
Section titled “Jak ustawić nazwę stanu (TF_STATE_NAME)”Domyślnie
Section titled “Domyślnie”Jeśli nic nie ustawisz, backend użyje:
production
Przykład: środowiska
Section titled “Przykład: środowiska”Możesz zdefiniować TF_STATE_NAME per environment:
productionstagingdev
Przykład ustawienia w pipeline (np. w variables: lub w UI projektu):
variables:
TF_STATE_NAME: "staging"Bezpieczeństwo i uprawnienia
Section titled “Bezpieczeństwo i uprawnienia”-
tofu initużywaCI_JOB_TOKENjako hasła do backendu GitLab Terraform State. -
Uprawnienia
CI_JOB_TOKENsą zależne od ustawień projektu i GitLab. -
Jeśli wdrożenia mają wykonywać akcje na chmurze/infra (np. Proxmox, Vault, DNS, itp.), wymagane są odpowiednie sekrety (np. tokeny providerów) dostarczane przez:
- GitLab CI Variables (masked/protected),
- Vault, jeśli masz integrację,
- dedykowane service accounts.
Typowe problemy i diagnoza
Section titled “Typowe problemy i diagnoza”tofu validate / tofu plan padają, bo brak providerów
Section titled “tofu validate / tofu plan padają, bo brak providerów”Sprawdź, czy .tofu-init.sh.yml jest wywoływany w before_script dla jobów:
validatetflintplanapply
W Twojej konfiguracji jest poprawnie.
Locking / backend nie działa
Section titled “Locking / backend nie działa”Zweryfikuj:
- czy GitLab ma włączoną funkcję Terraform State dla projektu,
- czy ścieżka API jest dostępna,
- czy
CI_JOB_TOKENma dostęp do projektu (zwykle ma).
apply uruchamia się w niechcianych sytuacjach
Section titled “apply uruchamia się w niechcianych sytuacjach”Sprawdź warunki:
- Domyślny branch wdraża automatycznie.
- Gałęzie z MR: manual.
- Tagi: nigdy.
Sugestie ulepszeń (opcjonalne, ale praktyczne)
Section titled “Sugestie ulepszeń (opcjonalne, ale praktyczne)”-
Zapisywanie planu jako artifact i używanie go w apply
- ogranicza drift pomiędzy planem i apply.
-
Environment + TF_STATE_NAME per environment
- łatwiejsza separacja stanów:
dev/staging/prod.
- łatwiejsza separacja stanów:
-
Cache providerów/pluginów
- skraca czas
initiplan.
- skraca czas
-
Raport z planu jako komentarz do MR
- poprawia review IaC.
Referencja: definicje z pipeline
Section titled “Referencja: definicje z pipeline”.gitlab-ci.yml (fragment)
Section titled “.gitlab-ci.yml (fragment)”🕵 opentofu fmt: format check✅ opentofu validate: walidacja✅ tflint: lint🧪 opentofu plan: plan💥 opentofu apply: wdrożenie kontrolowane regułami
pipelines/opentofu/tofu-init.sh.yml
Section titled “pipelines/opentofu/tofu-init.sh.yml”.tofu-init.sh.yml: init + backend GitLab Terraform State + locking