Wprowadzenie
W świecie Infrastructure as Code często wykorzystuje się pętle w celu stworzenia wielu zasobów bazujących na jednym wzorze oraz wartościach podanych jako zmienne. Takie rozwiązanie ułatwia tworzenie wielu instancji zasobu i skraca kod w porównaniu do stworzenia pięciu zasobów tego samego typu, zmieniając tylko niektóre właściwości. Z drugiej strony, utrzymanie i edytowanie takich plików jest bardziej skomplikowane, co może sprawić trudności mniej doświadczonym użytkownikom IaC.
Jednakże czasami konieczne jest stworzenie skomplikowanej konfiguracji zasobu, która składa się ze zbioru obiektów konfiguracyjnych, takich jak security rule w przypadku zasobu network security group w Azure. Chociaż istnieje możliwość stworzenia oddzielnego obiektu w deklaracji zasobów, czasem jest to niemożliwe. W takim przypadku pomocne mogą okazać się dynamic blocks w Terraform.
Rys.1 Plik konfiguracyjny opisujący wdrożenie NSG z dwoma security rule’ami
Dynamic Blocks
Dynamic Blocks w swoim działaniu przypominają pętle for w Terraformie. Jednakże, w odróżnieniu od pętli for, możemy ich użyć do implementacji zagnieżdżonych obiektów konfiguracji. Przyjrzyjmy się przykładowemu wykorzystaniu Dynamic Blocks w deklaracji security rule.
W przypadku takiego bloku możemy zauważyć następujące różnice względem klasycznej konfiguracji. Po pierwsze, cały blok kodu rozpoczyna słowo kluczowe „dynamic” w deklaracji dynamic blocks. Następnie musimy podać nazwę obiektu konfiguracyjnego, który chcemy zadeklarować – w naszym przypadku jest to „security_rule”. Po podaniu tych startowych wartości możemy otworzyć blok kodu, a w nim powinny znaleźć się następujące elementy:
For_each – jest odwołaniem do wartości złożonej, na podstawie, której nasza pętla zostanie wykonana. W naszym przypadku jest to odwołanie do zmiennej „securityRules”, która wygląda następująco:
Iterator – jest nieobowiązkowym atrybutem, który pozwala na stworzenie nazewnictwa dla tymczasowej zmiennej tworzonej podczas wykonywania pętli. Taka zmienna jest odpowiednikiem obecnie analizowanego obiektu z naszej listy. Jeśli nie podamy wartości dla Iterator’a, to przyjmie on wartość label’a w bloku „dynamic”, czyli w naszym przypadku „security_rule”. Nasza deklaracja bez pola „Iterator”, mogłaby wyglądać następująco:
Content to ostatnia część naszego bloku, w której znajduje się lista wszystkich atrybutów, którym chcemy przypisać wartości. W porównaniu z klasycznym podejściem atrybuty te są odwzorowane 1:1, jakbyśmy omijali pętlę.
Tak wykonane pliki, możemy spróbować, wdrożyć w naszym środowisku za pomocą komendy terraform apply, oraz podziwiać efekty.
Podsumowanie
Podsumowując, dynamic blocks mogą być bardzo przydatną funkcjonalnością w przypadku, gdy naszą konfigurację nie możemy traktować jako oddzielne obiekty, lecz muszą być przypisane do obiektu nadrzędnego. Niestety, tak samo jak w przypadku pętli, nasze pliki konfiguracyjne stają się wtedy bardziej skomplikowane i trudniejsze do utrzymania przez osoby z mniejszą wiedzą na temat IaC i Terraforma. Jednakże, w przypadku, gdy w projekcie mamy osoby o wysokim poziomie wiedzy z zakresu IaC i Terraforma, zastosowanie dynamic blocks może pozwolić na znaczące skrócenie kodu i zminimalizowanie czasu traconego na tworzenie powtarzalnych zasobów.