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...

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.

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.

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.

Sponsorowanie

—

Tłumaczenia

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.

Autorzy_ki

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.

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

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 main.tf

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

Jak myśleć o strukturze konfiguracji Terraform?

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

  • 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

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.

  4. 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.

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

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.)

Struktura kodu Terragrunt

Kluczowe koncepty

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.

Moduł zasobu (resource module)

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).

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

Ź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.

Zdalny zapis stanu infrastruktury (remote state)

Dostawca (provider, provisioner)

Skąd te trudności?

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.

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

Infrastruktura średniej wielkości 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 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)

  • 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ń.

Mała infrastruktura z Terraform

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

  • Idealny do modułów z małymi zasobami

  • 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ć.

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

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

Please if you want to become a sponsor.

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

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

Jeśli jesteś zainteresowany konkretnymi tematami, 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!)\

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

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ą , , , , .

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

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

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 , aby uzyskać więcej informacji.

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

Type
Description
Gotowość
Typ
Opis
Gotowość

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

Moduł zasobu to zbiór połączonych zasobów, które razem wykonują wspólną akcję (np. moduł 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).

Na przykład moduł wykorzystuje moduły zasobów, takie jak i , do zarządzania infrastrukturą wymaganą do uruchomienia na .

Innym przykładem jest moduł , w którym wiele modułów 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.

ź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 , w którym nazwa pliku jest uzyskiwana poprzez wywołanie zewnętrznego skryptu Python.

Źródło danych 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.

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

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

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ł 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 między kompozycjami jest często realizowany przy użyciu zdalnych źródeł danych stanu. Istnieje wiele sposobów na .

Źródło:

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

Źródło:

Dobry dla małych i liniowych modułów infrastruktury (np. )

Terraform
https://www.terraform-best-practices.com/
contact me
mną
otwórz nowy wątek (issue)
Anton Babenko
random
local
terraform
null
time
Crossplane
Crossplane vs Terraform
Terraform
Terragrunt

ś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

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)
    }
  }

}
kompozycją
moduł zasobu
moduł infrastruktury
kompozycja
Compliance.tf
opisuje wszystkie aspekty konfiguracji
AWS VPC Terraform
terraform-aws-atlantis
terraform-aws-vpc
terraform-aws-security-group
Atlantis
AWS Fargate
terraform-aws-cloudquery
terraform-aws-modules
Zewnętrzne
terraform-aws-lambda
http
stan Terraform
opisany w oficjalnej dokumentacji
terraform-aws-security-group
udostępnianie danych między konfiguracjami
https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/medium-terraform
Terraform Registry
https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/small-terraform
terraform-aws-atlantis

Infrastruktura wielkogabarytowa z Terraform

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

  • 2 konta AWS

  • 2 regiony

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

  • 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)

  • 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ń.

FAQ

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

Jakich narzędzi muszę używać?

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ć.

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.

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ąć.

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

Dokumentacja generowana automatycznie

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

terraform-docs

Źródła

Warsztaty

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

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

Tak

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

Tak

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

Źródło:

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

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

- narzędzie do orkiestracji

- linter kodu

- menadżer wersji

- narzędzie do automatyzacji pull-requestów

- Zbiór git hooków dla Terraforma do użycia z

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

Jakie są rozwiązania (dependency hell) z modułami?

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 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.

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.

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 ).

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

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ę.

Post napisany przez :

Znajdziesz je tutaj:

mała
średnia
duża
https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraform
Terraform Registry
przykłady kody Terragrunt
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"
}

Terraform

Terragrunt

العربية (Arabic)
Bosanski (Bosnian)
Terragrunt
tflint
tfenv
Atlantis
pre-commit-terraform
pre-commit framework
Infracost
piekła zależności
Dependabot
https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tf
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
https://github.com/antonbabenko/terraform-best-practices-workshop

Ź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 .

- Lista osób, które bardzo aktywnie współpracują z Terraformem i mogą Ci wiele powiedzieć (jeśli ich zapytasz).

- Wyselekcjonowana lista zasobów o Terraform.

- 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.

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

Français (French)
English
Português (Brazilian Portuguese)
ქართული (Georgian)
ελληνικά (Greek)
awesome-terraform
https://twitter.com/antonbabenko/lists/terraform-experts
https://github.com/shuaibiyy/awesome-terraform
http://bit.ly/terraform-youtube
https://weekly.tf
עברית (Hebrew)
Bahasa Indonesia (Indonesian)
हिंदी (Hindi)
Deutsch (German)
日本語 (Japanese)
Italiano (Italian)
ಕನ್ನಡ (Kannada)

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" {}

    resource "aws_route_table" "public_route_table" {}

    resource "aws_route_table" "public_aws_route_table" {}

  2. Nazwy zawsze powinny być rzeczownikami w liczbie pojedynczej.

  3. 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).

  4. 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.

  5. 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.

  6. 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ń.

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.

  3. Używaj liczby mnogiej w nazwie zmiennej, gdy jest ona listą (list(...)) lub mapą (map(...)) .

  4. Uporządkuj klucze w bloku zmiennych w następujący sposób: opis (description), typ (type), wartość domyślna (default), walidacja (validation).

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

  6. 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.

  7. 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).

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

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

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 aws_subnet to subnet, a dla aws_vpc to vpc.

    2. {type} to rodzaj źródła zasobów.

    3. {attribute} to zwracany atrybut

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

  4. 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.

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

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

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 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.

.

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). .

Jeśli zwracana wartość jest listą, powinna mieć nazwę w liczbie mnogiej. .

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
}
AWS VPC
Zobacz przykłady
Zobacz przykłady
Zobacz przykłady
한국어 (Korean)
Română (Romanian)
简体中文 (Simplified Chinese)
Español (Spanish)
Türkçe (Turkish)
Українська (Ukrainian)
اردو (Urdu)
Prosta kompozycja infrastruktury