Only this pageAll pages
Powered by GitBook
1 of 15

Polski (Polish)

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Terragrunt

Struktura kodu

Pytania dotyczące struktury kodu są zdecydowanie najczęściej zadawanymi w społeczności Terraform. W pewnym momencie każdy zaczyna się zastanawiać co dla projektu będzie najlepsze.

Jak powinienem uporządkować moje konfiguracje Terraform?

To jedno z pytań, na które jest wiele odpowiedzi, lecz bardzo trudno jest udzielić uniwersalnych porad, więc postarajmy się zacząć od zrozumienia z czym mamy do czynienia.

  • Jaka jest złożoność Twojego projektu?

    • Liczba powiązanych zasobów

    • Liczba użytych dostawców Terraform (uwaga — patrz poniżej na temat „dostawców logicznych” (logical providers))

  • Jak często zmienia się Twoja infrastruktura?

    • Zaczynając od raz w miesiącu/tygodniu/codziennie

    • Skończywszy na ciągłym (za każdym razem, gdy pojawia się nowa zmiana (commit))

  • Kto lub co zmienia kod? Czy pozwalasz serwerowi CI aktualizować repozytorium po zbudowaniu nowego artefaktu?

    • Tylko programiści mogą wysyłać kod do repozytorium infrastruktury

    • Każdy może proponować zmiany, otwierając pull-requesty (w tym automatyczne zadania uruchomione na serwerze CI)

  • Z jakiej platformy lub usługi wdrożeniowej korzystasz?

    • AWS CodeDeploy, Kubernetes czy OpenShift wymagają nieco innych podejść

  • Jak grupowane są środowiska?

    • Według środowiska, regionu, projektu

Dostawcy logiczni (logical providers) działają w całości w ramach logiki Terraform i bardzo często nie wchodzą w interakcję z żadnymi innymi usługami, więc możemy myśleć o ich złożoności jako O(1). Najpopularniejszymi dostawcami logicznymi są , , , , .

Rozpoczęcie pracy z odpowiednim podejściem do struktury projektu w Terraform

Umieszczenie całego kodu w pliku main.tf jest dobrym pomysłem, jeśli dopiero zaczynasz swoją przygodę z Terraform lub piszesz testowy kod, aby coś zweryfikować. We wszystkich innych przypadkach lepiej będzie mieć kilka plików podzielonych logicznie w następujący sposób:

  • main.tf — wywoływanie modułów, zmienny lokalnych i źródeł danych w celu utworzenia wszystkich zasobów

  • variables.tf — zawiera deklaracje zmiennych używanych w main.tf

  • outputs.tf — zawiera dane wyjściowe z zasobów utworzonych w

Plik terraform.tfvars nie powinien być używany poza .

Jak myśleć o strukturze konfiguracji Terraform?

Upewnij się, że rozumiesz kluczowe pojęcia — , i , gdyż są one używane w poniższych przykładach.

Popularne wskazówki dotyczące strukturyzowania kodu

  • Łatwiej i szybciej pracuje się z mniejszą liczbą zasobów

    • komendy terraform plan i terraform apply wykonują wywołania API, aby zweryfikować status zasobów

    • Jeśli masz całą infrastrukturę w jednej kompozycji, może to zająć trochę czasu

W tej książce przykładowe projekty są pogrupowane według złożoności — od małych do bardzo dużych infrastruktur. Ten podział nie jest ścisły, więc sprawdź, jak robią to inni.

Orkiestracja modułów i kompozycji infrastruktury

Posiadanie małej infrastruktury oznacza, że istnieje niewielka liczba zależności i niewiele zasobów. Wraz z rozwojem projektu pojawia się potrzeba łączenia wykonywania konfiguracji Terraform. Łączenia różnych modułów infrastruktury i przekazywanie wartości w ramach kompozycji staje się oczywistym następstwem.

Istnieje co najmniej 5 odrębnych grup rozwiązań do orkiestracji, z których korzystają programiści_stki:

  1. Czysty Terraform. Bardzo proste rozwiązanie. Programiści_stki muszą znać tylko Terraform, aby wykonać zadanie.

  2. Terragrunt. Narzędzie, którego można użyć do orkiestracji całej infrastruktury, a także obsługi zależności. Terragrunt działa natywnie z modułami infrastruktury i kompozycjami, dzięki czemu ogranicza powielanie kodu.

  3. Skrypty wewnętrzne. Często używane jako punkt startowy do używania orkiestracji oraz przed odkryciem Terragrunt.

Mając to wszystko na uwadze — ta książka zawiera przegląd pierwszych dwóch z struktur projektowych — tylko Terraform i Terragrunt.

