Jestem również w stanie migracji istniejącej infrastruktury AWS do Terraform, więc będę starał się aktualizować odpowiedź w miarę rozwoju.
W dużej mierze polegałem na oficjalnych przykładach Terraform i wielu próbach i błędach, aby opracować obszary, w których nie byłem pewien.
.tfstate
pliki
Konfiguracja Terraform może służyć do obsługi wielu skrzynek w innej infrastrukturze, z których każda może mieć inny stan. Ponieważ może być również uruchamiany przez wiele osób, stan ten powinien znajdować się w scentralizowanej lokalizacji (takiej jak S3), ale nie w git.
Można to potwierdzić patrząc na Terraform .gitignore
.
Kontrola dewelopera
Naszym celem jest zapewnienie deweloperom większej kontroli nad infrastrukturą przy jednoczesnym zachowaniu pełnego audytu (dziennik git) oraz możliwości sprawdzania poprawności zmian (pull requesty). Mając to na uwadze, nowy przepływ pracy dotyczący infrastruktury, do którego dążę, to:
- Podstawowy fundament powszechnych AMI, które obejmują moduły wielokrotnego użytku, np. Marionetka.
- Infrastruktura podstawowa udostępniana przez DevOps przy użyciu Terraform.
- Deweloperzy w razie potrzeby zmieniają konfigurację Terraform w Git (liczba wystąpień, nowy VPC, dodanie regionu / strefy dostępności itp.).
- Konfiguracja Git została wypchnięta, a żądanie ściągnięcia zostało przesłane do sprawdzenia przez członka zespołu DevOps.
- Po zatwierdzeniu wywołuje element webhook do CI w celu kompilacji i wdrożenia (nie jest w tej chwili pewna, jak podzielić wiele środowisk na partycje)
Edycja 1 - aktualizacja aktualnego stanu
Odkąd zacząłem tę odpowiedź, napisałem dużo kodu TF i czuję się bardziej komfortowo w naszym stanie rzeczy. Po drodze napotkaliśmy błędy i ograniczenia, ale zgadzam się, że jest to cecha charakterystyczna używania nowego, szybko zmieniającego się oprogramowania.
Układ
Mamy skomplikowaną infrastrukturę AWS z wieloma VPC z wieloma podsieciami. Kluczem do łatwego zarządzania tym było zdefiniowanie elastycznej taksonomii obejmującej region, środowisko, usługę i właściciela, której możemy użyć do uporządkowania kodu naszej infrastruktury (zarówno terraform, jak i marionetki).
Moduły
Następnym krokiem było utworzenie jednego repozytorium git do przechowywania naszych modułów terraform. Nasza struktura katalogów najwyższego poziomu dla modułów wygląda następująco:
tree -L 1 .
Wynik:
├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates
Każdy z nich ustawia rozsądne wartości domyślne, ale ujawnia je jako zmienne, które mogą zostać nadpisane przez nasz „klej”.
Klej
Posiadamy drugie repozytorium z naszym, glue
które korzysta z modułów wymienionych powyżej. Jest ułożony zgodnie z naszym dokumentem taksonomicznym:
.
├── README.md
├── clientA
│ ├── eu-west-1
│ │ └── dev
│ └── us-east-1
│ └── dev
├── clientB
│ ├── eu-west-1
│ │ ├── dev
│ │ ├── ec2-keys.tf
│ │ ├── prod
│ │ └── terraform.tfstate
│ ├── iam.tf
│ ├── terraform.tfstate
│ └── terraform.tfstate.backup
└── clientC
├── eu-west-1
│ ├── aws.tf
│ ├── dev
│ ├── iam-roles.tf
│ ├── ec2-keys.tf
│ ├── prod
│ ├── stg
│ └── terraform.tfstate
└── iam.tf
Na poziomie klienta mamy .tf
pliki specyficzne dla konta AWS , które udostępniają globalne zasoby (takie jak role IAM); następny to poziom regionu z kluczami publicznymi EC2 SSH; W końcu w naszym środowisku ( dev
, stg
, prod
etc) są naszą konfiguracje VPC, tworzenie instancji i zaglądanie połączeń itd są przechowywane.
Uwaga boczna: Jak widać, sprzeciwiam się mojej własnej radzie powyżej, trzymając się terraform.tfstate
git. Jest to środek tymczasowy, dopóki nie przejdę na S3, ale mi odpowiada, ponieważ obecnie jestem jedynym programistą.
Następne kroki
Jest to nadal proces ręczny i jeszcze nie w Jenkinsie, ale przenosimy dość dużą, skomplikowaną infrastrukturę i jak dotąd jest to dobre. Jak powiedziałem, kilka błędów, ale wszystko idzie dobrze!
Edycja 2 - zmiany
Minął prawie rok, odkąd napisałem tę wstępną odpowiedź, a stan Terraform i mnie znacznie się zmienił. Jestem teraz na nowej pozycji przy użyciu Terraform do zarządzania klastrem Azure, a Terraform jest teraz v0.10.7
.
Stan
Ludzie wielokrotnie powtarzali mi, że stan nie powinien wchodzić w Git - i mają rację. Wykorzystaliśmy to jako środek tymczasowy z dwuosobowym zespołem, który polegał na komunikacji i dyscyplinie programistów. W większym, rozproszonym zespole w pełni wykorzystujemy stan zdalny w S3 z blokadą zapewnianą przez DynamoDB. Najlepiej byłoby, gdyby zostało to przeniesione do Consul, teraz jest to wersja 1.0, aby zmniejszyć liczbę dostawców usług w chmurze.
Moduły
Wcześniej tworzyliśmy i używaliśmy modułów wewnętrznych. Nadal tak jest, ale wraz z pojawieniem się i rozwojem rejestru Terraform staramy się wykorzystać je przynajmniej jako podstawę.
Struktura plików
Nowa pozycja ma znacznie prostszą taksonomię z tylko dwoma środowiskami infx - dev
i prod
. Każdy ma własne zmienne i dane wyjściowe, wykorzystując ponownie nasze moduły utworzone powyżej. remote_state
Dostawca pomaga w dzieleniu się wyjść tworzonych zasobów pomiędzy środowiskami. Nasz scenariusz obejmuje subdomeny w różnych grupach zasobów platformy Azure do globalnie zarządzanej domeny TLD.
├── main.tf
├── dev
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf
Planowanie
Ponownie z dodatkowymi wyzwaniami rozproszonego zespołu, teraz zawsze zapisujemy nasze wyniki terraform plan
polecenia. Możemy sprawdzić i wiedzieć, co zostanie uruchomione bez ryzyka pewnych zmian między sceną plan
a apply
(chociaż pomaga w tym blokowanie). Pamiętaj, aby usunąć ten plik planu, ponieważ może on potencjalnie zawierać „tajne” zmienne tekstowe.
Ogólnie jesteśmy bardzo zadowoleni z Terraform i nadal się uczymy i ulepszamy dzięki dodanym nowym funkcjom.
Intensywnie używamy Terraform, a nasza zalecana konfiguracja jest następująca:
Układ plików
Zdecydowanie zalecamy przechowywanie kodu Terraform dla każdego środowiska (np. Stage, prod, qa) w osobnych zestawach szablonów (a zatem w osobnych
.tfstate
plikach). Jest to ważne, aby Twoje oddzielne środowiska były faktycznie odizolowane od siebie podczas wprowadzania zmian. W przeciwnym razie, podczas majstrowania przy jakimś kodzie podczas inscenizacji, zbyt łatwo jest wysadzić coś w prod. Zobacz Terraform, VPC i dlaczego potrzebujesz pliku tfstate na env, aby zapoznać się z kolorową dyskusją o tym, dlaczego.Dlatego nasz typowy układ plików wygląda następująco:
Cały kod Terraform dla etapu VPC trafia do
stage
folderu, cały kod dla produktu VPC trafia doprod
folderu, a cały kod, który znajduje się poza VPC (np. Użytkownicy IAM, tematy SNS, zasobniki S3) trafia doglobal
folderu .Zwróć uwagę, że zgodnie z konwencją zazwyczaj dzielimy nasz kod Terraform na 3 pliki:
vars.tf
: Zmienne wejściowe.outputs.tf
: Zmienne wyjściowe.main.tf
: Rzeczywiste zasoby.Moduły
Zazwyczaj naszą infrastrukturę definiujemy w dwóch folderach:
infrastructure-modules
: Ten folder zawiera małe, wielokrotnego użytku, wersjonowane moduły. Potraktuj każdy moduł jako plan tworzenia pojedynczego elementu infrastruktury, takiego jak VPC lub baza danych.infrastructure-live
: Ten folder zawiera rzeczywistą działającą infrastrukturę, którą tworzy poprzez połączenie modułów winfrastructure-modules
. Pomyśl o kodzie w tym folderze jak o rzeczywistych domach, które zbudowałeś ze swoich planów.Moduł Terraform jest byle zestaw szablonów Terraform w folderze. Na przykład możemy mieć folder o nazwie
vpc
in,infrastructure-modules
który definiuje wszystkie tabele tras, podsieci, bramy, listy ACL itp. Dla jednej sieci VPC:Możemy wtedy użyć tego modułu w
infrastructure-live/stage
iinfrastructure-live/prod
do tworzenia VPCs scenie i prod. Na przykład takinfrastructure-live/stage/main.tf
może wyglądać:Aby użyć modułu, użyj rozszerzenia
module
zasobu i wskazać jegosource
pole na ścieżkę lokalną na dysku twardym (np.source = "../infrastructure-modules/vpc"
) Lub, jak w powyższym przykładzie, adres URL Git (patrz źródła modułów ). Zaletą adresu URL Git jest to, że możemy określić konkretny git sha1 lub tag (ref=v0.0.4
). Teraz nie tylko definiujemy naszą infrastrukturę jako zbiór małych modułów, ale możemy wersjonować te moduły i starannie aktualizować lub wycofywać w razie potrzeby.Stworzyliśmy wiele wielokrotnego użytku, przetestowanych i udokumentowanych pakietów infrastruktury do tworzenia VPC, klastrów Docker, baz danych i tak dalej, a większość z nich to po prostu wersjonowane moduły Terraform.
Stan
Gdy używasz Terraform do tworzenia zasobów (np. Instancji EC2, baz danych, VPC), zapisuje on informacje o tym, co utworzył w
.tfstate
pliku. Aby wprowadzić zmiany w tych zasobach, wszyscy w Twoim zespole muszą mieć do nich dostęp.tfstate
pliku, ale NIE powinieneś sprawdzać go w Git (zobacz tutaj, aby uzyskać wyjaśnienie, dlaczego ).Zamiast tego zalecamy przechowywanie
.tfstate
plików w S3, włączając Terraform Remote State , który automatycznie wypycha / pobiera najnowsze pliki przy każdym uruchomieniu Terraform. Upewnij się, że włączyłeś.tfstate
przechowywanie wersji w swoim zasobniku S3, aby móc przywrócić starsze pliki, jeśli w jakiś sposób uszkodzisz najnowszą wersję. Jednak ważna uwaga: Terraform nie zapewnia blokowania . Więc jeśli dwóch członków zespołu pracujeterraform apply
w tym samym czasie na tym samym.tfstate
pliku, mogą skończyć się wzajemnym nadpisywaniem zmian.Aby rozwiązać ten problem, stworzyliśmy narzędzie open source o nazwie Terragrunt , które jest cienkim opakowaniem dla Terraform, które wykorzystuje Amazon DynamoDB do zapewniania blokowania (które powinno być całkowicie bezpłatne dla większości zespołów). Aby uzyskać więcej informacji, zobacz Dodawanie automatycznego blokowania i konfiguracji stanu zdalnego do Terraform z Terragrunt .
Dalsza lektura
Właśnie rozpoczęliśmy serię postów na blogu zatytułowanej Kompleksowy przewodnik po Terraform , w którym szczegółowo opisano wszystkie najlepsze praktyki, jakich nauczyliśmy się przy używaniu Terraform w prawdziwym świecie.
Aktualizacja: seria wpisów na blogu Wszechstronny przewodnik po Terraform stała się tak popularna, że rozszerzyliśmy ją do książki pod tytułem Terraform: Up & Running !
źródło
remote config
jeśli właśnie sprawdziłeś konfiguracje Terraform lub jeśli chcesz zmienić poprzednią konfigurację zdalną. Terraform 0.9 wprowadzi koncepcjębackends
, która bardzo to uprości. Zobacz ten PR, aby uzyskać więcej informacji.remote config
polecenie, aby wskazać stan produktu. Zakładając inny stan na środowisko. Czy to prawda? Nie mogę się doczekać wersji 0.9..tf
plików w dwóch różnych środowiskach, tak, musisz uruchamiać zaremote config
każdym razem, gdy się przełączasz. Jest to oczywiście bardzo podatne na błędy, więc nie polecam korzystania z tej techniki. Zamiast tego zapoznaj się z zalecanym układem pliku Terraform w tym poście na blogu oraz sposobem korzystania z modułów Terraform w tym poście .Wcześniej
remote config
pozwalano na to, ale teraz zostało zastąpione przez „ backendy ”, więc zdalne sterowanie terraform nie jest już dostępne.Szczegółowe informacje można znaleźć w dokumentacji .
źródło
Bardziej szczegółowo omówione przez @Yevgeny Brikman, ale w szczególności odpowiadając na pytania OP:
Użyj git dla plików TF. Ale nie sprawdzaj plików stanu w (np. Tfstate). Zamiast tego użyj
Terragrunt
do synchronizacji / blokowania plików stanu do S3.Nie.
tak
źródło
Wiem, że jest tu wiele odpowiedzi, ale moje podejście jest zupełnie inne.
Moduły
Zarządzanie środowiskiem
IaC sprawiło, że proces SDLC jest istotny dla zarządzania infrastrukturą i nie jest normalne oczekiwanie posiadania infrastruktury programistycznej, jak również środowisk programistycznych.
Rozdzielenie obowiązków
Jeśli jesteś w małej organizacji lub posiadasz infrastrukturę osobistą, to tak naprawdę nie ma zastosowania, ale pomoże ci zarządzać twoimi operacjami.
Pomaga to również w przypadku problemów z wydaniem, ponieważ niektóre zasoby rzadko się zmieniają, podczas gdy inne zmieniają się cały czas. Separacja eliminuje ryzyko i złożoność.
Ta strategia przypomina strategię wielu kont AWS. Przeczytaj, aby uzyskać więcej informacji.
CI / CD
To temat sam w sobie, ale Terraform działa bardzo dobrze w ramach dobrego potoku. Najczęstszym błędem jest tutaj traktowanie CI jako srebrnej kuli. Z technicznego punktu widzenia Terraform powinien dostarczać infrastrukturę tylko na etapach rurociągu montażowego. Byłoby to niezależne od tego, co dzieje się na etapach CI, gdzie zazwyczaj sprawdza się i testuje szablony.
Uwaga: Napisane na telefon komórkowy, więc przepraszamy za wszelkie błędy.
źródło
Typowe zalecenia dotyczące strukturyzacji kodu
Praca z mniejszą liczbą zasobów jest łatwiejsza i szybsza:
terraform plan
iterraform
zastosuj oba wywołania interfejsu API chmury w celu zweryfikowania stanu zasobów.Promień rażenia jest mniejszy i mniej zasobów:
Rozpocznij projekt przy użyciu stanu zdalnego:
tfstate
plikiem w git to koszmar.Spróbuj przećwiczyć spójną strukturę i konwencję nazewnictwa:
Utrzymuj moduły zasobów w jak najbardziej przejrzystej formie.
Nie twórz na stałe wartości, które można przekazać jako zmienne lub wykryć za pomocą źródeł danych.
Używaj
data
źródeł, aterraform_remote_state
zwłaszcza jako kleju między modułami infrastruktury w kompozycji.( patrz artykuł: https://www.terraform-best-practices.com/code-structure )
Przykład:
UWAGA: jako odniesienie, którego nie należy ściśle przestrzegać, ponieważ każdy projekt ma swoje specyficzne cechy
źródło
Uważam, że podczas korzystania z narzędzia Terraform do orkiestracji infrastruktury należy przestrzegać kilku najlepszych praktyk
Obsługuj wiele środowisk
Najczęściej zalecanym sposobem jest użycie terraform „przestrzeni roboczej” do obsługi wielu środowisk, ale uważam, że wykorzystanie przestrzeni roboczej może się różnić w zależności od sposobu pracy w organizacji. Innym jest przechowywanie kodu Terraform dla każdego środowiska (np. Stage, prod, QA) w celu oddzielenia stanów środowiska. Jednak w tym przypadku po prostu kopiujemy ten sam kod w wielu miejscach.
Zastosowałem inne podejście do obsługi i unikania powielania tego samego kodu terraform, przechowując w każdym folderze środowiska, ponieważ uważam, że przez większość czasu całe środowisko będzie w 90% takie samo.
Konfiguracja związana ze środowiskami
Zachowaj konfigurację i parametry związane ze środowiskiem oddzielnie w pliku zmiennych i przekaż tę wartość, aby skonfigurować infrastrukturę. np. jak poniżej
dev.backend.tfvar
dev.variable.tfvar
Warunkowe pomijanie części infrastruktury
Utwórz konfigurację w pliku zmiennej specyficznej dla środowiska env i na podstawie tej zmiennej zdecyduj o utworzeniu lub pominięciu tej części. W ten sposób w zależności od potrzeb można pominąć określoną część infrastruktury.
poniższe polecenie jest wymagane do zainicjowania i wykonania zmian infra dla każdego środowiska, cd do wymaganego folderu środowiska.
źródło
Nie podoba mi się pomysł z podfolderami, ponieważ spowoduje to różne źródła dla każdego środowiska i ma tendencję do dryfowania.
Lepszym podejściem jest posiadanie jednego stosu dla wszystkich środowisk (powiedzmy dla programistów, preprod i prod). Aby pracować w jednym środowisku, użyj
terraform workspace
.Tworzy to nowy obszar roboczy. Obejmuje to dedykowany plik stanu i zmienną,
terraform.workspace
której możesz użyć w swoim kodzie.W ten sposób otrzymasz tzw. Wiadra
po zastosowaniu do powyższych obszarów roboczych (użyj
terraform workspace select <WORKSPACE>
do zmiany środowisk). Aby kod był odporny na wiele regionów, zrób to w następujący sposób:dostać (dla regionu us-east-1)
źródło
Niektóre sprawdzone metody Terraform do przestrzegania:
Unikaj twardego kodowania: czasami programiści ręcznie tworzyli zasoby bezpośrednio. Musisz oznaczyć te zasoby i użyć importu terraform, aby uwzględnić je w kodach. Próbka:
account_number = „123456789012” account_alias = „mojafirma”
Uruchom Terraform z kontenera Dockera: Terraform udostępnia oficjalny kontener Docker, który umożliwia łatwe kontrolowanie, którą wersję można uruchomić.
Zaleca się uruchomienie kontenera Terraform Docker podczas ustawiania zadania kompilacji w potoku ciągłej integracji / ciągłej integracji.
Więcej informacji można znaleźć na moim blogu: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3
źródło
Chciałbym wnieść swój wkład w ten wątek.
W niektórych szczególnych przypadkach wymagany będzie ręczny dostęp do plików stanu Terraform. Rzeczy takie jak refaktoryzacja, wprowadzanie zmian lub naprawianie defektów będą wymagały uruchomienia operacji Terraform stanu przez personel operacyjny. W takich przypadkach zaplanuj wyjątkowo kontrolowany dostęp do stanu Terraform za pomocą hosta bastionu, VPN itp.
Zapoznaj się z dłuższym blogiem z najlepszymi praktykami, który szczegółowo omawia tę kwestię, w tym wskazówki dotyczące potoków ciągłej integracji / ciągłej integracji.
źródło
Jeśli nadal szukasz lepszego rozwiązania, spójrz na obszary robocze, które mogą zastąpić utrzymywanie innej struktury folderów środowiska, które mogą mieć zmienne specyficzne dla obszaru roboczego.
Jak wspomniał Yevgeniy Brikman , lepiej mieć strukturę modułową .
źródło
Użyj chmury terraform do zarządzania stanami i zapisywania ich wraz z powyższymi wskazówkami.
źródło