Terraform, narzędzie do zarządzania infrastrukturą jako kodem, pozwala na efektywne tworzenie, modyfikowanie i usuwanie zasobów w chmurze. Kluczowym elementem tego procesu są trzy podstawowe komendy: plan, apply i destroy. Każda z nich odgrywa istotną rolę w pełnym cyklu życia infrastruktury, od jej zaplanowania, przez zastosowanie konfiguracji, aż po usunięcie niepotrzebnych zasobów.

W momencie, gdy rozpoczynasz nowy projekt bez istniejących zasobów, terraformowy plan może wykazać liczne elementy oznaczone plusem (+), co wskazuje na konieczność utworzenia nowych zasobów. Zanim jednak przejdziesz do ich stworzenia, konieczne jest przejrzenie planu, by upewnić się, że szczegóły zasobów odpowiadają Twoim oczekiwaniom. Plan zawiera również odwołania do atrybutów, takie jak automatycznie generowane nazwy czy identyfikatory, które pojawią się po utworzeniu zasobów.

W przypadku dużych projektów, wynik planu może być bardzo rozbudowany. Istnieje możliwość zapisania tego planu do pliku, co przydaje się w środowiskach zespołowych. Dzięki temu członkowie zespołu mogą wspólnie przeglądać plan w systemie kontroli wersji lub w pipeline'ie CI/CD. Plik zapisany z użyciem parametru -out może zostać później użyty przy wywołaniu komendy terraform apply, aby zastosować wcześniej zaplanowaną konfigurację.

Gdy plan jest gotowy, przechodzimy do fazy stosowania konfiguracji. Proces ten rozpoczyna się od komendy terraform apply. Jeżeli plan nie został zapisany wcześniej, Terraform na nowo oblicza plan i wyświetla podsumowanie oczekiwanych zmian, prosząc użytkownika o potwierdzenie. Dopiero po wpisaniu "yes" proces jest finalizowany. Wtedy Terraform nawiązuje połączenie z dostawcą chmurowym, jak np. Azure, i tworzy zasoby zgodnie z deklaracjami w kodzie. Przykładem może być tworzenie grupy zasobów w chmurze Azure, jak pokazano poniżej:

hcl
resource "azurerm_resource_group" "project_rg" {
name = "ProjectRG" location = "WestUS" }

Po rozpoczęciu komendy apply w konsoli pojawia się komunikat o tworzeniu zasobów, np. azurerm_resource_group.project_rg: Creating..., a po zakończeniu procesu Terraform zaktualizuje lokalny lub zdalny plik stanu, co zapobiegnie ponownemu tworzeniu tych samych zasobów przy kolejnych uruchomieniach planu.

Jeśli jednak tworzenie zasobu nie powiedzie się z powodu problemów z uprawnieniami lub konfiguracją, Terraform zatrzyma proces, wyświetlając komunikat o błędzie. Po naprawieniu problemu w kodzie lub danych uwierzytelniających, można ponownie uruchomić komendę apply, aby dokończyć tworzenie infrastruktury.

Zmiany w już istniejącej infrastrukturze przebiegają w podobny sposób. Komenda plan pokazuje, jakie modyfikacje będą miały miejsce, a komenda apply wprowadza te zmiany w życie. Na przykład, jeśli użytkownik doda zasób sieci wirtualnej (virtual network), komenda plan pokaże nowy zasób do utworzenia z plusem (+), a po jego zatwierdzeniu, sieć zostanie utworzona w środowisku.

Jeśli zasoby przestaną być potrzebne, lub jeśli tworzono tymczasowe środowisko testowe, można je usunąć za pomocą komendy terraform destroy. Terraform przetwarza aktualny plik stanu, wyświetlając plan usunięcia zasobów. W tym przypadku obok każdego zasobu pojawi się minus (-), co oznacza jego usunięcie. Na przykład:

diff
- azurerm_resource_group.project_rg will be destroyed

Po zakończeniu procesu, Terraform wyczyści zasób z chmurowego dostawcy, a wszystkie dane lub obiekty, które były z nim związane, zostaną usunięte. Należy jednak pamiętać, że jeśli zasób zniknie z konfiguracji, ale pozostanie w środowisku dostawcy, Terraform nie usunie go, chyba że został wcześniej zaimportowany lub monitorowany.

