2016-05-21 11 views
15

Ich verwende Packer mit ansible provisioner einen ami, zu bauen und die Infrastruktur, um Setup mit diesem ami als Quelle Terraforming - etwas ähnlich zu diesem Beitrag: http://www.paulstack.co.uk/blog/2016/01/02/building-an-elasticsearch-cluster-in-aws-with-packer-and-terraformWie kann ich packer Ausgabe ami ID zu Terraform Variablen automatisch verketten?

Wenn Befehl packer build pack.json erfolgreich abgeschlossen bekomme ich die Ausgabe ami id in diesem Format:

eu-central-1: ami-12345678 

in meiner Terraforming Variablen variables.tf ich die Quelle ami-ID angeben muß, Region usw. Das Problem hier ist, dass ich will sie nicht manuell angeben oder mehrere Male. Für Region (die ich vorher kenne) ist es einfach, da ich Umgebungsvariablen in beiden Situationen verwenden kann, aber was ist mit der Ausgabe ami? Gibt es eine eingebaute Möglichkeit, diese Produkte zu verketten, oder einen nicht so hacky Ansatz, es zu tun?

EDIT: Hacky Ansatz für alle, die interessiert sein könnten. In dieser Lösung bin ich grep die aws Region & ami von Packer Ausgang ing und einen regulären Ausdruck in Perl verwendet das Ergebnis in eine terraform.tfvars Datei zu schreiben:

vars=$(pwd)"/terraform.tfvars" 
packer build pack.json | \ 
    tee /dev/tty | \ 
    grep -E -o '\w{2}-\w+-\w{1}: ami-\w+' | \ 
    perl -ne '@parts = split /[:,\s]+/, $_; print "aws_amis." . $parts[0] ." = \"" . $parts[1] . "\"\n"' > ${vars} 

Antwort

14

Sie sollten Terraforms Datenquelle für aws_ami verwenden. Auf diese Weise können Sie sich auf benutzerdefinierte Tags verlassen, die Sie beim Erstellen des AMI festlegen (z. B. eine Versionsnummer oder einen Zeitstempel). In der Terraform-Konfiguration können Sie dann einfach die verfügbaren AMIs für dieses Konto und diese Region filtern, um die benötigte AMI-ID zu erhalten.

https://www.terraform.io/docs/providers/aws/d/ami.html

data "aws_ami" "nat_ami" { 
    most_recent = true 
    executable_users = ["self"] 
    filter { 
    name = "owner-alias" 
    values = ["amazon"] 
    } 
    filter { 
    name = "name" 
    values = ["amzn-ami-vpc-nat*"] 
    } 
    name_regex = "^myami-\\d{3}" 
    owners = ["self"] 
} 

HINWEIS: im Beispiel oben (aus der Dokumentation), ist die Kombination von Filtern wahrscheinlich übertrieben. Sie können sich wahrscheinlich durch ganz gut mit so etwas wie erhalten:

data "aws_ami" "image" { 
    most_recent = true 
    owners = ["self"] 
    filter {      
    name = "tag:Application"  
    values = ["my-app-name"] 
    }        
} 

output "ami_id" { 
    value = "${data.aws_ami.image.id}" 
} 

Ein weiterer Vorteil ist, dass Sie auf mehrere Regionen mit der gleichen Konfiguration und keine variable Karte bereitstellen können!

7

der „offiziellen“ Weg, der von Hashicorp empfohlen wird, ist ihren Produktatlas als "Mittelsmann" zwischen den beiden zu verwenden. Sie würden the Atlas post-processor in Packer verwenden, um die Artefakte aufzuzeichnen (AMI-IDs in Ihrem Fall) und dann the atlas_artifact resource in Terraform verwenden, um die IDs für die Verwendung in Terraform wieder zu lesen.

In diesem Fall würden Sie die IDs von der Ressource erhalten, anstatt sie mit Variablen zu übergeben.

Abgesehen von Atlas sind die anderen Optionen eher begrenzt und in einigen Fällen hacky.

Wenn Sie wollen, es zu tun ohne externe Dienste alle dann bei Ihnen mit dem local shell post-processor als eine Möglichkeit experimentieren können einen lokalen Befehl auf Ihrem Artefakt zu laufen, oder Sie können the machine-readable output verwenden, um die AMI-IDs zu extrahieren und sie in einen Schreib Variablendatei für Terraform.

Eine weitere Möglichkeit besteht darin, ein eigenes Postprozessor-Plugin zu schreiben, das mit einer bereits verwendeten Software als Alternative zu Atlas interagiert. Zum Beispiel, mit einigen meiner Kollegen schrieb ich , die wir dann später mit der Buildkite API abrufen. Dies erfordert das Schreiben von benutzerdefiniertem Code in Go.

Zum Zeitpunkt der Erstellung ist Terraform Version 0.7 noch in der Entwicklung, aber es ist geplant, eine neue Funktion zu integrieren, die eine direkte Abfrage der EC2-API für AMIs erlaubt, die (falls sie tatsächlich auf 0,7 landen) eine weitere Option erlaubt die AMI mit Packer zu markieren und dann direkt von EC2 mit diesen Tags zu finden. Dies nutzt EC2 selbst als "Mittelsmann", was vielleicht weniger umständlich ist, da es ohnehin schon als Speicher für den AMI eingesetzt wurde.

+0

Schön, werde alle diese Optionen überprüfen und mit Rückmeldung kommen! – fips

+0

Okay, das Schreiben eines Postprozessors scheint die beste Option zu sein - generisch/erweiterbar. Ich denke, man sollte keinen externen Dienst (Atlas/aws) suchen müssen, da die Ami-ID bereits lokal verfügbar ist. Für den Moment habe ich eine Hacky-Lösung (siehe aktualisierte Frage) verwendet, bis ich einen Post-Prozessor schreibe, der deinem ähnlich ist. Danke, dass du 'packer-buildkite' geteilt hast. :-) – fips