Zobacz przykłady struktur kodu dla lub w następnym rozdziale.

main.tf
  • versions.tf — zawiera wymagania dotyczące wersji dla Terraform i dostawców

  • Promień rażenia jest mniejszy przy mniejszej ilości zasobów

    • Odizolowanie od siebie niepowiązanych zasobów poprzez umieszczenie ich w oddzielnych kompozycjach zmniejsza ryzyko, jeśli coś pójdzie nie tak

  • Rozpocznij swój projekt od użycia stanu zdalnego (remote state), ponieważ:

    • Twój laptop nie jest odpowiednim miejscem na źródło prawdy (source of truth) o Twojej infrastrukturze

    • Zarządzanie plikiem tfstate w repozytorium git to koszmar

    • Później, gdy warstwy infrastruktury zaczną rosnąć w wielu kierunkach (liczba zależności lub zasobów) łatwiej będzie mieć wszystko pod kontrolą

  • Ćwicz pisanie spójnej struktury i praktykuj zachowywanie konwencji nazewnictwa:

    • Podobnie jak przy kodzie proceduralnym, kod Terraform powinien być napisany tak, aby w pierwszej kolejności mogli go przeczytać ludzie. Zachowanie porządku pomoże, kiedy trzeba będzie wrócić do zmian sprzed pół roku.

    • Przenoszenie zasobów w pliku stanu Terraform jest możliwe, ale może to być trudniejsze, jeśli masz niespójną strukturę i nazewnictwo

  • Zachowaj moduły zasobów tak proste, jak to możliwe

  • Nie "hardkoduj" wartości, które mogą być przekazywane jako zmienne lub uzyskane przy użyciu źródeł danych

  • Użyj źródeł danych i terraform_remote_state jako łącznika między modułami infrastruktury w kompozycji

  • Ansible lub inne narzędzie ogólnego przeznaczenia do automatyzacji. Zwykle wybierane rozwiązanie, gdy Terraform jest używany po implementacji Ansible lub gdy aktywnie używany jest interfejs użytkownika Ansible.
  • Crossplane i inne rozwiązania inspirowane Kubernetes. Czasami sensowne jest wykorzystanie ekosystemu Kubernetes i zastosowanie pętli uzgadniania (reconciliation loop), aby osiągnąć pożądany stan konfiguracji Terraform. Obejrzyj film Crossplane vs Terraform, aby uzyskać więcej informacji.

  • random
    local
    terraform
    null
    time
    kompozycją
    moduł zasobu
    moduł infrastruktury
    kompozycja
    Terraform
    Terragrunt

    Warsztaty

    Istnieją też warsztaty dla osób, które chcą przećwiczyć niektóre z zagadnień opisanych w tej książce.

    Znajdziesz je tutaj: https://github.com/antonbabenko/terraform-best-practices-workshop

    Terraform

    Infrastruktura średniej wielkości Terraform

    Źródło: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/medium-terraform

    Ten przykład zawiera kod dla strukturyzacji konfiguracji Terraform dla średniego rozmiaru infrastruktury, która zawiera:

    • 2 konta AWS

    • 2 oddzielne środowiska (prod i stage, które nic ze sobą nie dzielą). Każde środowisko funkcjonuje na osobnym koncie AWS

    • Każde środowisko korzysta z innej wersji gotowego modułu infrastruktury (alb) pochodzącego z

    • Każde środowisko używa tej samej wersji modułów/sieci (modules/network) modułu wewnętrznego, ponieważ pochodzi z katalogu lokalnego.

    • Idealny dla projektów, w których infrastruktura jest logicznie odseparowana (osobne konta AWS)

    • Dobre, gdy nie ma potrzeby modyfikowania zasobów współdzielonych między kontami AWS (jedno środowisko = jedno konto AWS = jeden plik stanu)

    W miarę rozwoju projektu coraz trudniej będzie zapewnić wzajemną aktualność tych środowisk. Rozważ użycie modułów infrastruktury (gotowych lub wewnętrznych) do powtarzalnych zadań.

    Cześć!

    Ten dokument jest próbą opisania najlepszych praktyk dotyczących korzystania z Terraform i przedstawia zalecenia związane z najczęstszymi problemami, z jakimi spotykają się użytkownicy_czki Terraform.

    to dość nowy projekt (jak większość narzędzi DevOps), który zaistniał w 2014 roku.

    Terraform jest potężnym (jeśli nie najpotężniejszym) i jednym z najczęściej używanych narzędzi, który umożliwia zarządzanie infrastrukturą jako kodem. Pozwala programistom_ką rozwiązywać wiele różnych problemów infrastrukturalnych tak, aby dało się to dalej łatwo wspierać, integrować i rozwijać.

    Niektóre informacje opisane w tej książce mogą wydawać się nieoptymalnymi praktykami. Jestem tego świadom. Czasem zachodzi potrzeba pomocy czytelnikom_czkom w oddzieleniu tego, co jest powszechnie znanymi najlepszymi praktykami, a co jest po prostu kolejnym subiektywnym sposobem robienia rzeczy. Używam wtedy wskazówek, aby zapewnić kontekst oraz ikony, które określają poziom trudności w każdej podsekcji dotyczącej najlepszych praktyk.

    Historia tej książki rozpoczęła się w słonecznym Madrycie w 2018 roku i jest dostępna za darmo pod tym linkiem -

    Kilka lat później został on zaktualizowany o najnowsze zalecane praktyki dostępne w Terraform 1.0. Ostatecznie — ta książka powinna zawierać większość praktyk i zaleceń dla użytkowników Terraform, które można uznać za bezdyskusyjnie najlepsze.

    Dobre, gdy nie ma potrzeby organizowania zmian między środowiskami
  • Dobre, gdy zasoby infrastruktury są celowo różne w zależności od środowiska i nie można ich uogólniać (np. niektóre zasoby są nieobecne w jednym środowisku lub w niektórych regionach)

  • Terraform Registry
    Sponsorowanie

    Please contact me if you want to become a sponsor.

    — Terraform Compliance Simplified. Make your Terraform modules compliance-ready.

    —

    Tłumaczenia

    Skontaktuj się ze mną, jeśli chcesz pomóc przetłumaczyć tę książkę na inne języki.

    Wsparcie i współpraca

    Zawsze chętnie usłyszę wasze opinie i zaktualizuje tę książkę. Społeczność ciągle dojrzewa, a nowe pomysły są weryfikowane i wdrażane.

    Jeśli jesteś zainteresowany konkretnymi tematami, otwórz nowy wątek (issue) lub daj kciuk w górę przy istniejącym, który chcesz poruszyć najbardziej. Jeśli chcesz wnieść swój wkład do książki, wprowadź zmianę i utwórz pull request (nie martw się czy to co napisałeś_aś jest idealne od samego początku!)\

    Autorzy_ki

    Ta książka jest pod opieką Anton Babenko oraz wielu innych współautorów_ek i __ tłumaczy___ek.

    Licencja

    Ta praca jest objęta licencją Apache 2. Zobacz LICENSE, aby uzyskać szczegółowe informacje.

    Autorzy_rki __ i __ współtwórcy_czynie treści nie mogą zagwarantować aktualności oraz poprawności informacji tutaj znalezionych. Upewnij się, że rozumiesz, iż informacje podane tutaj są dostarczane dobrowolnie i że między Tobą a jakimikolwiek osobami związanymi z tą treścią lub projektem nie powstaje żadna umowa ani kontrakt. Autorzy_rki __ i __ współtwórcy_czynie nie przyjmują i niniejszym zrzekają się jakiejkolwiek odpowiedzialności wobec jakiejkolwiek strony za jakiekolwiek straty, szkody, lub zakłócenia spowodowane błędami, lub pominięciami w informacjach zawartych w tych treściach, powiązanych z nimi lub z nimi połączonych, niezależnie od tego, czy takie błędy lub pominięcia wynikają z zaniedbania, wypadku lub jakiejkolwiek innej przyczyny.

    Prawa autorskie © 2018-2023 Anton Babenko.

    Terraform
    https://www.terraform-best-practices.com/
    العربية (Arabic)
    Bosanski (Bosnian)
    Português (Brazilian Portuguese)
    English
    Français (French)
    ქართული (Georgian)
    Deutsch (German)
    ελληνικά (Greek)
    עברית (Hebrew)
    हिंदी (Hindi)
    Bahasa Indonesia (Indonesian)
    Italiano (Italian)
    日本語 (Japanese)
    ಕನ್ನಡ (Kannada)
    한국어 (Korean)
    Română (Romanian)
    简体中文 (Simplified Chinese)
    Español (Spanish)
    Türkçe (Turkish)
    Українська (Ukrainian)
    اردو (Urdu)

    Przykłady kodu

    Struktura kodu Terraform

    Poniższe przykłady dotyczą AWS, ale większość zasad pokazanych w przykładach można zastosować do innych dostawców chmury publicznej, a także innych rodzajów dostawców (DNS, DB, Monitoring, itp.)

    Type
    Description
    Gotowość

    Struktura kodu Terragrunt

    Typ
    Opis
    Gotowość

    Infrastruktura wielkogabarytowa z Terraform

    Źródło:

    Ten przykład zawiera kod dla strukturyzacji konfiguracji Terraform dla dużego rozmiaru infrastruktury, która zawiera:

    • 2 konta AWS

    • 2 regiony

    Mała infrastruktura z Terraform

    Źródło:

    Ten przykład zawiera kod dla strukturyzacji konfiguracji Terraform dla małego rozmiaru infrastruktury, w której nie są używane zależności zewnętrzne.

    • Idealny na początek i gdy refaktoryzacja na bieżąco jest możliwa

    Kluczowe koncepty

    Oficjalna dokumentacja Terraforma szczegółowo . Przeczytaj ją uważnie, aby zrozumieć resztę tej sekcji.

    Ta sekcja opisuje kluczowe pojęcia, które są używane w książce.

    Zasób (resource)

    Przykładowe zasoby to aws_vpc, aws_db_instance, itd. Zasób należy do dostawcy (provider), może przyjmować argumenty (parameters) oraz zwracać różne atrybuty (outputs) i ma swój cykl życia (lifecycle). Może on być tworzony, pobierany, aktualizowany i usuwany.

    FAQ

    FTP (Frequent Terraform Problems), czyli najczęstsze problemy z Terraform

    Jakich narzędzi muszę używać?

    • - narzędzie do orkiestracji

    Pisanie konfiguracji Terraform

    Użyj zmiennych lokalnych (locals), aby określić jawne zależności między zasobami

    Przydatny sposób na wskazanie Terraform, że niektóre zasoby powinny zostać usunięte wcześniej, nawet jeśli nie ma bezpośredniej zależności w konfiguracjach.

    mała

    Mało zasobów, żadnych zewnętrznych zależności. Pojedyncze konto AWS. Tylko jeden region. Jedno środowisko.

    Tak

    średnia

    Kilka kont i środowisk AWS. Korzystanie z gotowych modułów infrastruktury Terraform. Wykorzystanie Terraform.

    Tak

    duża

    Wiele kont AWS, wiele regionów, pilna potrzeba ograniczenia kopiowania i wklejania, niestandardowe moduły infrastruktury, intensywne użycie kompozycji. Wykorzystanie Terraform.

    WIP

    bardzo duża

    Kilku dostawców (AWS, GCP, Azure). Wdrożenia w wielu chmurach. Wykorzystanie Terraform.

    Nie

    średnia

    Kilka kont i środowisk AWS. Korzystanie z gotowych modułów infrastruktury. Wykorzystanie Terragrunt.

    Nie

    duża

    Wiele kont AWS, wiele regionów, pilna potrzeba ograniczenia kopiowania i wklejania, niestandardowe moduły infrastruktury, intensywne użycie kompozycji. Wykorzystanie Terragrunt.

    Nie

    bardzo duża

    Kilku dostawców (AWS, GCP, Azure). Wdrożenia w wielu chmurach. Wykorzystanie Terragrunt.

    Nie

    2 oddzielne środowiska (
    prod
    i
    stage
    , które nic ze sobą nie dzielą). Każde środowisko funkcjonuje na osobnym koncie AWS
  • Każde środowisko korzysta z innej wersji gotowego modułu infrastruktury (alb) pochodzącego z Terraform Registry

  • Każde środowisko używa tej samej wersji modułów/sieci (modules/network) modułu wewnętrznego, ponieważ pochodzi z katalogu lokalnego.

  • W dużych projektach, takich jak przedstawiono tutaj, korzyści z użycia Terragrunt stają się bardzo widoczne. Spójrz na przykłady kody Terragrunt.

    • Idealny dla projektów, w których infrastruktura jest logicznie odseparowana (osobne konta AWS)

    • Dobre, gdy nie ma potrzeby modyfikowania zasobów współdzielonych między kontami AWS (jedno środowisko = jedno konto AWS = jeden plik stanu)

    • Dobre, gdy nie ma potrzeby organizowania zmian między środowiskami

    • Dobre, gdy zasoby infrastruktury są celowo różne w zależności od środowiska i nie można ich uogólniać (np. niektóre zasoby są nieobecne w jednym środowisku lub w niektórych regionach)

    W miarę rozwoju projektu coraz trudniej będzie zapewnić wzajemną aktualność tych środowisk. Rozważ użycie modułów infrastruktury (gotowych lub wewnętrznych) do powtarzalnych zadań.

    https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraform

    Idealny do modułów z małymi zasobami

  • Dobry dla małych i liniowych modułów infrastruktury (np. terraform-aws-atlantis)

  • Dobry dla małej liczby zasobów (mniej niż 20-30)

  • Plik jednego stanu dla wszystkich zasobów może spowolnić proces pracy z Terraform. Jeśli liczba zasobów rośnie, rozważ użycie argumentu -target, aby je ograniczyć.

    https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/small-terraform
    tflint - linter kodu
  • tfenv - menadżer wersji

  • Atlantis - narzędzie do automatyzacji pull-requestów

  • pre-commit-terraform - Zbiór git hooków dla Terraforma do użycia z pre-commit framework

  • Infracost - Oszacowywanie kosztów chmury w pull requestach. Działa z Terragrunt, Atlantis a także pre-commit-terrraform.

  • Jakie są rozwiązania piekła zależności (dependency hell) z modułami?

    Należy określić wersje modułów zasobów i infrastruktury. Dostawcy powinni być skonfigurowani poza modułami, ale tylko w kompozycji. Wersję dostawców i Terraform można również zablokować.

    Nie ma głównego narzędzia do zarządzania zależnościami, ale jest kilka wskazówek, dzięki którym piekło zależności będzie mniej problematyczne. Na przykład Dependabot może służyć do automatyzacji aktualizacji zależności. Dependabot tworzy pull requesty, aby Twoje zależności były bezpieczne i aktualne. Dependabot obsługuje konfiguracje Terraform.

    Terragrunt

    Źródła i dalsze materiały

    Jest wielu wspaniałych ludzi, którzy tworzą świetne treści i zarządzają projektami open-source istotnymi dla społeczności Terraform, ale nie mogę wymyślić niczego lepszego co nie byłoby kopiowaniem takiej listy jak awesome-terraform.

    https://twitter.com/antonbabenko/lists/terraform-experts - Lista osób, które bardzo aktywnie współpracują z Terraformem i mogą Ci wiele powiedzieć (jeśli ich zapytasz).

    https://github.com/shuaibiyy/awesome-terraform - Wyselekcjonowana lista zasobów o Terraform.

    http://bit.ly/terraform-youtube - Kanał YouTube Antona Babenko „Twoja Tygodniowa Dawka Terraformu” ("Your Weekly Dose of Terraform"). Na livestreamy z recenzjami, wywiadami, Q&A, kodowaniem na żywo i hackowaniem przy pomocy Terraform.

    https://weekly.tf - cotygodniowy biuletyn Terraform. Różne wiadomości ze świata Terraform (projekty, ogłoszenia, dyskusje) zebrane w jednym miejscu przez Antona Babenko.

    Terraform 0.12 - argumenty wymagane vs opcjonalne
    1. Wymagany argument index_document musi być ustawiony, jeśli var.website nie jest pustą mapą.

    2. Opcjonalny argument error_document można pominąć.

    https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tf
    main.tf
    variable "website" {
      type    = map(string)
      default = {}
    }
    
    resource "aws_s3_bucket" "this" {
      # pomijamy...
    
      dynamic "website" {
        for_each = length(keys(var.website)) == 0 ? [] : [var.website]
    
        content {
          index_document = website.value.index_document
          error_document = lookup(website.value, "error_document", null)
        }
      }
    }
    terraform.tfvars
    website = {
      index_document = "index.html"
    }
    Moduł zasobu (resource module)

    Moduł zasobu to zbiór połączonych zasobów, które razem wykonują wspólną akcję (np. moduł AWS VPC Terraform tworzy VPC, podsieci, bramę NAT itp.). Jest on zależny od konfiguracji dostawcy, którą można zdefiniować w nim lub w strukturach na wyższym poziomie (np. w module infrastruktury).

    Moduł infrastruktury (infrastructure module)

    Moduł infrastruktury to zbiór modułów zasobów, które nie muszą być ze sobą logicznie połączone, ale mogą, współpracując ze sobą służyć temu samemu celowi. Definiuje konfigurację dla dostawców, która jest następnie przekazywana do modułów zasobów podrzędnych i do samodzielnych zasobów. Zwykle ogranicza się on do pracy w pojedynczej encji na każdy logiczny separator (np. region AWS, projekt Google).

    Na przykład moduł terraform-aws-atlantis wykorzystuje moduły zasobów, takie jak terraform-aws-vpc i terraform-aws-security-group, do zarządzania infrastrukturą wymaganą do uruchomienia Atlantis na AWS Fargate.

    Innym przykładem jest moduł terraform-aws-cloudquery, w którym wiele modułów terraform-aws-modules jest używanych razem do zarządzania infrastrukturą, a także do tworzenia, wypychania i wdrażania obrazów platformy Docker. Wszystko w jednym miejscu.

    Kompozycja (composition)

    Kompozycja to zbiór modułów infrastruktury, które mogą obejmować kilka logicznie oddzielonych obszarów (np. regiony AWS, kilka kont AWS). Kompozycja służy do opisania kompletnej infrastruktury wymaganej dla całej organizacji lub projektu.

    Kompozycja składa się z modułów infrastruktury, na które składają się moduły zasobów, które realizują poszczególne zasoby

    Prosta kompozycja infrastruktury

    Źródło danych (data source)

    Źródło danych wykonuje operacje tylko do odczytu (read-only) i jest zależne od konfiguracji dostawcy. Jest ono używane w module zasobów i module infrastruktury.

    Źródło danych terraform_remote_state działa jako spoiwo dla modułów i kompozycji wyższego poziomu.

    Zewnętrzne źródło danych umożliwia, aby zewnętrzny program działał jako źródło danych, udostępniając dowolne dane do użycia w innym miejscu w konfiguracji Terraform. Oto przykład z modułu terraform-aws-lambda, w którym nazwa pliku jest uzyskiwana poprzez wywołanie zewnętrznego skryptu Python.

    Źródło danych http wysyła żądanie HTTP GET do podanego adresu URL i zwraca informacje o odpowiedzi. Jest to często przydatne w uzyskiwaniu informacji z punktów końcowych (endpoints), dla których nie istnieje natywny dostawca Terraform.

    Zdalny zapis stanu infrastruktury (remote state)

    Moduły infrastruktury i kompozycje powinny zachowywać swój stan Terraform w zdalnej lokalizacji, gdzie mogą być pobierane przez inne osoby w kontrolowany sposób (np. z ACL, wersjonowaniem, rejestrowaniem).

    Dostawca (provider, provisioner)

    Dostawca jest bardzo dobrze opisany w oficjalnej dokumentacji. Nie ma więc sensu tego tutaj powtarzać. Moim zdaniem ma on niewiele wspólnego z pisaniem dobrych modułów w Terraform.

    Skąd te trudności?

    Podczas gdy poszczególne zasoby są jak atomy w infrastrukturze, moduły zasobów są molekułami. Moduł jest najmniejszą jednostką, którą wersjonujemy i możemy udostępniać innym. Ma dokładną listę argumentów i implementuje podstawową logikę. Na przykład moduł terraform-aws-security-group tworzy zasoby aws_security_group oraz aws_security_group_rule na podstawie danych wejściowych. Może on być użyty razem z innymi modułami do stworzenia modułu infrastruktury.

    Dostęp do danych oraz wymiana między nimi (moduły zasobów i moduły infrastruktury) jest realizowany z wykorzystaniem wyjść modułów (module output) i źródeł danych.

    Dostęp między kompozycjami jest często realizowany przy użyciu zdalnych źródeł danych stanu. Istnieje wiele sposobów na udostępnianie danych między konfiguracjami.

    Starając się przedstawić opisane powyżej pojęcia przy pomocy pseudorelacji uzyskamy następującą strukturę:

    opisuje wszystkie aspekty konfiguracji
    Compliance.tf

    Stylizacja kodu

    • Przykłady i moduły Terraform powinny zawierać dokumentację wyjaśniającą funkcje i sposoby ich używania.

    • Wszystkie linki w plikach README.md powinny być bezwzględne, aby witryna Terraform Registry wyświetlała je poprawnie.

    • Dokumentacja może zawierać schematy stworzone za pomocą i plany stworzone za pomocą .

    • Korzystaj z , aby upewnić się, że kod jest prawidłowy, odpowiednio sformatowany i automatycznie udokumentowany przed przekazaniem go do git'a i sprawdzeniem przez innych.

    Dokumentacja

    Dokumentacja generowana automatycznie

    to framework do zarządzania i utrzymywania różnorodnych narzędzi do sprawdzania kodu przed jego wysłaniem do zdalnego repozytorium. Jest napisanym w Pythonie potężnym narzędziem do automatyzacji żmudnych czynności na maszynie programisty, zanim kod zostanie przekazany do repozytorium git. Zwykle jest używany do uruchamiania linterów i formatowania kodu (zobacz ).

    Dzięki konfiguracjom Terraform pre-commit może służyć do formatowania i sprawdzania poprawności kodu, a także do aktualizowania dokumentacji.

    Sprawdź . Zapoznaj się z nim oraz istniejącym repozytoriami (np. ), w których jest ono już używane.

    terraform-docs

    to narzędzie, które generuje dokumentację z modułów Terraform w różnych formatach wyjściowych. Możesz uruchomić go ręcznie (bez pre-commit hooków) lub użyć , aby automatycznie zaktualizować dokumentację.

    Źródła

    1. Post napisany przez :

    composition-1 {
      infrastructure-module-1 {
        data-source-1 => d1
    
        resource-module-1 {
          data-source-2 => d2
          resource-1 (d1, d2)
          resource-2 (d2)
        }
    
        resource-module-2 {
          data-source-3 => d3
          resource-3 (d1, d3)
          resource-4 (d3)
        }
      }
    
    }
    mermaid
    cloudcraft.co
    pre-commit hooks dla Terraform
    pre-commit
    supported hooks
    repozytorium pre-commit-terraform
    terraform-aws-vpc
    terraform-docs
    pre-commit-terraform
    Strona narzędzia pre-commit
    Zbiór git hooków dla Terraform
    Dean Wilson
    pre-commit hooks and terraform - a safety net for your repositories

    Konwencje nazewnictwa

    Podstawowe zasady

    Nie ma powodu, aby nie przestrzegać przynajmniej poniższych zasad :)

    Pamiętaj, że rzeczywiste zasoby często mają ograniczenia w dopuszczalnym nazewnictwie. Niektóre zasoby, na przykład nie mogą zawierać myślników. Inne zaś muszą być napisane z wykorzystaniem camelCase. Konwencje zawarte w tej książce odnoszą się tylko do samych nazw Terraform.

    1. Wszędzie używaj _ (podkreślenia) zamiast - (myślnika) (nazwy zasobów, nazwy źródeł danych, nazwy zmiennych, dane wyjściowe itp.).

    2. Staraj się używać małych liter i cyfr (nawet jeśli obsługiwany jest kod UTF-8).

    Zasoby i źródła danych

    1. Nie powtarzaj typu zasobu w nazwie zasobu (ani częściowo, ani całkowicie):

      resource "aws_route_table" "public" {}

    Przykładowy kod zasobu (resource)

    Użycie count / for_each

    Umiejscowienie tags

    Warunki w count

    Zmienne

    1. Nie próbuj na nowo wymyślać koła w modułach zasobów: użyj nazwy (name), opisu (description) i wartości domyślnej (default) dla zmiennych zgodnie z definicją w sekcji „Odniesienie do argumentów” ("Argument Reference") dla zasobu, z którym pracujesz.

    2. Obsługa walidacji w zmiennych jest raczej ograniczona (np. brak dostępu do innych zmiennych lub wyszukiwania). Zawczasu planuj odpowiednie użycie, ponieważ w wielu przypadkach funkcja walidacji jest bezużyteczna.

    Dane wyjściowe

    Spraw, aby dane wyjściowe były spójne i zrozumiałe poza zakresem użycia (scope) (gdy użytkownik korzysta z modułu, powinno być oczywiste, jaki jest typ i atrybut zwracanej wartości).

    1. Nazwa danych wyjściowych powinna opisywać właściwość, którą zawiera, i być bardziej ścisła niż standardowo.

    2. Dobra struktura nazwy wyjścia wygląda tak: {name}_{type}_{attribute} , gdzie:

      1. {name} to nazwa zasobu lub źródła danych bez prefiksu dostawcy. {name} dla

    Przykłady poprawnego output

    Zwróć co najwyżej jeden identyfikator security_group:

    W przypadku posiadania wielu zasobów tego samego typu, należy unikać this w nazwie wyjścia:

    Użyj nazwy w liczbie mnogiej, jeśli wartością zwracaną jest lista

    resource "aws_route_table" "public_route_table" {}

    resource "aws_route_table" "public_aws_route_table" {}

  • Nazwa zasobu powinna nazywać się this, jeśli nie ma bardziej opisowej i ogólnej nazwy, lub jeśli moduł zasobów tworzy pojedynczy zasób tego typu (np. w module AWS VPC jest pojedynczy zasób typu aws_nat_gateway i wiele zasobów typu aws_route_table, więc aws_nat_gateway powinien nazywać się this, a aws_route_table powinny być nazwane opisowe - jak private, public, database.

  • Nazwy zawsze powinny być rzeczownikami w liczbie pojedynczej.

  • Używaj - wewnątrz wartości argumentów oraz w miejscach, w których wartość będą odczytywane przez człowiekowa (np. wewnątrz nazwy DNS instancji RDS).

  • Argumenty count lub for_each umieszczaj wewnątrz bloku zasobu lub źródła danych jako pierwszy argument u góry i oddzielaj go znakiem nowej linii.

  • Argument tags, jeśli jest obsługiwany przez zasób, umieszczaj jako ostatni , po którym następuje depend_on i lifecycle, jeśli to konieczne. Wszystkie te elementy powinny być oddzielone pojedynczym pustym wierszem.

  • Używając warunków logicznych przy argumencie count lub for_each stosuj wartości logiczne zamiast porównywania długości ciągu czy innych wyrażeń.

  • Używaj liczby mnogiej w nazwie zmiennej, gdy jest ona listą (
    list(...)
    ) lub mapą (
    map(...)
    ) .
  • Uporządkuj klucze w bloku zmiennych w następujący sposób: opis (description), typ (type), wartość domyślna (default), walidacja (validation).

  • Zawsze dołączaj opis (description) do wszystkich zmiennych, nawet jeśli uważasz, że jest to oczywiste (przyda się w przyszłości).

  • Używaj prostych typów (number, string, list(...), map(...), any) zamiast określonego typu, takiego jak object(), chyba że musisz mieć ścisłą kontrolę nad każdym elementem.

  • Użyj określonych typów, np. map(map(string)) jeśli wszystkie elementy mapy mają ten sam typ (np. string ) lub mogą być na niego przekonwertowane (np. typ number można przekonwertować na string).

  • Użyj any, aby ominąć walidację typu, gdy chcesz obsłużyć różne typy..

  • Wartość {} to czasami mapa, a czasami obiekt. Użyj tomap(...), aby stworzyć mapę, ponieważ nie ma możliwości stworzenia obiektu.

  • aws_subnet
    to
    subnet
    , a dla
    aws_vpc
    to
    vpc
    .
  • {type} to rodzaj źródła zasobów.

  • {attribute} to zwracany atrybut

  • Zobacz przykłady.

  • Jeśli zwracana jest wartość z funkcjami interpolacji i wieloma zasobami, {name} i {type} powinny być jak najbardziej ogólne (należy unikać prefiksu this). Zobacz przykłady.

  • Jeśli zwracana wartość jest listą, powinna mieć nazwę w liczbie mnogiej. Zobacz przykłady.

  • Zawsze dołączaj opis (description) danych wyjściowych, nawet jeśli uważasz, że jest to oczywiste.

  • Unikaj użycia sensitive, chyba że w pełni kontrolujesz użycie tego wyjścia (danych wyjściowych) we wszystkich miejscach i we wszystkich modułach.

  • Stosuj try() (dostępne od Terraform 0.13) zamiast element(concat(...)) (podejście starsze dla wersji przed 0.13)

  • main.tf
    resource "aws_route_table" "public" {
      count = 2
    
      vpc_id = "vpc-12345678"
      # ... w celu uproszczenia pomijamy pozostałe argumenty
    }
    
    resource "aws_route_table" "private" {
      for_each = toset(["one", "two"])
    
      vpc_id = "vpc-12345678"
      # ... w celu uproszczenia pomijamy pozostałe argumenty
    }
    main.tf
    resource "aws_route_table" "public" {
      vpc_id = "vpc-12345678"
      count  = 2
    
      # ... w celu uproszczenia pomijamy pozostałe argumenty
    }
    main.tf
    resource "aws_nat_gateway" "this" {
      count = 2
    
      allocation_id = "..."
      subnet_id     = "..."
    
      tags = {
        Name = "..."
      }
    
      depends_on = [aws_internet_gateway.this]
    
      lifecycle {
        create_before_destroy = true
      }
    }   
    main.tf
    resource "aws_nat_gateway" "this" {
      count = 2
    
      tags = "..."
    
      depends_on = [aws_internet_gateway.this]
    
      lifecycle {
        create_before_destroy = true
      }
    
      allocation_id = "..."
      subnet_id     = "..."
    }
    outputs.tf
    resource "aws_nat_gateway" "that" {    # Best
      count = var.create_public_subnets ? 1 : 0
    }
    
    resource "aws_nat_gateway" "this" {    # Good
      count = length(var.public_subnets) > 0 ? 1 : 0
    }
    outputs.tf
    output "security_group_id" {
      description = "The ID of the security group"
      value       = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
    }
    outputs.tf
    output "this_security_group_id" {
      description = "The ID of the security group"
      value       = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
    }
    outputs.tf
    output "rds_cluster_instance_endpoints" {
      description = "A list of all cluster instance endpoints"
      value       = aws_rds_cluster_instance.this.*.endpoint
    }