Powyższy proces pokazuje, jak za pomocą Terraform można efektywnie zarządzać pełnym cyklem życia zasobów chmurowych, od ich utworzenia, przez modyfikację, aż po ich usunięcie, wszystko w sposób deklaratywny, powtarzalny i zautomatyzowany.

Należy również zwrócić uwagę, że Terraform, dzięki swojej zdolności do deklaratywnego opisywania infrastruktury, pozwala na dużą elastyczność. Użytkownicy mogą w łatwy sposób dostosować konfiguracje do różnych środowisk (np. produkcyjnego, testowego czy deweloperskiego) za pomocą zmiennych. Warto również pamiętać, że Terraform wspiera zaawansowane struktury danych, takie jak listy, mapy czy obiekty, co pozwala na tworzenie bardziej złożonych, dynamicznych konfiguracji.

Jak tworzyć elastyczne i wielokrotnego użytku moduły Terraform?

W dzisiejszych czasach praktycznie każdy projekt infrastrukturalny wymaga używania narzędzi, które umożliwiają automatyzację i standaryzację procesów. Jednym z najpotężniejszych rozwiązań w tej dziedzinie jest Terraform, który pozwala na efektywne zarządzanie zasobami chmurowymi i infrastrukturą jako kodem. Terraform korzysta z tzw. modułów, które umożliwiają tworzenie powtarzalnych, elastycznych i łatwych do modyfikacji elementów infrastruktury. Poniżej omówimy kluczowe aspekty związane z tworzeniem i używaniem modułów w Terraform, z uwzględnieniem zmiennych wejściowych, lokalnych wartości i wyjściowych, które stanowią podstawę do budowy skalowalnych i zorganizowanych środowisk.

Zmienne wejściowe (Inputs)

Jednym z najistotniejszych elementów w pracy z modułami Terraform są zmienne wejściowe. Moduły pozwalają na tworzenie elastycznych bloków, które mogą być dostosowane do różnych potrzeb środowiskowych. Zamiast modyfikować kod samego modułu, użytkownicy mogą podać odpowiednie wartości dla zmiennych, dzięki czemu zachowują oni pełną kontrolę nad konfiguracją zasobów bez konieczności modyfikowania struktury kodu.

Dzięki zmiennym wejściowym zespoły mogą ustalać parametry, takie jak rozmiar instancji, region czy tagi, które są specyficzne dla danego środowiska. Na przykład, gdy chcemy stworzyć wirtualną maszynę w chmurze, możemy użyć zmiennych takich jak instance_size, location czy tags, które będą różne w zależności od środowiska produkcyjnego, testowego czy deweloperskiego. Takie podejście pozwala na uniknięcie duplikowania dużych fragmentów konfiguracji dla różnych projektów i środowisk.

Za pomocą zmiennych wejściowych możliwe jest również wprowadzenie ograniczeń dotyczących typu danych, co zapobiega nieprawidłowemu użyciu zmiennych. Z kolei zdefiniowanie domyślnych wartości zmiennych pozwala na szybkie utworzenie środowiska, które nie wymaga każdorazowej interakcji użytkownika przy każdej instalacji.

Wartości lokalne (Locals)

Kolejnym ważnym elementem w module Terraform są wartości lokalne. Dzięki nim możemy ukryć wewnętrzną logikę i obliczenia w obrębie modułu, aby nie były one widoczne dla końcowego użytkownika. Wartości lokalne pełnią rolę stałych lub obliczanych wyników, które mogą być użyte w różnych miejscach konfiguracji bez ryzyka błędów i duplikowania kodu.

Jeśli projekt wymaga np. unikalnego schematu nazw, połączenia kilku list czy map, bądź obliczenia ostatecznej wartości z kilku parametrów, warto stworzyć odpowiednią definicję w lokalnym bloku. Dzięki temu unikniemy powtarzania tej samej logiki w różnych częściach kodu. Na przykład, tworząc nazwę wirtualnej maszyny, możemy połączyć prefix projektu z nazwą środowiska, co pozwala na elastyczne zarządzanie nazwami zasobów, a także uniknięcie ich powielania.

Wartości lokalne pozwalają także na centralizację logiki, co znacząco ułatwia wprowadzanie zmian, np. w przypadku zmiany schematu nazw. Zmiana definicji lokalnej powoduje automatyczną aktualizację nazw wszystkich zależnych zasobów.

