2017-04-04 58 views
5

W trakcie oceny Terraform, aby zastąpić (częściowo) nasz proces udzielania odpowiedzi dla SaaS dla wielu dzierżawców, zdajemy sobie sprawę z wygody, wydajności i niezawodności Terraform, ponieważ możemy obsłużyć zmiana infrastruktury (dodawanie/usuwanie) płynnie, śledzenie stanu infra (to bardzo fajne).Terraform: zarządzanie stanem dla wielu dzierżawców

Nasza aplikacja to SaaS dla wielu dzierżawców, dla których dostarczamy oddzielne instancje dla naszych klientów - w Ansible mamy własny dynamiczny ekwipunek (zupełnie taki sam jak dynamiczne zasoby EC2). Przechodzimy przez wiele książek/samouczków Terraform i najlepszych praktyk, z których wiele sugeruje, że stany wielostanowiskowe powinny być zarządzane osobno & zdalnie w Terraform, ale wszystkie z nich wyglądają jak statyczne env (np. Dev/Staging/Prod).

Czy istnieje jakaś najlepsza praktyka lub prawdziwy przykład zarządzania dynamiczną inwentaryzacją stanów dla aplikacji korzystających z wielu dzierżawców? Chcielibyśmy śledzić stan każdego zestawu instancji klienta - łatwo wprowadzamy w nich zmiany.

Jednym podejściem może być utworzenie katalogu dla każdego klienta i umieszczenie w nim skryptów * .tf, które będą wywoływać nasz moduł hostowany gdzieś na świecie. Pliki stanu mogą być przesyłane do S3, dzięki czemu możemy w razie potrzeby wprowadzać zmiany do każdego klienta.

Odpowiedz

2

Twoje sugerowane podejście brzmi dla mnie dobrze, ale jest kilka rzeczy, które możesz rozważyć.

zachować oryginalne szablony Terraform (_template w poniższej drzewa) jako wersjonowanych artefakt (git repo, dla EG) i po prostu przekazać klucz-wartość właściwości, aby móc odtworzyć swoją infrastrukturę. W ten sposób będziesz mieć bardzo małą ilość kopii wklejonego kodu konfiguracji Terraform leżącego w katalogach.

Jak to wygląda: Potrzebne są

/tf-infra 
├── _global 
│   └── global 
│    ├── README.md 
│    ├── main.tf 
│    ├── outputs.tf 
│    ├── terraform.tfvars 
│    └── variables.tf 
└── staging 
    └── eu-west-1 
     ├── saas 
     │   ├── _template 
     │   │   └── dynamic.tf.tpl 
     │   ├── customer1 
     │   │   ├── auto-generated.tf 
     │   │   └── terraform.tfvars 
     │   ├── customer2 
     │   │   ├── auto-generated.tf 
     │   │   └── terraform.tfvars 
... 

Dwa skrypty pomocnicze: rendering

  1. szablonu. Zastosowanie albo sed wygenerować module's source attribute lub użyć bardziej potężne narzędzie (jak na przykład to się robi w airbnb/streamalert)

  2. wrapper script. Zazwyczaj wystarcza uruchomienie terraform -var-file=....

Udostępnione terraform pliki państwa oraz środków, które powinny być globalne (katalog _global powyżej) mogą być przechowywane na S3, tak że inne warstwy mogą z nich korzystać.

PS: Jestem bardzo otwarty na komentarze dotyczące proponowanego rozwiązania, ponieważ jest to ciekawe zadanie pracować dalej :)

5

Terraform działa na poziomie folderu, ciągnąc w każdym .tf plików (i przez domyślnie plik terraform.tfvars).

Tak więc robimy coś podobnego do Anton 's answer, ale pozbędziemy się pewnej złożoności wokół szablonów z sed.Więc jako podstawowy przykład struktury może wyglądać następująco:

