2016-05-03 21 views
16

Ich habe Terraform verwendet, um meinen AWS-Stack zu erstellen und habe es genossen. Wenn es in einer kommerziellen Umgebung verwendet werden soll, müsste die Konfiguration für verschiedene Umgebungen (z. B. QA, STAGING, PROD) wiederverwendet werden.Verschiedene Umgebungen für Terraform (Hashicorp)

Wie könnte ich das erreichen? Müsste ich ein Wrapper-Skript erstellen, das Aufrufe von Terraforms CLI ausführt, während es verschiedene Statusdateien pro Umgebung wie unten weitergibt? Ich frage mich, ob es eine nativere Lösung von Terraform gibt.

terraform apply -state=qa.tfstate 

Antwort

12

Ich schlage vor, Sie werfen einen Blick auf die hashicorp best-practices repo, die eine ziemlich gute Einstellung für den Umgang mit verschiedenen Umgebungen hat (ähnlich wie James Woolfenden vorgeschlagen).

Wir verwenden ein ähnliches Setup, und es funktioniert ganz gut. Bei diesem Best-Practices-Repo wird jedoch davon ausgegangen, dass Sie Atlas verwenden, was wir nicht tun. Wir haben ein ziemlich ausgeklügeltes Rakefile erstellt, das im Grunde (indem wir erneut das Best-Practices-Repo verwenden) alle Unterordner von/terraform/providers/aws erhält und sie als verschiedene Builds mit Namespaces verfügbar macht. Also unsere rake -T Ausgang würde die folgenden Aufgaben aufzulisten:

us_east_1_prod:init 
us_east_1_prod:plan 
us_east_1_prod:apply 

us_east_1_staging:init 
us_east_1_staging:plan 
us_east_1_staging:apply 

Diese Trennung Änderungen verhindert, die exklusiv sein könnte dev versehentlich beeinflussen (oder noch schlimmer, zerstören) etwas in prod, wie es eine andere Statusdatei ist. Es ermöglicht auch das Testen einer Änderung in dev/staging, bevor es tatsächlich auf prod angewendet wird.

Auch ich stolperte vor kurzem auf diesem kleinen aufzuschreiben, was im Grunde zeigt, was passieren könnte, wenn man alles zusammen zu halten: https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/

+0

Ich denke, das ist wahrscheinlich eine bessere Antwort für viele Leute. – the0ther

+1