Zmienne wyjściowe (Outputs)

Po zakończeniu konfiguracji zasobów w module, bardzo ważne staje się udostępnienie niezbędnych informacji na zewnątrz, np. identyfikatorów zasobów czy adresów IP. W tym celu stosujemy zmienne wyjściowe, które stanowią punkt odniesienia do danych generowanych przez moduł. Dzięki wyjściom, inne części konfiguracji mogą odnosić się do tych wartości bez potrzeby wnikania w szczegóły implementacji danego zasobu.

Zmienne wyjściowe pełnią bardzo istotną rolę w rozdzieleniu logiki wewnętrznej modułu od jego interfejsu zewnętrznego, co pomaga w tworzeniu czystych i modularnych rozwiązań. Dodatkowo umożliwiają one bezproblemowe rozwijanie modułów, ponieważ nowe wyjścia mogą być dodawane bez wpływu na istniejących konsumentów modułu.

Na przykład, po utworzeniu maszyny wirtualnej w chmurze, możemy ustawić zmienną wyjściową dla identyfikatora maszyny (vm_id), publicznego adresu IP (vm_public_ip) czy tagów przypisanych do zasobów. Tego rodzaju wyjścia pozwalają na łatwe odwoływanie się do istotnych danych przez inne moduły lub konfiguracje nadrzędne.

Tworzenie własnego modułu

Tworzenie własnego modułu jest jednym z najłatwiejszych sposobów, aby zobaczyć, jak te koncepcje działają w praktyce. Przykładem może być stworzenie modułu, który będzie zarządzał grupą zasobów w chmurze Azure. Moduł taki może obejmować utworzenie grupy zasobów oraz sieci wirtualnej. Wszystkie parametry takie jak resource_group_name, location, vnet_name i address_space można zdefiniować w pliku variables.tf, a potem zaimportować do głównej konfiguracji Terraform.

Tego typu moduły stają się podstawą do skalowalnych i łatwych do zarządzania środowisk w chmurze, ponieważ pozwalają na ich łatwą replikację w różnych regionach, środowiskach i projektach.

Wnioski

Tworzenie modułów w Terraformie to nie tylko sposób na uporządkowanie kodu, ale także na zwiększenie efektywności w zarządzaniu zasobami w chmurze. Kluczowe elementy takie jak zmienne wejściowe, wartości lokalne i wyjściowe są fundamentami, które pozwalają na tworzenie elastycznych, wielokrotnego użytku komponentów infrastrukturalnych. Każdy moduł staje się łatwiejszy w użyciu, łatwiejszy do zarządzania i łatwiejszy do rozwijania w miarę rosnących potrzeb projektu. Kluczem do sukcesu jest zrozumienie zasad pracy z tymi elementami i ich odpowiednie wykorzystanie w różnych scenariuszach.

Jak efektywnie używać Provisioners w Terraformie do zarządzania konfiguracją

Provisioners w Terraformie to narzędzie umożliwiające wykonywanie skryptów lub poleceń na nowo utworzonych zasobach. Ich podstawową funkcjonalnością jest uzupełnienie procesu tworzenia infrastruktury o konfigurację systemową lub aplikacyjną, której Terraform nie zarządza w pełni. Chociaż Terraform świetnie radzi sobie z provisioningiem zasobów w chmurze, takich jak sieci, dyski czy maszyny wirtualne, nie zajmuje się głębszą konfiguracją na poziomie systemu operacyjnego czy aplikacji. W takich przypadkach provisioners stanowią przydatne rozwiązanie, choć ich stosowanie wymaga ostrożności.

Provisioners mogą być użyteczne w scenariuszach, w których potrzebujemy dokonać prostych zmian konfiguracji po utworzeniu zasobu, takich jak instalacja oprogramowania, przesyłanie certyfikatów SSL czy inne jednorazowe działania. Jednak w przypadku bardziej rozbudowanej konfiguracji lub długoterminowego zarządzania, warto sięgnąć po bardziej wyspecjalizowane narzędzia, takie jak Ansible, Chef czy Puppet.

