HashiCorp Packer und HCP Packer Release Pipelines


Bicycle

In unseren vorherigen Beiträgen zu HashiCorp Packer haben wir gezeigt, wie man mit Packer Images für AWS und Azure erstellt. In diesem Artikel werden wir etwas hinzufügen, das wir in unseren letzten Gedanken in unserem Artikel zur HCP Packer Template VM-Verteilung behandelt haben: So fördern Sie Änderungen an den Packer-Vorlagen in verschiedenen Umgebungen.

Warum wollen wir HCP Packer Release Channels verwenden?

Mit der Standardkonfiguration einer HCP Packer hcp_packer_registry Definition für die HCP Packer Registrierung werden alle Iterationen innerhalb des latest Channels erstellt. Zum Testen ist das in Ordnung, aber wir möchten mehr Kontrolle über die Verteilung unserer Vorlagen haben. Wir möchten eine Auswahl an Kanälen für unsere unterschiedlichen Umgebungen haben, z.B. einen staging Channels für unsere Staging-Umgebung und einen production Channels für unsere Produktionsumgebung zu haben. Daher müssen wir mehrere HCP Packer Registry Channels erstellen und die Verteilung unserer Vorlagen an diese Konfigurration automatisieren.

HCP Packer Template

Unsere aktuelle HCP Packer-Definition sieht wie der folgende Ausschnitt aus:

 1build {
 2
 3  sources = [ "source.amazon-ebs.eu-central-1","source.amazon-ebs.eu-east-1", "source.amazon-ebs.us-east-1", "source.amazon-ebs.us-west-1" ]
 4
 5  hcp_packer_registry {
 6  
 7    bucket_name = replace(replace(var.image_name, ".", "-"), "_","-")
 8    description = "HCP Packer Registry: ${var.image_name}-${var.ansible_play}-${var.ci_commit_ref}-${var.ci_commit_sha"
 9    bucket_labels = {
10      "owner"         = "infralovers",
11      "name"          = "${var.image_name}",
12      "play"          = "${var.ansible_play}",
13      "ci_commit_ref" = "${var.ci_commit_ref}",
14      "ci_commit_sha" = "${var.ci_commit_sha}"
15    }
16  
17    build_labels = {
18      "owner"         = "infralovers",
19      "build-time"    = "${var.timestamp}",
20      "name"          = "${var.image_name}",
21      "play"          = "${var.ansible_play}",
22      "ci_commit_ref" = "${var.ci_commit_ref}",
23      "ci_commit_sha" = "${var.ci_commit_sha}"
24    }
25  }
26
27  provisioner "shell" {
28    inline = ["while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done"]
29  }
30
31  provisioner "shell" {
32    execute_command = "echo 'packer' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
33    script          = "packer/scripts/setup.sh"
34  }
35
36  provisioner "ansible" {
37    galaxy_file             = "ansible/requirements.yaml"
38    playbook_file           = "ansible/common.yml"
39    use_proxy               = false
40    groups                  = [ "common", var.ansible_play ]
41  }
42
43  provisioner "ansible" {
44    playbook_file           = "ansible/${var.ansible_play}.yml"
45    use_proxy               = false
46    groups                  = [ "common", var.ansible_play ]
47  }
48
49  provisioner "shell" {
50    execute_command = "echo 'packer' | {{ .Vars }} sudo -S -E bash '{{ .Path }}'"
51    script          = "packer/scripts/cleanup.sh"
52  }
53
54  provisioner "cnspec" {
55    on_failure      = "continue"
56    score_threshold = 85
57    asset_name      = "${var.image_name}${var.image_tag}"
58    sudo {
59      active = true
60    }
61    annotations = {
62      Source_AMI    = "{{ .SourceAMI }}"
63      Creation_Date = "{{ .SourceAMICreationDate }}"
64    }
65  }
66}

Innerhalb dieser Definition wechselten wir von ansible-local zu ansible als Provisioner, aber mehr dazu in einem anderen Artikel, der diese Änderung verursacht hat. Außerdem verwenden wir cnspec von unseren Freunden von Mondoo, um die Sicherheit zu überprüfen unserer Bilder. Dies ist ein großartiges Tool, um die Sicherheit Ihrer Bilder zu überprüfen und wir werden dies auch in einem anderen Artikel behandeln.

HCP Packer Image Iterationen

Beim ersten Build erstellen wir die latest-Iteration. Jeder folgende Build erstellt eine neue Iteration. Alle Packer Builds erstellen nun neue Iteration dieses Images. Wir können die Iterationen in der HCP Packer Registry sehen:

HCP Packer Iterations

HCP Packer Release Channel Automatisierung