$ tree -a --dirsfirst 
. 
├── components 
│   ├── application.tf 
│   ├── common.tf 
│   ├── global_component1.tf 
│   └── global_component2.tf 
├── modules 
│   ├── module1 
│   ├── module2 
│   └── module3 
├── production 
│   ├── customer1 
│   │   ├── application.tf -> ../../components/application.tf 
│   │   ├── common.tf -> ../../components/common.tf 
│   │   └── terraform.tfvars 
│   ├── customer2 
│   │   ├── application.tf -> ../../components/application.tf 
│   │   ├── common.tf -> ../../components/common.tf 
│   │   └── terraform.tfvars 
│   └── global 
│    ├── common.tf -> ../../components/common.tf 
│    ├── global_component1.tf -> ../../components/global_component1.tf 
│    ├── global_component2.tf -> ../../components/global_component2.tf 
│    └── terraform.tfvars 
├── staging 
│   ├── customer1 
│   │   ├── application.tf -> ../../components/application.tf 
│   │   ├── common.tf -> ../../components/common.tf 
│   │   └── terraform.tfvars 
│   ├── customer2 
│   │   ├── application.tf -> ../../components/application.tf 
│   │   ├── common.tf -> ../../components/common.tf 
│   │   └── terraform.tfvars 
│   └── global 
│    ├── common.tf -> ../../components/common.tf 
│    ├── global_component1.tf -> ../../components/global_component1.tf 
│    └── terraform.tfvars 
├── apply.sh 
├── destroy.sh 
├── plan.sh 
└── remote.sh 

Tutaj można uruchomić plan/zastosowanie/zniszczyć z poziomu głównego, w którym skrypty shell wrapper obsłużyć rzeczy jak cd'ing do katalogu i działa terraform get -update=true ale również do folderu, aby uzyskać terraform init, aby uzyskać unikalny klucz pliku stanu dla S3, umożliwiający śledzenie stanu każdego folderu niezależnie.

Powyższe rozwiązanie ma ogólne moduły, które zawijają zasoby w celu zapewnienia wspólnego interfejsu dla rzeczy (na przykład nasze instancje EC2 są oznaczone w określony sposób w zależności od niektórych zmiennych wejściowych i mają prywatny rekord Route53), a następnie "zaimplementowane komponenty ".

Te komponenty zawierają pakiet modułów/zasobów, które Terraform zastosuje w tym samym folderze. Możemy więc umieścić ELB, niektóre serwery aplikacji i bazę danych pod numerem application.tf, a następnie dowiązanie symboliczne do lokalizacji daje nam jedno miejsce do kontrolowania za pomocą Terraform. Tam, gdzie możemy mieć pewne różnice w zasobach dla danej lokalizacji, zostaną one oddzielone. W powyższym przykładzie widać, że staging/global ma wartość global_component2.tf, której nie ma w produkcji. Może to być coś, co stosuje się tylko w środowiskach nieprodukcyjnych, takich jak niektóre funkcje kontroli sieci, aby uniemożliwić dostęp do Internetu.

Prawdziwa zaleta polega na tym, że wszystko jest łatwo dostępne bezpośrednio dla programistów, a nie ma etapu tworzenia szablonów, który zapewnia kod Terraform.

Pomaga także śledzić proces DRY, w którym jedyne rzeczywiste różnice między środowiskami występują w plikach terraform.tfvars w lokalizacjach i ułatwiają testowanie zmian przed ich aktywacją, ponieważ każdy folder jest prawie taki sam jak inny.

+0

Przy takim podejściu działałbyś terraform wewnątrz każdego folderu lub z katalogu głównego? Pytam, ponieważ w zależności od tego pliki stanu mogą być przechowywane w ścieżce głównej lub w każdym folderze. –

+0

Nie można uruchomić Terraform z folderu nadrzędnego. Terraform działa tylko z tym, co znajduje się w bieżącym katalogu. Tak się składa, że ​​mamy kilka skryptów pomocniczych, które są w katalogu głównym repo, które 'cd' w lokalizacji, na której chcemy działać, a następnie uruchamiają komendy' terraform' CLI. – ydaetskcoR

+0

Tak, mogę, robię to przez cały czas ... 'ścieżka planu terraform/to/coś' –