Jednym z podstawowych provisionerów w Terraformie jest local-exec, który pozwala na uruchomienie lokalnych skryptów lub poleceń po utworzeniu zasobu. Na przykład, jeśli masz skonfigurowane konto magazynowe w chmurze i chcesz wysłać powiadomienie do Slacka za każdym razem, gdy konto zostanie stworzone, wystarczy dodać provisioner local-exec, który wykona odpowiednią komendę wysyłającą wiadomość. Jednak w przypadku zmiany nazwy zasobu lub niepowodzenia w tworzeniu, użytkownik może otrzymać częściowe wiadomości. Z tego względu local-exec należy traktować jako ostateczność, gdy inne metody nie są w stanie sprostać wymaganiom. Warto także pamiętać, że ta metoda nie jest zalecana do dużych lub regularnych zadań konfiguracyjnych, które lepiej obsługiwać za pomocą dedykowanych rozwiązań chmurowych lub pipeline’ów CI/CD.

Kolejnym ważnym provisionerem jest remote-exec, który umożliwia uruchamianie poleceń na nowo utworzonym zasobie, np. maszynie wirtualnej, przez SSH. Przykład zastosowania tego provisionera to sytuacja, w której uruchamiasz maszynę wirtualną w chmurze (np. w Azure), a następnie potrzebujesz zainstalować i uruchomić Nginx. Po uruchomieniu zasobu Terraform automatycznie łączy się z maszyną przez SSH, wykonuje aktualizację systemu, instaluje Nginx i uruchamia serwis. Tego typu podejście jest wygodne przy prostych inicjalizacjach, jednak nie jest rekomendowane do większych czy regularnych zadań konfiguracyjnych, ponieważ może prowadzić do braku odporności na błędy w przypadku awarii podczas instalacji.

Warto zauważyć, że provisioner remote-exec daje pewną elastyczność, pozwalając na dynamiczne odczytywanie atrybutów zasobów, takich jak adres IP maszyny czy zmienne środowiskowe, które stają się dostępne dopiero po utworzeniu zasobu. Tego rodzaju podejście jest przydatne, gdy musimy dostosować konfigurację do specyficznych parametrów utworzonych zasobów. Niemniej jednak, kod staje się wtedy bardziej efemeryczny, zrealizowany w poleceniach powłoki lub zewnętrznych plikach, co może utrudnić utrzymanie przejrzystości w projekcie.

Jednym z bardziej zaawansowanych rozwiązań jest użycie provisionera null_resource, który pozwala na wykonywanie akcji na podstawie zmian w zmiennych lub innych referencjach, które nie są bezpośrednio powiązane z żadnym zasobem. Na przykład, możemy zdefiniować null_resource, który uruchomi skrypt lokalny za każdym razem, gdy wersja aplikacji zostanie zaktualizowana. W przypadku zmiany wartości zmiennej, null_resource zostaje oznaczone jako "zniszczone" i Terraform ponownie uruchamia przypisany do niego provisioner. Tego typu podejście może być przydatne w przypadku prostych operacji, takich jak wysyłanie powiadomień po zbudowaniu obrazu Docker, jednak należy unikać nadmiaru null_resources, ponieważ może to prowadzić do nieporządku w kodzie i utrudniać jego zarządzanie.

Zalecane jest, aby provisionery były wykorzystywane tylko w przypadku drobnych zadań konfiguracyjnych, które nie wymagają ciągłych aktualizacji. W przypadku bardziej zaawansowanych scenariuszy konfiguracyjnych, takich jak instalacja i konfiguracja oprogramowania na nowych maszynach, warto rozważyć integrację z dedykowanymi narzędziami do zarządzania konfiguracją, takimi jak Ansible, Chef czy Puppet, które oferują większą elastyczność oraz odporność na błędy. W tym celu Terraform powinien być używany do samego tworzenia zasobów, a późniejsza konfiguracja powinna być zarządzana przez systemy konfiguracji lub pipeline'y CI/CD, które zapewniają większą kontrolę nad procesem oraz minimalizują ryzyko błędów.

Jedną z ważniejszych kwestii, którą należy mieć na uwadze przy pracy z provisionerami, jest konieczność zachowania idempotencji operacji. Oznacza to, że skrypty i polecenia wykonywane przez provisionery muszą być zaprojektowane w taki sposób, aby mogły być uruchamiane wielokrotnie bez ryzyka wprowadzenia niepożądanych zmian. Ważne jest również, aby projektować środowisko w sposób, który minimalizuje konieczność ponownego uruchamiania provisionerów, ponieważ proces tworzenia i niszczenia zasobów może prowadzić do dużych opóźnień, szczególnie w przypadku skalowania infrastruktury.

