Najczęstsze błędy w Terraformie dotyczą obsługi stanu, blokad, sekretów, modułów, wersji providerów i zatwierdzania planów. Ich skutkiem może być drift, czyli rozbieżność między konfiguracją a rzeczywistą infrastrukturą, a także nieudane wdrożenia lub nieplanowane zmiany. Poniższe zasady pomagają ograniczyć te problemy w rosnącym środowisku IaC.
Spis treści
Nie traktuj pliku stanu jak zwykłego pliku projektu
Stan Terraform jest częścią procesu wdrażania. Błąd pojawia się wtedy, gdy zespół przechowuje go lokalnie, kopiuje między komputerami albo dopuszcza do pracy na kilku niespójnych wersjach. W takiej sytuacji plan może opierać się na nieaktualnych danych i nie odzwierciedlać rzeczywistego środowiska.
Zapobieganie powinno obejmować:
- używanie wspólnego, zdalnego miejsca przechowywania stanu,
- ograniczenie dostępu do stanu do osób i procesów, które go potrzebują,
- zachowanie historii zmian i możliwości odtworzenia wcześniejszej wersji,
- unikanie ręcznej edycji pliku stanu.
Praktyki dotyczące organizacji stanu, współpracy i wdrożeń opisuje Terraform Best Practices 2025.
Nie uruchamiaj wdrożeń bez blokady stanu
Gdy dwie osoby lub procesy wykonują operacje Terraform jednocześnie, mogą odczytać ten sam stan, a następnie zapisać sprzeczne zmiany. To jeden z typowych sposobów powstawania driftu i uszkodzenia procesu wdrażania.
Przed pracą zespołową skonfiguruj mechanizm blokady stanu. W praktyce oznacza to, że jedna operacja uzyskuje możliwość zmiany stanu, a kolejna czeka albo kończy się komunikatem o zajętym stanie. Nie usuwaj blokady ręcznie tylko dlatego, że wdrożenie trwa dłużej. Najpierw sprawdź, czy poprzedni proces nadal działa. Wymuszenie odblokowania bez tej kontroli może pogorszyć sytuację.
Po przerwanym wdrożeniu bezpieczniejszy przebieg to: sprawdzenie aktywnych procesów, potwierdzenie aktualności stanu, ponowne wygenerowanie planu i dopiero potem kontynuowanie pracy. Zagadnienia związane z bezpieczną pracą z providerem i procesem wdrożenia omawia AWS Prescriptive Guidance.
Nie umieszczaj sekretów w kodzie i zmiennych jawnych
Hasła, tokeny i klucze dostępowe zapisane w plikach Terraform, wartościach domyślnych lub historii repozytorium mogą trafić do niepowołanych osób. Sekret może również zostać ujawniony w stanie albo w logach procesu, jeśli konfiguracja i narzędzia nie są odpowiednio zabezpieczone.
Stosuj następujące zasady:
- przechowuj sekrety w przeznaczonym do tego mechanizmie zarządzania sekretami,
- nie commituj ich do repozytorium,
- ograniczaj uprawnienia procesu Terraform do niezbędnego zakresu,
- sprawdzaj kod i plan pod kątem wartości poufnych przed zatwierdzeniem.
Bezpieczeństwo sekretów, uprawnień i konfiguracji Terraform jest omówione w materiale Terraform Security Best Practices.
Nie twórz modułów bez jasno określonych wejść i wyjść
Moduł, który ukrywa zbyt wiele ustawień albo przyjmuje niejasne zmienne, utrudnia przewidywanie zmian. W większym środowisku może to prowadzić do przypadkowych wartości, powielania zasobów i planów, których nie da się łatwo ocenić.
Każdy moduł powinien mieć określony zakres odpowiedzialności. Zdefiniuj jego zmienne wejściowe, wartości wyjściowe i oczekiwane zależności. Nie kopiuj tego samego fragmentu konfiguracji do wielu katalogów, jeśli ma on wspólne zachowanie. Przed zmianą modułu wygeneruj plan dla każdego środowiska, które z niego korzysta.
Kontroluj wersje providerów
Zmiana wersji providera może zmienić sposób interpretacji argumentów, wartości domyślnych lub istniejących zasobów. Jeśli zespół nie kontroluje wersji, ta sama konfiguracja może dać inny plan na różnych komputerach lub w kolejnym procesie CI.
Zapisz wymagane wersje Terraform i providerów w konfiguracji projektu oraz aktualizuj je celowo, a nie przypadkowo. Aktualizację wykonuj etapami: najpierw plan, potem test na bezpiecznym środowisku, a dopiero później wdrożenie. Praktyki zarządzania providerem i jego wersjami opisuje AWS Prescriptive Guidance.
Importuj istniejące zasoby przed ich ponownym opisaniem
Jeśli zasób został utworzony poza Terraformem, dodanie samego bloku zasobu do kodu nie oznacza jeszcze, że Terraform zna jego stan. Przy kolejnym planie narzędzie może próbować utworzyć drugi zasób albo zgłosić różnice między konfiguracją a infrastrukturą.
Bezpieczny proces przejęcia zasobu obejmuje:
- zidentyfikowanie istniejącego zasobu i jego unikalnego identyfikatora,
- zaimportowanie go do stanu Terraform,
- dopasowanie konfiguracji do rzeczywistych ustawień,
- uruchomienie planu i sprawdzenie, czy proponowana zmiana jest zamierzona.
Nie zatwierdzaj planu, który chce zastąpić istniejący zasób, dopóki nie sprawdzisz przyczyny tej propozycji.
Nie zatwierdzaj planu bez przeglądu
Plan Terraform nie jest formalnością. Może zawierać usunięcie zasobu, zmianę uprawnień, modyfikację sieci albo odtworzenie obiektu zamiast aktualizacji. Ryzyko rośnie, gdy plan jest generowany długo przed wdrożeniem lub zatwierdzany bez porównania z zakresem zmiany.
Przed akceptacją sprawdź:
- czy liczba i rodzaj zmian odpowiadają zadaniu,
- czy nie ma nieoczekiwanych operacji usunięcia lub odtworzenia,
- czy zmiany uprawnień i dostępu są zamierzone,
- czy plan został wykonany na aktualnym stanie,
- czy osoba zatwierdzająca zna wpływ zmiany na zależne zasoby.
Jeżeli plan zawiera nieoczekiwane różnice, zatrzymaj wdrożenie. Najpierw porównaj kod, wersje providerów, stan i ręczne zmiany wykonane poza Terraformem. Zjawisko, w którym rzeczywista infrastruktura odchodzi od konfiguracji, jest opisywane jako Terraform drift w materiale Encore.
Co zrobić po wykryciu driftu lub nieudanego wdrożenia
- Nie uruchamiaj kolejnych zmian na podstawie starego planu.
- Zabezpiecz aktualny stan i ustal, czy inne wdrożenie nie korzysta z blokady.
- Sprawdź różnice między kodem, stanem i rzeczywistą infrastrukturą.
- Zweryfikuj zmiany wykonane ręcznie, importy oraz wersje providerów.
- Wygeneruj nowy plan po usunięciu przyczyny rozbieżności.
- Przejrzyj plan z inną osobą przed ponownym wdrożeniem.
Po zmianach ryzykownych zachowaj kopię stanu i przygotuj możliwość cofnięcia zmiany. Terraform powinien być używany jako kontrolowany proces, a nie jako polecenie uruchamiane bez analizy wyniku.
