Dzisiaj jako INNOKREA zapraszamy do kolejnego odcinka serii prezentującej podejście IaC (Infrastructure as a code) za pomocą narzędzia Terraform. Jeśli jesteście zainteresowani, na czym może polegać stosowanie IaC w repozytorium Github lub jakie problemy można napotkać w związku z zarządzaniem stanem Terraform, to zachęcamy do lektury.

 

Terraform kontra GitHub

Podejście IaC jest stosowane w wielu usługach w tym na przykład przy tworzeniu repozytoriów. Jeśli chcemy mieć pewien standard zarządzania repozytorium w firmie, w postaci kodu, który jest łatwo zarządzany i wspólny dla wszystkich produktów, które dostarcza nasza firma, to Terraform przychodzi nam z pomocą. Mamy możliwości ustawienia odpowiednich parametrów dla takich zasobów jak:

  • github_repository - Ten zasób umożliwia zdefiniowanie repozytorium GitHub. Możesz określić atrybuty, takie jak nazwa repozytorium, opis, widoczność i czy jest to repozytorium szablonowe.
  • github_branch_protection - Za pomocą tego zasobu możesz narzucić zasady ochrony gałęzi dla określonego repozytorium.
  • github_team - Ten zasób umożliwia tworzenie zespołów GitHub i konfigurowanie ich właściwości. Możesz określić nazwę zespołu, opis, ustawienia prywatności i członków.
  • github_team_membership - Możesz użyć tego zasobu do zarządzania członkostwem w zespole. Pozwala on na dodawanie lub usuwanie członków z określonego zespołu GitHub.
  • github_issue_label - Ten zasób umożliwia zdefiniowanie etykiet dla problemów GitHub. Możesz określić nazwę etykiety, kolor i opis.

 

Aby utworzyć takie repozytorium z poziomu Terraforma należy najpierw utworzyć token do API Github’a z odpowiednimi uprawnieniami dla naszego konta, a następnie zdefiniować odpowiedniego dostawcę oraz zasób. Jeśli wszystko jest poprawne, to po wykonaniu komendy apply zmiany zostaną zastosowane i zdalne repozytorium zostanie utworzone.

Rysunek 1 - Tworzenie repozytorium Github z poziomu kodu w Terraform.

 

Zarządzanie stanem

W poprzednim artykule wspominaliśmy o komendzie terraform destroy pozwalającej na zniszczenie stworzonych (terraform apply) zdalnie zasobów np. serwerów. Warto także zaznaczyć, że jeśli usuniemy z naszego pliku te kilka linii o zasobie, to Terraform też będzie próbował usunąć dany obiekt poprzez zdalne API, gdy wykonamy polecenie terraform apply. Terraform dąży więc do zachowania spójności stanu lokalnego infrastruktury ze zdalną i komenda apply pomaga to osiągnąć. Poprzez pliki .tfstate terraform przechowuje informacje o stanie danego obiektu, który jest aktualizowany przy zmianach. Jeśli wykonamy komendę terraform destroy, to pliki stanu znikną.

Rysunek 2 -  Zawartość pliku .tfstate.

 

Warto powiedzieć, że stan .tfstate przechowuje więcej informacji niż plik .tf bo przechowuje stan całego obiektu, włącznie z wartościami, których nie zdefiniowaliśmy. Raczej nie powinno edytować się tego pliku. Natomiast, manualne skasowanie pliku .tfstate może nam spowodować, że to co mamy w konsoli przestanie być spójne z tym co faktycznie dzieje się w infrastrukturze np. utworzyć dodatkowe repozytorium lub serwer.

Rysunek 3 - Dodatkowe parametry domyślne, których nie podaliśmy jako użytkownicy.

 

Natomiast jeśli zdalny stan zostanie zmodyfikowany np. poprzez manualną edycję serwera, to można lokalnie zaobserwować zmianę po wykonaniu komendy terraform plan lub terraform apply. Po wykonaniu polecenia apply zdalny stan zostanie napisany stanem lokalnym wynikającym z treści pliku. Przykład zaprezentowano poniżej.

Rysunek 4 - Manualna zmiana typu instancji z poziomu panelu AWS.

Rysunek 5 - Reakcja na manualną zmianę. Terraform zauważył różnicę i proponuje przywrócenie infrastruktury do stanu zgodnego z lokalnym.

  

Argumenty vs atrybuty

Terrafrom wprowadza oznaczenia pomiędzy parametrami dzieląc je na argumenty i atrybuty. Argumenty służą do definiowania wejść dla zasobu. Są one zwykle używane w bloku resource, aby określić wartości wymagane do utworzenia lub zmodyfikowania zasobu.

Atrybuty z kolei służą do pobierania wyników zasobu. Zwykle są one używane poza blokiem resource, aby uzyskać informacje o utworzonym zasobie. Na przykład, po utworzeniu instancji EC2 można chcieć pobrać jej adres IP publiczny, nazwę DNS lub identyfikator instancji.

Rysunek 6 - Przykładowe atrybuty z dokumentacji pewnego pluginu.

 

Istnieją atrybuty na które nie mamy wpływu jak i o których wartości dowiemy się dopiero po zainicjalizowaniu infrastruktury np. przydzielony przez providera adres ip. Aby wyświetlić dany atrybut lub argument korzystamy zbloku output. Dostępne atrybuty możemy wyczytać z dokumentacji lub pliku .tfstate. Składnia output jest następująca:

output <nazwa_własna> {

value = <typ_obiektu>.<nazwa_lokalna>.<nazwa_atrybutu>

}

Rysunek 7 i 8 - Wyświetlanie atrybutów dotyczących utworzonego repozytorium Github oraz EC2 AWS.

 

Czasem pomiędzy zasobami występują zależności jak np. adres ip jednego obiektu musi znaleźć się na inpucie drugiego obiektu. Na poniższym zdjęciu id obiektów ElasticIP oraz EC2 jest przypisywane do siebie za pomocą resource’a aws_eip_association.

Rysunek 9 - Przypisanie odpowiedniego ip do instancji za pomocą nowego zasobu. Czasem przypisanie atrybutów odbywa się poprzez zasoby pośrednie jak tu “association”, a czasem bezpośrednio. Jest to zależne od implementacji danego dostawcy i należy szukać tej informacji w dokumentacji.

 

 

Podsumowanie

W niniejszym artykule przedstawiliśmy podstawy o zarządzaniu stanem w Terraform oraz podstawy konfigurowania repozytorium Github. Profesjonalne używanie tego narzędzie wymaga jednak sporej wprawy i rozumienia wielu aspektów działania infrastruktury. Zachęcamy do lektury innych materiałów na ten temat!