W końcu, warto pamiętać, że provisioners to narzędzie przeznaczone głównie do jednorazowych działań na zasobach, a nie do ciągłego zarządzania infrastrukturą. Jeśli infrastruktura wymaga regularnych aktualizacji, najlepszym rozwiązaniem będzie integracja Terraform z narzędziami do zarządzania konfiguracją, które zapewnią lepszą kontrolę nad procesem i zmniejszą ryzyko błędów wynikających z wykonywania operacji na wciąż rozwijającej się infrastrukturze.

Jak efektywnie zarządzać CIDR w Terraform i unikać najczęstszych błędów

W pracy z Terraformem, jednym z najistotniejszych aspektów jest poprawne zarządzanie przestrzenią sieciową, w tym również CIDR-ami. W kontekście Virtual Private Cloud (VPC), zarządzanie CIDR-ami staje się kluczowe, ponieważ błędne przypisanie zakresów IP może prowadzić do poważnych problemów, takich jak nakładające się sieci, co w konsekwencji może spowodować błędy w konfiguracji i przerwy w dostępie do usług. Dlatego tak istotne jest, aby poprawnie przeprowadzać walidację CIDR-ów i unikać najczęstszych pułapek.

Jednym z narzędzi, które może pomóc w automatycznym podziale przestrzeni VPC na odpowiednie podsieci, jest funkcja cidrsubnet(). Dzięki niej można precyzyjnie podzielić adresację na mniejsze fragmenty, które następnie zostaną przypisane do konkretnych podsieci w ramach VPC. Funkcja ta jest szczególnie przydatna, gdy zarządza się dużymi infrastrukturami i trzeba efektywnie gospodarować dostępną przestrzenią adresową.

Jednak aby upewnić się, że przypisane CIDR-y się nie nakładają, należy wykorzystać narzędzia walidacyjne, takie jak OPA (Open Policy Agent). Narzędzie to pozwala na kontrolowanie, czy przestrzeń adresowa jest prawidłowo rozdzielona, eliminując potencjalne błędy związane z konfiguracją, które mogą wyniknąć z nałożenia się zakresów. Regularne uruchamianie poleceń terraform validate oraz terraform plan pomaga wychwycić błędy już na etapie planowania, co znacząco zmniejsza ryzyko nieoczekiwanych problemów w produkcji.

Ponadto, warto pamiętać o dwóch innych pomocnych poleceniach Terraform: terraform fmt oraz terraform taint. Pierwsze z nich odpowiada za formatowanie kodu zgodnie z najlepszymi praktykami, co nie tylko poprawia jego czytelność, ale także pomaga wychwycić drobne błędy syntaktyczne. Z kolei terraform taint pozwala na wymuszenie odtworzenia zasobów, co bywa przydatne w przypadku, gdy zasoby zostały zmienione lub usunięte, a nie zostały jeszcze zaktualizowane w stanie Terraform.

Warto jednak pamiętać, że odtworzenie zasobów może wiązać się z przestojami w działaniu usług produkcyjnych, co w przypadku niektórych aplikacji i systemów może prowadzić do poważnych konsekwencji. Dlatego przed wykonaniem tych operacji należy dokładnie zaplanować ich czas oraz wpływ na całą infrastrukturę.

Podczas pracy z Terraformem warto również zwrócić szczególną uwagę na najczęstsze problemy, które mogą wystąpić w kontekście CIDR-ów i podziału sieci. Należy unikać nakładających się zakresów IP, ponieważ prowadzi to do błędów podczas próby przypisania podsieci do wirtualnych sieci. Należy także pamiętać o poprawnym ustawieniu parametrów dla każdej podsieci, tak aby przestrzeń adresowa była wykorzystana w sposób optymalny, a nie marnotrawiona.

Wspomniane problemy, związane z nakładającymi się CIDR-ami czy błędnymi odniesieniami do zasobów, to tylko niektóre z wyzwań, które mogą wystąpić podczas zarządzania infrastrukturą w Terraformie. Dlatego tak ważne jest, aby zarówno na etapie pisania kodu, jak i później, podczas wdrażania zmian, dbać o precyzyjne sprawdzanie poprawności konfiguracji. Regularne testowanie, walidowanie i stosowanie narzędzi do automatycznego formatowania oraz kontroli zgodności kodu pozwala na minimalizowanie ryzyka wystąpienia poważnych błędów, które mogą prowadzić do problemów z działaniem infrastruktury.