Im Moment erstellt unsere HCP Packer-Definition für die HCP Packer Registry alle Iterationen der Vorlage innerhalb des latest Kanals. Zum Testen ist das in Ordnung, aber wir möchten eine kontrollierte Verteilung unserer Vorlagen haben. Wir möchten eine Auswahl an Kanälen für unsere speziellen Umgebungen haben, z. einen staging Kanal für unsere Staging-Umgebung und einen production Kanal für zu haben unserer Produktionsumgebung. Daher müssen wir für jeden dieser Kanäle eine neue HCP Packer Registry erstellen. Wir werden das folgende Snippet verwenden, um die HCP Packer Registry für den production Kanal zu erstellen:

 1variable "hcp_image_name" {
 2  type = string
 3}
 4
 5variable "hcp_channel"{
 6  type = string
 7  default = "production"
 8}
 9
10variable "hcp_channel_source" {
11  type = string
12  default = "latest"
13}
14
15data "hcp_packer_iteration" "latest" {
16  bucket_name = var.hcp_image_name
17  channel     = var.hcp_channel_source
18}
19
20resource "hcp_packer_channel" "production" {
21  name        = var.hcp_channel
22  bucket_name = var.hcp_image_name
23}
24
25resource "hcp_packer_channel_assignment" "production" {
26  bucket_name  = var.hcp_image_name
27  channel_name = var.hcp_channel
28
29  iteration_version = data.hcp_packer_iteration.latest.incremental_version
30}

Wir verwenden diesen Coden un innerhalb einer Pipeline für dieverse Artefakte. Aus diesem Grund müssen wir hier auch vorher Zuweisungen zum aktuellen Status durchführen um dann Änderungen korrekt auslösen zu können. Wir gehen davon aus, dass die Variable IMAGE_NAME auf den Namen des Bildes gesetzt ist, das wir erstellen möchten:

1terraform import -var "hcp_image_name=${IMAGE_NAME}" hcp_packer_channel.production "${IMAGE_NAME}:production"
2
3terraform import -var "hcp_image_name=${IMAGE_NAME}" hcp_packer_channel_assignment.production "${IMAGE_NAME}:production"
4
5terraform apply -auto-approve -var "hcp_image_name=${IMAGE_NAME}"

Daraus ergibt sich dann folgender Aufruf, wenn die Variable ersetzt wurde:

1terraform import -var "hcp_image_name=ubuntu-22-04-docker" hcp_packer_channel.production "ubuntu-22-04-docker:production"
2
3terraform import -var "hcp_image_name=ubuntu-22-04-docker" hcp_packer_channel_assignment.production "ubuntu-22-04-docker:production"
4
5terraform apply -auto-approve -var "hcp_image_name=ubuntu-22-04-docker"

Diese Importbefehle sind relevant, um die vorhandene HCP Packer Registry für den production Kanal zu importieren. Der letzte Befehl adressiert die HCP Packer Registry für den production Kanal.

Dieses Snippet erstellt eine neue HCP Packer Registry für den production Kanal und weist diesem Kanal die neueste Iteration zu. Wir können dasselbe Snippet auch verwenden, um einen staging Kanal zu erstellen. Wir müssen lediglich den Namen des Kanals und den Quellkanal der HCP Packer Registry ändern.

HCP Packer Channels

Zusammenfassung

Wir haben gezeigt, wie man eine HCP Packer Registry für einen bestimmten Kanal erstellt. Damit können wir einen latest und einen production Kanal erstellen. Mit demselben Snippet können wir auch jeden anderen Kanal erstellen. Wir müssen lediglich den Namen des Kanals und den Quellkanal der HCP Packer Registry ändern. Durch dieses Setup können wir eine Release-Pipeline erstellen, die den neuesten-Kanal als Entwicklungsphase und Produktion verwendet als produktionsbereit. Zwischen diesen Phasen können wir jeden anderen Kanal erstellen, den wir benötigen, z.B. staging oder qa. Dies gibt uns viel Flexibilität bei der Erstellung einer Release-Pipeline, die unseren Anforderungen entspricht.

Wir verwenden dieses Setup innerhalb einer Pipeline, um Bilder innerhalb einer Pipeline zu erstellen und sie an verschiedene Umgebungen zu verteilen, indem wir Pipeline-bezogene Zusammenführungsanforderungen und ihren entsprechenden Zielzweig ausführen. Wenn sich eine Zusammenführungsanforderung auf den Hauptkanal bezieht, wird das zugehörige Bild auf den production Kanal hochgestuft.

Zurück Unsere Trainings entdecken

Wir sind für Sie da

Sie interessieren sich für unsere Trainings oder haben einfach eine Frage, die beantwortet werden muss? Sie können uns jederzeit kontaktieren! Wir werden unser Bestes tun, um alle Ihre Fragen zu beantworten.

Hier kontaktieren