Es ist definitiv eine bewährte Methode, einen separaten Tabellenabschnitt pro Umgebung beizubehalten. Seit Terraform 0.10 führt die Funktion [Workspaces] (https://www.terraform.io/docs/state/workspaces.html) genau das für jeden Arbeitsbereich durch (d. H.Umgebung) – RichVel

3

Keine Notwendigkeit, ein Wrapper-Skript zu erstellen. Was wir tun, ist unser env in ein Modul zu teilen und dann eine Terraform-Datei auf oberster Ebene zu haben, wo wir dieses Modul für jede Umgebung importieren. Solange Sie Ihr Modul-Setup so eingerichtet haben, dass es genügend Variablen akzeptiert, im Allgemeinen env_name und ein paar andere, sind Sie gut. Als Beispiel

# project/main.tf 
module "dev" { 
    source "./env" 

    env = "dev" 
    aws_ssh_keyname = "dev_ssh" 
} 

module "stage" { 
    source "./env" 

    env = "stage" 
    aws_ssh_keyname = "stage_ssh" 
} 

# Then in project/env/main.tf 
# All the resources would be defined in here 
# along with variables for env and aws_ssh_keyname, etc. 
+0

Interessant. Wie halten Sie die .TFState-Dateien getrennt? Behalten Sie die umgebungsspezifischen Module in separaten Ordnern und behalten Sie zugehörige .tfstate-Dateien dort bei? – n00b

+0

Brauche keine Datei für das gesamte aws-Konto. Wenn du dein Modul in git eingibst, kannst du Versionen und Zweige für die envs festlegen. Stellen Sie nur sicher, dass Sie ein Terraform-Get vor jeder Implementierung in die Nicht-Dev-Umgebung ausführen. – Paul

+0

Meinst du eine 'terraform refresh'? – n00b

5

Wie Sie Ihre Terraforming Nutzung skalieren, müssen Sie Zustand (zwischen Devs, bauen Prozesse und verschiedene Projekte) teilen, mehrere Umgebungen und Regionen unterstützen. Dazu müssen Sie den Remote-Status verwenden. Bevor Sie Ihre Terraform ausführen, müssen Sie Ihren Status einrichten. (Im mit Powershell)

$environment="devtestexample" 
$region  ="eu-west-1" 
$remote_state_bucket = "${environment}-terraform-state" 
$bucket_key = "yoursharedobject.$region.tfstate" 

aws s3 ls "s3://$remote_state_bucket"|out-null 
if ($lastexitcode) 
{ 
    aws s3 mb "s3://$remote_state_bucket" 
} 

terraform remote config -backend S3 -backend-config="bucket=$remote_state_bucket" -backend-config="key=$bucket_key" -backend-config="region=$region" 
#(see here: https://www.terraform.io/docs/commands/remote-config.html) 

terraform apply -var='environment=$environment' -var='region=$region' 

jetzt Ihr Zustand in S3 gespeichert ist, nach Region, durch die Umwelt, und Sie können dann diesen Zustand in anderen tf Projekte zugreifen.

7

Paul-Lösung mit Modulen die richtige Idee. Ich würde jedoch dringend empfehlen gegen alle Ihre Umgebungen (z. B. QA, Staging, Produktion) in der gleichen Terraform-Datei definieren. Wenn du das tust, riskierst du, wenn du die Staging-Einstellungen änderst, auch versehentlich die Produktion zu unterbrechen, was teilweise dazu führt, dass diese Umgebungen nicht isoliert werden! Eine farbenfrohe Diskussion darüber, was schiefgehen kann, finden Sie unter Terraform, VPC, and why you want a tfstate file per env.

Ich empfehle immer, den Terraform-Code für jede Umgebung in einem separaten Ordner zu speichern. In der Tat können Sie sogar den Terraform-Code für jede "Komponente" (z. B. eine Datenbank, eine VPC, eine einzelne App) in separaten Ordnern speichern. Der Grund liegt wiederum in der Isolation: Wenn Sie Änderungen an einer einzelnen App vornehmen (was Sie möglicherweise zehn Mal am Tag tun), möchten Sie nicht Ihre gesamte VPC gefährden (die Sie wahrscheinlich nie ändern werden).

Daher mein typisches Datei-Layout sieht ungefähr so ​​aus:

stage 
    └ vpc 
    └ main.tf 
    └ vars.tf 
    └ outputs.tf 
    └ app 
    └ db 
prod 
    └ vpc 
    └ app 
    └ db 
global 
    └ s3 
    └ iam 

All Terraforming-Code für die Staging-Umgebung geht in die stage Ordner, die gesamte Code für die Umwelt prod geht in die prod Ordner und Der gesamte Code außerhalb der Umgebung (z. B. IAM-Benutzer, S3-Buckets) wird in den Ordner global übernommen.

Weitere Informationen finden Sie unter How to manage Terraform state. Einen tieferen Einblick in die Best Practices von Terraform finden Sie im Buch Terraform: Up & Running.

+0

Haben Sie versucht, diese Lösung mit einer Verwendung von Modulen zu verschmelzen, um separate Ordner loszuwerden - separates Statusproblem? – aholbreich

+0

@aholbreich Um den gleichen Code nicht zwischen den einzelnen Umgebungen kopieren zu müssen, verwenden wir Module wie hier beschrieben: [Wie man eine wiederverwendbare Infrastruktur mit Terraform-Modulen erstellt] (https://blog.gruntwork.io/how-to -replizieren-wiederverwendbare-Infrastruktur-mit-Terraform-Module-25526d65f73d). –

+0

@YevgeniyBrikman irgendwelche Empfehlungen zum Entfernen der 90% Duplizierung von Code aus jeder Umgebung? Jeder von mir ist sehr ähnlich und alle ändern ist fehleranfällig. Danke im Voraus. –

3

Bitte beachten Sie, dass Terraform ab der Version 0.10.0 das Konzept der Arbeitsbereiche (Umgebungen in 0.9.x) unterstützt.

Ein Arbeitsbereich ist ein benannter Container für den Terraform-Status. Bei mehreren Arbeitsbereichen kann ein einziges Verzeichnis der Terraform-Konfiguration verwendet werden, um mehrere unterschiedliche Gruppen von Infrastrukturressourcen zu verwalten.

Weitere Informationen hier: https://www.terraform.io/docs/state/workspaces.html

Verwandte Themen