Dodatkowo, warto zaznaczyć, że zarządzanie CIDR-ami jest tylko jednym z wielu aspektów pracy z Terraformem, który obejmuje także konfigurację trasowania, load balancerów, automatyczne skalowanie zasobów czy zarządzanie rekordami DNS. Skupiając się na sieci i CIDR-ach, warto pamiętać, że cała infrastruktura jest ze sobą ściśle powiązana. Zmiany w jednym obszarze mogą wpływać na inne, dlatego każda zmiana powinna być dobrze przemyślana i testowana, aby uniknąć zakłóceń w działaniu całej infrastruktury.

Warto również mieć na uwadze, że niektóre problemy w infrastrukturze mogą pojawić się dopiero po dłuższym czasie eksploatacji, co jest związane z tzw. "drift" w stanie zasobów. Oznacza to, że zasoby w chmurze mogą zostać zmienione poza Terraformem, przez co stan w narzędziu staje się nieaktualny. Aby temu zapobiec, należy regularnie przeprowadzać procesy synchronizacji oraz monitorować stan zasobów w chmurze.

Jak wygląda typowy proces konfiguracji i używania Terraform na platformie Azure?

Aby skutecznie zarządzać infrastrukturą na platformie Azure, wielu użytkowników Terraform przyjmuje ustandaryzowaną strukturę folderów, co pozwala na lepszą organizację kodu. Typowa struktura projektu obejmuje plik main.tf, który zawiera definicje dostawcy (provider) i głównych zasobów, plik variables.tf do określania zmiennych wejściowych oraz osobny plik terraform.tfvars, który przechowuje wrażliwe dane, takie jak dane logowania do konta Azure. Takie podejście zapewnia lepszą organizację kodu i ułatwia jego późniejsze zarządzanie.

W pliku terraform.tfvars przechowywane są zmienne, które są wykorzystywane w konfiguracji. Przykładem mogą być następujące zmienne:

hcl
variable "azure_subscription_id" {} variable "azure_client_id" {} variable "azure_client_secret" {} variable "azure_tenant_id" {}

Kiedy uruchomimy polecenie terraform init, Terraform wykryje odniesienia do tych zmiennych i poprosi użytkownika o ich podanie, chyba że użyjemy podejścia opartego na pliku .tfvars lub zmiennych środowiskowych. Jeśli w systemie ustawione są odpowiednie zmienne środowiskowe, takie jak TF_VAR_azure_subscription_id lub TF_VAR_azure_client_secret, Terraform automatycznie przypisze ich wartości do odpowiednich zmiennych w trakcie działania.

Po zakończeniu inicjalizacji, możemy uruchomić polecenie terraform plan, które zwizualizuje zmiany, jakie zostaną wprowadzone w środowisku Azure. Na przykład, jeśli w konfiguracji mamy zasób azurerm_resource_group, plan wyświetli, że ten zasób zostanie utworzony. Kolejne polecenie terraform apply wywołuje odpowiednie API platformy Azure, aby fizycznie utworzyć ten zasób. Cały proces sprawdza poprawność poświadczeń, danych subskrypcji oraz połączeń sieciowych. Jeśli użytkownik napotka błąd uwierzytelniania, zwykle wystarczy upewnić się, że wartości client_id, client_secret oraz tenant_id odpowiadają tym, które zostały przypisane do wcześniej utworzonego aplikacji serwisowej (service principal) za pomocą polecenia az ad sp create-for-rbac. W niektórych przypadkach użytkownicy mogą również musieć dostosować przypisanie ról w Azure Active Directory, jeśli minimalne uprawnienia powodują niepowodzenie polecenia Terraform.

Wspólnym początkiem pracy z Terraform jest stworzenie dedykowanego folderu, w którym przechowywane będą wszystkie pliki *.tf. Przykładowo, możemy utworzyć folder o nazwie terraform-demo, w którym będą znajdować się co najmniej trzy pliki: main.tf, variables.tf oraz terraform.tfvars. Przykładowa zawartość pliku main.tf, który definiuje dostawcę Azure oraz jeden zasób, może wyglądać tak:

hcl
terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "=3.0.0" } } } provider "azurerm" { features {} subscription_id = var.azure_subscription_id client_id = var.azure_client_id client_secret = var.azure_client_secret tenant_id = var.azure_tenant_id } resource "azurerm_resource_group" "demo_rg" { name = "demo-resource-group" location = "EastUS" }

Natomiast w pliku variables.tf mogą zostać zadeklarowane zmienne:

hcl
variable "azure_subscription_id" {}
variable "azure_client_id" {} variable "azure_client_secret" {} variable "azure_tenant_id" {}

W pliku terraform.tfvars przechowywane będą faktyczne wartości zmiennych, które nie powinny zostać uwzględnione w systemie kontroli wersji:

hcl
azure_subscription_id = "11111111-2222-3333-4444-555555555555" azure_client_id = "abcdef12-3456-7890-abcd-ef1234567890" azure_client_secret = "replace_me_with_secure_value" azure_tenant_id = "12345678-abcd-1234-abcd-123456abcdef"

Dzięki tej strukturze, możemy uruchamiać różne polecenia Terraform, aby zarządzać zasobami na platformie Azure.

Pierwszym krokiem po przygotowaniu struktury jest uruchomienie polecenia terraform init w folderze terraform-demo, co skonfiguruje folder roboczy, pobierze odpowiednie wtyczki dostawcy oraz zweryfikuje obecność wymaganych modułów.

bash
cd terraform-demo
terraform init

Polecenie to sprawdza plik main.tf i, zgodnie z deklaracją wtyczki, pobiera ją z rejestru Terraform. Po zakończeniu procesu inicjalizacji, Terraform informuje użytkownika o statusie instalacji wtyczek oraz o konfiguracji backendu, jeśli został on zdefiniowany.

Po zakończeniu inicjalizacji, następnym krokiem jest użycie polecenia terraform validate. Polecenie to sprawdza składnię plików *.tf, upewniając się, że wszystkie odniesienia do zasobów, zmiennych i dostawców są poprawne. Dzięki temu możemy szybko wychwycić błędy, takie jak pomyłki w nazwach zasobów lub nieprawidłowe odwołania do zmiennych.

bash
terraform validate

Jeśli konfiguracja jest poprawna, Terraform zwróci komunikat o powodzeniu. W przeciwnym razie, otrzymamy informację o błędach, które należy poprawić.

Następnym poleceniem, które możemy uruchomić, jest terraform fmt, które automatycznie sformatuje pliki Terraform, dopasowując je do standardowego stylu kodowania. Dzięki temu, kod stanie się bardziej czytelny, a ewentualne różnice w stylu pisania kodu, które mogą pojawić się w zespole, zostaną zredukowane do minimum.

bash
terraform fmt

Dzięki temu poleceniu, kod w plikach zostanie automatycznie poprawiony pod względem wcięć, rozmieszczenia nawiasów itp., co ułatwia dalszą pracę z nim, a także sprawia, że jest on bardziej czytelny dla innych członków zespołu.

Po walidacji i formatowaniu kodu, można przejść do polecenia terraform plan. Polecenie to generuje plan działań, w którym przedstawione zostaną zmiany, jakie zostaną wprowadzone w infrastrukturze. Dzięki temu możemy zweryfikować, jakie zasoby zostaną utworzone, zmodyfikowane lub usunięte.

bash
terraform plan

Plan powinien szczegółowo wskazać, co dokładnie się zmieni, a także umożliwić użytkownikowi sprawdzenie, czy planowane zmiany są zgodne z oczekiwaniami. Na przykład, jeżeli w planie widzimy, że zasób, którego nie zamierzaliśmy zmieniać, zostanie usunięty, może to wskazywać na błędne przypisanie zmiennych lub zasobów.

Znajomość tych podstawowych poleceń i procedur pozwala na skuteczne zarządzanie infrastrukturą na platformie Azure za pomocą Terraform. Oczywiście, dla bardziej złożonych projektów, korzystanie z modułów, struktur folderów i zaawansowanych funkcji Terraform staje się konieczne, ale podstawy, takie jak zarządzanie zmiennymi, walidacja konfiguracji czy generowanie planu, są kluczowe, by rozpocząć pracę z tym narzędziem.