One place for hosting & domains

      Packer

      How to Deploy a Packer Image with Terraform


      Both the Packer and Terraform tools by HashiCorp stand out for remarkable infrastructure-automating. Despite some overlap, the tools have distinct and complimentary features. This makes them an effective pair, with Packer used to create images that Terraform then deploys as a complete infrastructure.

      Learn more about Packer in our
      Using the Linode Packer Builder to Create Custom Images guide. Discover how you can leverage Terraform in our
      Beginner’s Guide to Terraform.

      In this tutorial, find out how to use Packer and Terraform together to deploy Linode instances. The tutorial uses the Linode Terraform provider to deploy several instances based on a Linode image built with Packer.

      Before You Begin

      1. If you have not already done so, create a Linode account and Compute Instance. See our
        Getting Started with Linode and
        Creating a Compute Instance guides.

      2. Follow our
        Setting Up and Securing a Compute Instance guide to update your system. You may also wish to set the timezone, configure your hostname, create a limited user account, and harden SSH access.

      Note

      This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, see the
      Users and Groups guide.

      How to Install the Prerequisites

      To get started, install both Packer and Terraform on the same system. Below you can find links to installation guides for the two tools, as well as steps covering most Linux operating systems.

      Installing Packer

      Packer’s installation process varies substantially depending on your operating system. Refer to the
      official installation guide for instructions if your system is not covered here.

      Debian / Ubuntu

      sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
      curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -\
      sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
      sudo apt-get update && sudo apt-get install packer

      AlmaLinux / CentOS Stream / Rocky Linux

      sudo yum install -y yum-utils
      sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
      sudo yum -y install packer

      Fedora

      sudo dnf install -y dnf-plugins-core
      sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
      sudo dnf -y install packer

      Afterward, verify your installation and display the installed version with the following command:

      1.8.4

      Installing Terraform

      Terraform’s installation process also varies depending on your operating system. Refer to HashiCorp’s
      official documentation on installing the Terraform CLI for systems that are not covered here. You can also refer to the section on installing Terraform in our guide
      Use Terraform to Provision Linode Environments.

      Debian / Ubuntu

      sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
      wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
      echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
      sudo apt update && sudo apt install terraform

      AlmaLinux / CentOS Stream / Rocky Linux

      sudo yum install -y yum-utils
      sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
      sudo yum -y install terraform

      Fedora

      sudo dnf install -y dnf-plugins-core
      sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
      sudo dnf -y install terraform

      Afterward, verify your installation with:

      Terraform v1.3.3
      on linux_amd64

      How to Build a Packer Image

      Packer automates the creation of machine images. These images are helpful when looking to streamline your process for provisioning infrastructure. Such images give you a consistent basis for deploying instances.

      Moreover, images are much more efficient. Rather than executing a series of installations and commands with each provisioned instance, the provisioning tool can deploy ready-made images.

      The examples in this tutorial uses a Linode image built with Packer. Linode has a builder available for Packer, which lets you put together images specifically for a Linode instance.

      To do so, follow along with our guide on
      Using the Linode Packer Builder to Create Custom Images. By the end, you should have a Packer-built image on your Linode account.

      The remaining steps in this tutorial should work no matter what kind of image you built following the guide linked above. However, the Packer image used in the examples to follow has the label packer-linode-image-1, runs on an Ubuntu 20.04 base, and has NGINX installed.

      How to Configure Terraform

      Terraform focuses on automating the provisioning process, allowing you to deploy your infrastructure entirely from code.

      To learn more about deploying Linode instances with Terraform, see our tutorial on how to
      Use Terraform to Provision Linode Environments.

      This tutorial covers a similar series of steps, but specifically demonstrates how you can work with custom Linode images.

      Before moving ahead, create a directory for your Terraform scripts, and change that to your working directory. This tutorial uses the linode-terraform directory in the current user’s home directory:

      mkdir ~/linode-terraform
      cd ~/linode-terraform

      The rest of the tutorial assumes you are working out of this directory.

      Setting Up the Linode Provider

      Terraform’s providers act as abstractions of APIs, giving Terraform an interface for working with various resources on host platforms.

      Linode has its own Terraform provider, which you can learn more about from its Terraform
      provider registry page.

      To use the provider, you just need a couple of short blocks in a Terraform script.

      Create a new Terraform file named packer-linode.tf, which acts as the base for this tutorial’s Terraform project:

      Give it the contents shown here:

      File: packer-linode.tf
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      terraform {
        required_providers {
          linode = {
            source = "linode/linode"
            version = "1.29.3"
          }
        }
      }
      provider "linode" {
        token = var.token
      }

      The terraform block starts the project by indicating its required providers (e.g. Linode). The provider block then starts the Linode provider. The token argument allows the provider to authenticate its connection to the Linode API.

      When done, press CTRL+X to exit nano, Y to save, and Enter to confirm.

      Assigning Terraform Variables

      Above, you can see that the token value for the Linode provider uses the var.token variable. Although not required, variables make Terraform scripts much more adaptable and manageable.

      This tutorial handles variables using two files.

      1. First, create a variables.tf file:

        Now fill it with the contents shown below. This file defines all the variables for the Terraform project. Some of these variables have default values, which Terraform automatically uses if not otherwise assigned. Other variables need to be assigned, which you can see in the next file.

        File: variables.tf
         1
         2
         3
         4
         5
         6
         7
         8
         9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        
        variable "token" {
          description = "The Linode API Personal Access Token."
        }
        variable "password" {
          description = "The root password for the Linode instances."
        }
        variable "ssh_key" {
          description = "The location of an SSH key file for use on the Linode instances."
          default = "~/.ssh/id_rsa.pub"
        }
        variable "node_count" {
          description = "The number of instances to create."
          default = 1
        }
        variable "region" {
          description = "The name of the region in which to deploy instances."
          default = "us-east"
        }
        variable "image_id" {
          description = "The ID for the Linode image to be used in provisioning the instances"
          default = "linode/ubuntu20.04"
        }

        When done, press CTRL+X to exit nano, Y to save, and Enter to confirm.

      2. Now create a terraform.tfvars file:

        This file, with the .tfvars ending, is a place for assigning variable values. Give the file the contents below, replacing the values in arrow brackets (<...>) with your actual values:

        File: terraform.tfvars
        1
        2
        3
        4
        
        token = "<LinodeApiToken>"
        password = "<RootPassword>"
        node_count = 2
        image_id = "private/<LinodeImageId>"

        The <LinodeApiToken> needs to be an API token associated with your Linode account. You can follow our
        Get an API Access Token guide to generate a personal access token. Be sure to give the token “Read/Write” permissions.

        Above, you can see a value of private/<LinodeImageId> for the image_id. This value should match the image ID for the Linode image you created with Packer. All custom Linode images are prefaced with private/ and conclude with the image’s ID. In these examples, private/17691867 is assumed to be the ID for the Linode image built with Packer.

        There are two main ways to get your image ID:

        • The Linode image ID appears at the end of the output when you use Packer to create the image. For instance, in the guide on creating a Linode image with Packer linked above, you can find the output:

          ==> Builds finished. The artifacts of successful builds are:
          --> linode.example-linode-image: Linode image: packer-linode-image-1 (private/17691867)
        • The Linode API has an endpoint for listing available images. The list includes your custom images if you call it with your API token.

          You can use a cURL command to list all images available to you, public and private. Replace $LINODE_API_TOKEN with your Linode API token:

          curl -H "Authorization: Bearer $LINODE_API_TOKEN" \https://api.linode.com/v4/images

          The output can be overwhelming in the command line, so you may want to use another tool to prettify the JSON response. This has been done with the result shown here:

          {
              "pages": 1,
              "data": [{
                  "id": "private/17691867",
                  "label": "packer-linode-image-1",
                  "description": "Example Packer Linode Image",
                  // [...]

        When done, press CTRL+X to exit nano, Y to save, and Enter to confirm.

      Defining the Linode Resource

      The next step for the Terraform script is to define the actual resource to be provisioned. In this case, the script needs to provision Linode instances, which can be done using the linode_instance resource.

      Open the packer-linode.tf file created earlier and add the details shown here to the end:

      File: packer-linode.tf
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      
      resource "linode_instance" "packer_linode_instance" {
        count = var.node_count
        image = var.image_id
        label = "packer-image-linode-${count.index + 1}"
        group = "packer-image-instances"
        region = var.region
        type = "g6-standard-1"
        authorized_keys = [ chomp(file(var.ssh_key)) ]
        root_pass = var.password
        connection {
          type = "ssh"
          user = "root"
          password = var.password
          host = self.ip_address
        }
        provisioner "remote-exec" {
          inline = [
            # Update the system.
            "apt-get update -qq",
            # Disable password authentication; users can only connect with an SSH key.
            "sed -i '/PasswordAuthentication/d' /etc/ssh/sshd_config",
            "echo \"PasswordAuthentication no\" >> /etc/ssh/sshd_config",
            # Check to make sure NGINX is running.
            "systemctl status nginx --no-pager"
          ]
        }
      }

      And with that, the Terraform project is ready to provision two Linode instances based on your Packer-built image. Most of the configuration details for the resource block are managed by variables. So you shouldn’t need to fiddle with much of the resource block to adjustment things like the number of instances to provision.

      The remote-exec provisioner, and specifically the inline list within it, is where much of the customization comes in. This block defines shell commands to be executed on the newly provisioned instance. The commands here are relatively simple, but this provisioner can give you fine-grained control of operations on the instance.

      How to Provision a Packer Image with Terraform

      From here, a handful of Terraform commands are all you need to provision and manage Linode instances from the Packer-built image.

      First, Terraform needs to run some initialization around the script. This installs any prerequisites, specifically the linode provider in this example, and sets up Terraform’s lock file.

      Running Terraform’s plan command is also good practice. Here, Terraform checks your script for immediate errors and provides an outline of the projected resources to deploy. You can think of it as a light dry run.

      Review the plan, and when ready, provision your instances with the apply command. This may take several minutes to process, depending on your systems and the number of instances being deployed.

      linode_instance.packer_linode_instance[0] (remote-exec): Connected!
      linode_instance.packer_linode_instance[0] (remote-exec): ● nginx.service - A high performance web server and a reverse proxy server
      linode_instance.packer_linode_instance[0] (remote-exec):      Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
      linode_instance.packer_linode_instance[0] (remote-exec):      Active: active (running) since Thu 2022-10-27 15:56:42 UTC; 9s ago
      [...]
      
      Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

      In the future, whenever you want to remove the instances created with Terraform, you can use the destroy command from within your Terraform script directory.

      As with the apply command, you get a preview of the instances and are asked to confirm before the instances are destroyed.

      Conclusion

      This tutorial outlined how to use Terraform to deploy Linode instances built with a Packer image. This arrangement provides an efficient setup for provisioning and managing Linode instances. Terraform streamlines the process of provisioning infrastructure, and it is made even more efficient using pre-built images from Packer.

      The example covered in this tutorial is fairly simple. But the setup can be readily adapted and expanded on to deploy more robust and complex infrastructures.

      More Information

      You may wish to consult the following resources for additional information
      on this topic. While these are provided in the hope that they will be
      useful, please note that we cannot vouch for the accuracy or timeliness of
      externally hosted materials.



      Source link

      Erstellen eines Hashicorp-Vault-Servers mit Packer und Terraform in DigitalOcean [Schnellstart]


      Einführung

      Vault von Hashicorp ist ein Open-Source-Tool, um Geheimnisse und sensible Daten in dynamischen Cloud-Umgebungen sicher zu speichern. Packer und Terraform, ebenfalls von Hashicorp entwickelt, können zusammen verwendet werden, um Images von Vault zu kreieren und bereitzustellen.

      In diesem Tutorial erstellen Sie mit Packer einen unveränderlichen Snapshot des Systems mit installiertem Vault und dirigieren dessen Bereitstellung mit Terraform.

      Eine ausführlichere Version dieses Tutorials finden Sie in Erstellen eines Hashicorp Vault-Servers mit Packer und Terraform in DigitalOcean.

      Voraussetzungen

      • Auf Ihrem lokalen Rechner installierter Packer. Lesen Sie für Anweisungen die offizielle Dokumentation.
      • Auf Ihrem lokalen Rechner installiertes Terraform. Lesen Sie die offizielle Dokumentation für eine Anleitung.
      • Ein persönliches Zugriffstoken (API-Schlüssel) mit Lese- und Schreibberechtigungen für Ihr DigitalOcean-Konto. Besuchen Sie Erstellen eines persönlichen Zugriffstokens, um ein Token zu erstellen.
      • Einen SSH-Schlüssel, den Sie zur Authentifizierung mit den bereitgestellten Vault Droplets verwenden, die auf Ihrem lokalen Rechner verfügbar sind und Ihrem DigitalOcean-Konto hinzugefügt werden. Sie benötigen auch dessen Fingerabdruck, den Sie von der Security-Seite Ihres Kontos nach dem Erstellen kopieren können. Besuchen Sie die DigitalOcean-Dokumentation für detaillierte Anweisungen oder das Tutorial Einrichten von SSH-Schlüsseln.

      Schritt 1 — Erstellen einer Packer-Vorlage

      Erstellen und wechseln Sie in das Verzeichnis ~/vault-orchestration, um Ihre Vault-Dateien zu speichern:

      • mkdir ~/vault-orchestration
      • cd ~/vault-orchestration

      Erstellen Sie separate Verzeichnisse für die Packer- und Terraform-Konfiguration, indem Sie Folgendes ausführen:

      Navigieren Sie zum Verzeichnis Packer:

      Verwenden von Vorlagenvariablen

      Erstellen Sie eine variables.json in Ihrem packer-Unterverzeichnis, um Ihre privaten variablen Daten zu speichern:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/variables.json

      {
        "do_token": "your_do_api_key",
        "base_system_image": "ubuntu-18-04-x64",
        "region": "nyc3",
        "size": "s-1vcpu-1gb"
      }
      

      Sie verwenden diese Variablen in der Vorlage, die Sie erstellen. Sie können die Werte Basisbild, Region und Droplet-Größe entsprechend den developer docs bearbeiten.

      Ersetzen Sie your_do_api_key durch Ihren API-Schlüssel. Speichern und schließen Sie dann die Datei.

      Erstellen von Builders und Provisioners

      Erstellen Sie Ihre Packer-Vorlage für Vault in einer Datei namens template.json:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/template.json

      {
         "builders": [{
             "type": "digitalocean",
             "api_token": "{{user `do_token`}}",
             "image": "{{user `base_system_image`}}",
             "region": "{{user `region`}}",
             "size": "{{user `size`}}",
             "ssh_username": "root"
         }],
         "provisioners": [{
             "type": "shell",
             "inline": [
                 "sleep 30",
                 "sudo apt-get update",
                 "sudo apt-get install unzip -y",
                 "curl -L https://releases.hashicorp.com/vault/1.3.2/vault_1.3.2_linux_amd64.zip -o vault.zip",
                 "unzip vault.zip",
                 "sudo chown root:root vault",
                 "mv vault /usr/local/bin/",
                 "rm -f vault.zip"
             ]
      }]
      }
      

      Sie definieren einen einfachen digitalocean-Builder. Packer erstellt ein temporäres Droplet der definierten Größe, des definierten Bilds und der definierten Region, wobei der bereitgestellte API-Schlüssel verwendet wird.

      Der Provisioner stellt über SSH eine Verbindung mit dem angegebenen Benutzernamen her und führt nacheinander alle definierten Provisioners aus, bevor ein DigitalOcean-Snapshot aus dem Droplet erstellt und gelöscht wird.

      Es ist eine Art Shell, die die angegebenen Befehle auf das Ziel ausführt. Die Befehle in der Vorlage warten 30 Sekunden, bis das System hochgefahren ist. Anschließend wird Vault 1.3.2 heruntergeladen und entpackt. Konsultieren Sie die offizielle Vault-Downloadseite, um die aktuellste Version für Linux zu erhalten.

      Speichern und schließen Sie die Datei.

      Überprüfen Sie die Gültigkeit Ihrer Vorlage:

      • packer validate -var-file=variables.json template.json

      Sie sehen die folgende Ausgabe:

      Output

      Template validated successfully.

      Schritt 2 — Erstellen des Snapshots

      Erstellen Sie Ihren Snapshot mit dem Packer-Befehl build:

      • packer build -var-file=variables.json template.json

      Sie sehen eine Menge Ausgabe, die so aussehen wird:

      Output

      digitalocean: output will be in this color. ==> digitalocean: Creating temporary ssh key for droplet... ==> digitalocean: Creating droplet... ==> digitalocean: Waiting for droplet to become active... ==> digitalocean: Using ssh communicator to connect: ... ==> digitalocean: Waiting for SSH to become available... ==> digitalocean: Connected to SSH! ==> digitalocean: Provisioning with shell script: /tmp/packer-shell035430322 ... ==> digitalocean: % Total % Received % Xferd Average Speed Time Time Time Current ==> digitalocean: Dload Upload Total Spent Left Speed digitalocean: Archive: vault.zip ==> digitalocean: 100 45.5M 100 45.5M 0 0 154M 0 --:--:-- --:--:-- --:--:-- 153M digitalocean: inflating: vault ==> digitalocean: Gracefully shutting down droplet... ==> digitalocean: Creating snapshot: packer-1581537927 ==> digitalocean: Waiting for snapshot to complete... ==> digitalocean: Destroying droplet... ==> digitalocean: Deleting temporary ssh key... Build 'digitalocean' finished. ==> Builds finished. The artifacts of successful builds are: --> digitalocean: A snapshot was created: 'packer-1581537927' (ID: 58230938) in regions '...'

      Die letzte Zeile enthält den Namen des Snapshots (wie packer-1581537927) und seine ID in Klammern, wie hier hervorgehoben. Notieren Sie sich die ID des Snapshots, da Sie diese im nächsten Schritt benötigen.

      Falls der Build-Prozess durch Fehler in der API fehlschlägt, warten Sie einige Minuten und versuchen Sie es dann erneut.

      Schritt 3 — Schreiben der Terraform-Konfiguration

      Navigieren Sie zum Unterverzeichnis terraform:

      • cd ~/vault-orchestration/terraform

      Erstellen Sie eine Datei namens do-provider.tf, um den Provider zu speichern:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/do-provider.tf

      variable "do_token" {
      }
      
      variable "ssh_fingerprint" {
      }
      
      variable "instance_count" {
      default = "1"
      }
      
      variable "do_snapshot_id" {
      }
      
      variable "do_name" {
      default = "vault"
      }
      
      variable "do_region" {
      }
      
      variable "do_size" {
      }
      
      variable "do_private_networking" {
      default = true
      }
      
      provider "digitalocean" {
      token = var.do_token
      }
      

      Diese Datei stellt dem digitalocean-Provider einen API-Schlüssel zur Verfügung. Um die Werte dieser Variablen anzugeben, erstellen Sie eine Variablendefinitionsdatei, ähnlich wie bei Packer. Der Dateiname muss entweder auf .tfvars oder auf .tfvars.json enden.

      Speichern und schließen Sie die Datei.

      Erstellen Sie eine Variablendefinitionsdatei:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/definitions.tf

      do_token         = "your_do_api_key"
      ssh_fingerprint  = "your_ssh_key_fingerprint"
      do_snapshot_id   = your_do_snapshot_id
      do_name          = "vault"
      do_region        = "nyc3"
      do_size          = "s-1vcpu-1gb"
      instance_count   = 1
      

      Ersetzen Sie your_do_api_key, your_ssh_key_fingerprint und your_do_snapshot_id (die Snapshot-ID, die Sie im vorherigen Schritt notiert haben). Die Parameter do_region und do_size müssen die gleichen Werte wie in der Packer-Variablendatei haben.

      Speichern und schließen Sie die Datei.

      Erstellen Sie die folgende Datei, um die Bereitstellungskonfiguration des Vault-Snapshots zu speichern:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/deployment.tf

      resource "digitalocean_droplet" "vault" {
      count              = var.instance_count
      image              = var.do_snapshot_id
      name               = var.do_name
      region             = var.do_region
      size               = var.do_size
      private_networking = var.do_private_networking
      ssh_keys = [
        var.ssh_fingerprint
      ]
      }
      
      output "instance_ip_addr" {
      value = {
        for instance in digitalocean_droplet.vault:
        instance.id => instance.ipv4_address
      }
      description = "The IP addresses of the deployed instances, paired with their IDs."
      }
      

      Sie definieren eine einzelne resource vom Typ digitalocean_droplet namens vault. Sie legen ihre Parameter entsprechend den Variablenwerten fest und fügen (mit seinem Fingerabdruck) einen SSH-Schlüssel von Ihrem DigitalOcean-Konto zur Droplet-Ressource hinzu. Sie output die IP-Adressen aller neu erstellten Instanzen an die Konsole aus.

      Speichern und schließen Sie die Datei.

      Initialisieren Sie das Verzeichnis als Terraform-Projekt:

      Sie sehen die folgende Ausgabe:

      Output

      Initializing the backend... Initializing provider plugins... The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, it is recommended to add version = "..." constraints to the corresponding provider blocks in configuration, with the constraint strings suggested below. * provider.digitalocean: version = "~> 1.14" Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.

      Schritt 4 — Bereitstellung von Vault mit Terraform

      Testen Sie die Gültigkeit Ihrer Konfiguration:

      Sie sehen die folgende Ausgabe:

      Output

      Success! The configuration is valid.

      Führen Sie den Befehl plan aus, um zu sehen, was Terraform bei der Bereitstellung der Infrastruktur versucht:

      • terraform plan -var-file="definitions.tfvars"

      Die Ausgabe wird ähnlich sein wie:

      Output

      Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.vault[0] will be created + resource "digitalocean_droplet" "vault" { ... } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.

      Führen Sie den Plan aus:

      • terraform apply -var-file="definitions.tfvars"

      Das Droplet wird die Bereitstellung abschließen und Sie sehen eine Ausgabe, die etwa folgendermaßen aussieht:

      Output

      An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + digitalocean_droplet.vault-droplet ... Plan: 1 to add, 0 to change, 0 to destroy. ... digitalocean_droplet.vault-droplet: Creating... ... Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: instance_ip_addr = { "181254240" = "your_new_server_ip" }

      Schritt 5 — Verifizieren Ihres bereitgestellten Droplet

      Führen Sie Folgendes aus, um sich mit Ihrem neuen Droplet zu verbinden:

      Nach der Anmeldung führen Sie Vault aus mit:

      Sie sehen die entsprechende “Hilfe”-Ausgabe:

      Output

      Usage: vault <command> [args] Common commands: read Read data and retrieves secrets write Write data, configuration, and secrets delete Delete secrets and configuration list List data or secrets login Authenticate locally agent Start a Vault agent server Start a Vault server status Print seal and HA status unwrap Unwrap a wrapped secret Other commands: audit Interact with audit devices auth Interact with auth methods debug Runs the debug command kv Interact with Vault's Key-Value storage lease Interact with leases namespace Interact with namespaces operator Perform operator-specific tasks path-help Retrieve API help for paths plugin Interact with Vault plugins and catalog policy Interact with policies print Prints runtime configurations secrets Interact with secrets engines ssh Initiate an SSH session token Interact with tokens

      Zusammenfassung

      Sie verfügen jetzt über ein automatisiertes System zur Bereitstellung von Hashicorp Vault auf DigitalOcean Droplets mit Unterstützung von Terraform und Packer. Um Vault zu verwenden, müssen Sie es initialisieren und weiter konfigurieren. Anweisungen hierzu finden Sie in den Offiziellen Dokumenten.

      Weitere Tutorials zur Verwendung von Terraform finden Sie auf der Terraform Content Page.



      Source link

      Erstellen eines Hashicorp Vault Server unter Verwendung von Packer und Terraform auf DigitalOcean


      Der Autor wählte den Free and Open Source Fund, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Vault von Hashicorp ist ein Open Source Tool, um Zugangsdaten und sensible Daten in dynamischen Cloud-Umgebungen sicher zu speichern. Es bietet eine starke Datenverschlüsselung, identitätsbasierten Zugriff unter Verwendung von benutzerdefinierten Richtlinien, geheimes Leasen und Widerrufen sowie ein ausführliches Auditprotokoll, das fortlaufend aufgezeichnet wird. Vault bietet zudem eine HTTP-API und ist damit die ideale Wahl für die Speicherung von Anmeldeinformationen in verstreuten serviceorientierten Implementierungen wie Kubernetes.

      Packer und Terraform, ebenfalls von Hashicorp entwickelt, können zusammen verwendet werden, um Bilder von Vault zu kreieren und bereitzustellen. Innerhalb dieses Workflows können Entwickler Packer verwenden, um unveränderliche Bilder für verschiedene Plattformen aus einer einzelnen Konfigurationsdatei zu erstellen, die angibt, was das Bild enthalten soll. Terraform stellt dann so viele angepasste Exemplare der erstellten Bilder bereit, wie benötigt werden.

      In diesem Tutorial erstellen Sie mit Packer einen unveränderlichen Snapshot des Systems mit installiertem Vault und orchestrieren dessen Bereitstellung mit Terraform. Zum Schluss verfügen Sie über ein automatisiertes System zur Bereitstellung von Vault. So können Sie sich anstatt auf den zugrunde liegenden Installations- und Bereitstellungsprozess auf die Arbeit mit Vault selbst konzentrieren.

      Voraussetzungen

      • Auf Ihrem lokalen Rechner installierter Packer. Lesen Sie für Anweisungen die Offizielle Dokumentation.
      • Auf Ihrem lokalen Rechner installiertes Terraform. Lesen Sie die Offizielle Dokumentation für eine Anleitung.
      • Einen persönlichen Zugangs-Token (API-Schlüssel) mit Lese- und Schreibberechtigungen für Ihr DigitalOcean-Konto. Um einen solchen zu erstellen, besuchen Sie Erstellen eines persönlichen Zugangs-Tokens bei den Dokumenten.
      • Einen SSH-Schlüssel, den Sie zur Authentifizierung mit den bereitgestellten Vault Droplets verwenden, die auf Ihrem lokalen Rechner verfügbar sind und Ihrem DigitalOcean-Konto hinzugefügt werden. Sie benötigen auch dessen Fingerabdruck, den Sie von der Sicherheitsseite Ihres Kontos nach dem Erstellen kopieren können. Besuchen Sie die DigitalOcean Dokumentation für detaillierte Anweisungen oder das Tutorial Einrichten von SSH-Schlüsseln.

      Schritt 1 — Erstellen einer Packer-Vorlage

      In diesem Schritt schreiben Sie eine Packer-Konfigurationsdatei, die sogenannte Vorlage, die Packer anweist, wie ein Bild mit vorinstalliertem Vault erstellt werden kann. Sie schreiben die Konfiguration im Format JSON, einem gängigen, visuell lesbaren Dateiformat.

      Für die Zwecke dieses Tutorials speichern Sie alle Dateien unter ~/vault-orchestration. Erstellen Sie das Verzeichnis, indem Sie den folgenden Befehl ausführen:

      • mkdir ~/vault-orchestration

      Navigieren Sie dorthin:

      Sie speichern die Konfigurationsdateien für Packer und Terraform separat in verschiedenen Unterverzeichnissen. Erstellen Sie diese mit dem folgenden Befehl:

      Da Sie zuerst mit Packer arbeiten, navigieren Sie in dessen Verzeichnis:

      Verwenden von Vorlagenvariablen

      Die Speicherung von privaten Daten und Zugangsdaten für Applikationen in einer separaten Variablendatei ist der ideale Weg, diese aus Ihrer Vorlage herauszuhalten. Beim Erstellen des Bildes ersetzt Packer die angegebenen Variablen mit ihren Werten. Die Hartkodierung von geheimen Datenwerten in Ihre Vorlage ist ein Sicherheitsrisiko, insbesondere wenn sie mit Teammitgliedern geteilt oder auf öffentlichen Websites wie GitHub veröffentlicht werden soll.

      Sie speichern diese im Unterverzeichnis packer, in einer Datei namens variables.json​​​​​​. Erstellen Sie sie mit Ihrem bevorzugten Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/variables.json

      {
          "do_token": "your_do_api_key",
          "base_system_image": "ubuntu-18-04-x64",
          "region": "nyc3",
          "size": "s-1vcpu-1gb"
      }
      

      Die Variablendatei besteht aus einem JSON-Wörterbuch, das die Variablennamen ihren Werten zuordnet. Sie verwenden diese Variablen in der Vorlage, die Sie erstellen. Wenn Sie möchten, können Sie die Werte Basisbild, Region und Droplet-Größe entsprechend den Entwicklerdokumenten bearbeiten.

      Denken Sie daran, your_do_api_key durch Ihren API-Schlüssel zu ersetzen, den Sie als Teil der Voraussetzungen erstellt haben. Speichern und schließen Sie dann die Datei.

      Erstellen von Buildern und Provisionern

      Mit der fertigen Variablendatei erstellen Sie nun die Packer-Vorlage selbst.

      Sie speichern die Packer-Vorlage für Vault in einer Datei namens template.json. Erstellen Sie sie mit Ihrem Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/packer/template.json

      {
           "builders": [{
               "type": "digitalocean",
               "api_token": "{{user `do_token`}}",
               "image": "{{user `base_system_image`}}",
               "region": "{{user `region`}}",
               "size": "{{user `size`}}",
               "ssh_username": "root"
           }],
           "provisioners": [{
               "type": "shell",
               "inline": [
                   "sleep 30",
                   "sudo apt-get update",
                   "sudo apt-get install unzip -y",
                   "curl -L https://releases.hashicorp.com/vault/1.3.2/vault_1.3.2_linux_amd64.zip -o vault.zip",
                   "unzip vault.zip",
                   "sudo chown root:root vault",
                   "mv vault /usr/local/bin/",
                   "rm -f vault.zip"
               ]
          }]
      }
      

      In der Vorlage definieren Sie Arrays von Buildern und Provisionern. Builder weisen Packer an, wie das Systembild (je nach Typ) zu erstellen ist und wo es gespeichert werden soll, während Provisioner eine Reihe von Aktionen enthalten, die Packer auf dem System durchführen muss, bevor es in ein unveränderliches Bild umgewandelt wird, wie z. B. die Installation oder Konfiguration von Software. Ohne Provisioner würden Sie zum Schluss ein unangetastetes Bild des Basissystems erhalten. Sowohl Builder als auch Provisioner stellen Parameter zur weiteren Anpassung des Workflows zur Verfügung.

      Sie definieren zuerst einen einzelnen Builder des Typs digitalocean, d. h. dass Packer beim Befehl zur Erstellung eines Bildes die bereitgestellten Parameter verwendet, um mit dem bereitgestellten API-Schlüssel ein temporäres Droplet der definierten Größe zu erstellen, mit dem angegebenen Basissystembild und der angegebenen Region. Das Format zum Abrufen einer Variablen ist {{user 'variable_name'}}, wobei der hervorgehobene Teil der Name ist.

      Wenn das provisorische Droplet bereitgestellt ist, stellt der Provisioner eine Verbindung über SSH mit dem angegebenen Benutzernamen her und führt nacheinander alle definierten Provisioner aus, bevor ein DigitalOcean Snapshot aus dem Droplet erstellt und es gelöscht wird.

      Es handelt sich um eine Shell, die die angegebenen Befehle auf dem Ziel ausführt. Die Befehle können entweder inline als Array von Zeichenfolgen angegeben oder in getrennten Skriptdateien definiert werden, wenn das Einfügen in die Vorlage aufgrund der Größe zu umständlich wird. Die Befehle in der Vorlage warten 30 Sekunden, bis das System hochgefahren ist. Anschließend wird Vault 1.3.2 heruntergeladen und entpackt. Konsultieren Sie die Offizielle Vault Downloadseite und ersetzen Sie den Link in den Befehlen durch eine neuere Version für Linux, wenn verfügbar.

      Wenn Sie fertig sind, speichern und schließen Sie die Datei.

      Um die Gültigkeit Ihrer Vorlage zu überprüfen, führen Sie den folgenden Befehl aus:

      • packer validate -var-file=variables.json template.json

      Packer akzeptiert einen Pfad zur Variablendatei über das Argument -var-file.

      Sie sehen die folgende Ausgabe:

      Output

      Template validated successfully.

      Sollten Sie eine Fehlermeldung erhalten, gibt Packer genau an, wo dieser aufgetreten ist, sodass Sie diesen korrigieren können.

      Nun haben Sie eine funktionierende Vorlage, die ein Bild mit installiertem Vault erzeugt, wobei Ihr API-Schlüssel und andere Parameter in einer separaten Datei definiert sind. Jetzt können Sie Packer aufrufen und den Snapshot erstellen.

      Schritt 2 — Erstellen des Snapshot

      In diesem Schritt erstellen Sie einen DigitalOcean Snapshot aus Ihrer Vorlage mit dem Packerbefehl build.

      Um Ihren Snapshot zu erstellen, führen Sie den folgenden Befehl aus:

      • packer build -var-file=variables.json template.json

      Die Ausführung des Befehls nimmt etwas Zeit in Anspruch. Sie sehen eine Menge Ausgabe, die so aussehen wird:

      Output

      digitalocean: output will be in this color. ==> digitalocean: Creating temporary ssh key for droplet... ==> digitalocean: Creating droplet... ==> digitalocean: Waiting for droplet to become active... ==> digitalocean: Using ssh communicator to connect: ... ==> digitalocean: Waiting for SSH to become available... ==> digitalocean: Connected to SSH! ==> digitalocean: Provisioning with shell script: /tmp/packer-shell035430322 ... ==> digitalocean: % Total % Received % Xferd Average Speed Time Time Time Current ==> digitalocean: Dload Upload Total Spent Left Speed digitalocean: Archive: vault.zip ==> digitalocean: 100 45.5M 100 45.5M 0 0 154M 0 --:--:-- --:--:-- --:--:-- 153M digitalocean: inflating: vault ==> digitalocean: Gracefully shutting down droplet... ==> digitalocean: Creating snapshot: packer-1581537927 ==> digitalocean: Waiting for snapshot to complete... ==> digitalocean: Destroying droplet... ==> digitalocean: Deleting temporary ssh key... Build 'digitalocean' finished. ==> Builds finished. The artifacts of successful builds are: --> digitalocean: A snapshot was created: 'packer-1581537927' (ID: 58230938) in regions '...'

      Packer protokolliert alle Schritte, die es beim Erstellen Ihrer Vorlage vorgenommen hat. Die letzte Zeile enthält den Namen des Snapshots (wie packer-1581537927) und seine rot markierte ID in Klammern. Notieren Sie die ID Ihres Snapshots, da Sie diese im nächsten Schritt benötigen.

      Falls der Build-Prozess durch Fehler in der API fehlschlägt, warten Sie einige Minuten und versuchen Sie es dann erneut.

      Sie haben nun einen DigitalOcean Snapshot entsprechend Ihrer Vorlage erstellt. Auf dem Snapshot ist Vault vorinstalliert und Sie können nun Droplets mit ihm als Systembild bereitstellen. Im nächsten Schritt schreiben Sie die Terraform-Konfiguration zur Automatisierung solcher Bereitstellungen.

      Schritt 3 — Schreiben der Terraform-Konfiguration

      In diesem Schritt schreiben Sie die Terraform-Konfiguration zur Automatisierung der Droplet-Bereitstellungen des Snapshots, der den gerade mit Packer erstellten Vault enthält.

      Bevor Sie die eigentliche Terraform-Konfiguration zur Bereitstellung von Vault aus dem zuvor erstellten Snapshot schreiben, müssen Sie hierzu zunächst den DigitalOcean-Provider konfigurieren. Navigieren Sie zum Terraform-Unterverzeichnis, indem Sie Folgendes ausführen:

      • cd ~/vault-orchestration/terraform

      Erstellen Sie dann eine Datei namens do-provider.tf, in der Sie den Provider speichern:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/do-provider.tf

      variable "do_token" {
      }
      
      variable "ssh_fingerprint" {
      }
      
      variable "instance_count" {
        default = "1"
      }
      
      variable "do_snapshot_id" {
      }
      
      variable "do_name" {
        default = "vault"
      }
      
      variable "do_region" {
      }
      
      variable "do_size" {
      }
      
      variable "do_private_networking" {
        default = true
      }
      
      provider "digitalocean" {
        token = var.do_token
      }
      

      Diese Datei gibt Parametervariablen an und verleiht dem digitalocean-Provider einen API-Schlüssel. Sie verwenden diese Variablen später in Ihrer Terraform-Vorlage, aber Sie müssen zuerst deren Werte festlegen. Zu diesem Zweck unterstützt Terraform die Angabe der variablen Werte in einer Variablendefinitionsdatei, ähnlich wie bei Packer. Der Dateiname muss entweder in .tfvars oder .tfvars.json enden. Sie übergeben diese Datei später an Terraform mit dem Argument -var-file.

      Speichern und schließen Sie die Datei.

      Erstellen Sie eine Variablendefinitionsdatei mit dem Namen definitions.tfvars mithilfe Ihres Texteditors:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/definitions.tf

      do_token         = "your_do_api_key"
      ssh_fingerprint  = "your_ssh_key_fingerprint"
      do_snapshot_id   = your_do_snapshot_id
      do_name          = "vault"
      do_region        = "nyc3"
      do_size          = "s-1vcpu-1gb"
      instance_count   = 1
      

      Ersetzen Sie your_do_api_key, your_ssh_key_fingerprint und your_do_snapshot_id jeweils mit dem API-Schlüssel Ihres Kontos, dem Fingerabdruck Ihres SSH-Schlüssels und der aus dem vorherigen Schritt erhaltenen Snapshot-ID. Die Parameter do_region und do_size müssen die gleichen Werte wie in der Packer-Variablendatei haben. Wenn Sie mehrere Exemplare gleichzeitig bereitstellen möchten, stellen Sie instance_count auf den gewünschten Wert.

      Danach speichern und schließen Sie die Datei.

      Weitere Informationen über den DigitalOcean Terraform Provider finden Sie in den Offiziellen Dokumenten.

      Sie speichern die Vault Snapshot-Bereitstellungskonfiguration in einer Datei namens deployment.tf, unter dem Verzeichnis terraform. Erstellen Sie sie mit Ihrem Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      ~/vault-orchestration/terraform/deployment.tf

      resource "digitalocean_droplet" "vault" {
        count              = var.instance_count
        image              = var.do_snapshot_id
        name               = var.do_name
        region             = var.do_region
        size               = var.do_size
        private_networking = var.do_private_networking
        ssh_keys = [
          var.ssh_fingerprint
        ]
      }
      
      output "instance_ip_addr" {
        value = {
          for instance in digitalocean_droplet.vault:
          instance.id => instance.ipv4_address
        }
        description = "The IP addresses of the deployed instances, paired with their IDs."
      }
      

      Hier definieren Sie eine einzelne Ressource des Typs digitalocean_droplet namens vault. Danach legen Sie seine Parameter entsprechend den Variablenwerten fest und fügen einen SSH-Schlüssel (mit seinem Fingerabdruck) von Ihrem DigitalOcean-Konto zur Droplet-Ressource hinzu. Zum Schluss erfolgt das output der IP-Adressen aller neu erstellten Exemplare an die Konsole.

      Speichern und schließen Sie die Datei.

      Bevor Sie die Bereitstellungskonfiguration einsetzen, müssen Sie das Verzeichnis als Terraform-Projekt initialisieren:

      Sie sehen die folgende Ausgabe:

      Output

      Initializing the backend... Initializing provider plugins... The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, it is recommended to add version = "..." constraints to the corresponding provider blocks in configuration, with the constraint strings suggested below. * provider.digitalocean: version = "~> 1.14" Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.

      Bei der Initialisierung eines Verzeichnisses als Projekt liest Terraform die verfügbaren Konfigurationsdateien ein und lädt die als notwendig erachteten Plugins herunter, wie in der Ausgabe protokolliert.

      Sie verfügen jetzt über die Terraform-Konfiguration, um Ihren Vault Snapshot bereitzustellen. Sie können diese nun validieren und in einem Droplet bereitstellen.

      Schritt 4 — Bereitstellen von Vault mit Terraform

      In diesem Abschnitt verifizieren Sie die Terraform-Konfiguration mit dem Befehl validate. Nach erfolgreicher Verifizierung wenden Sie sie mit apply an und stellen als Ergebnis ein Droplet bereit.

      Führen Sie den folgenden Befehl aus, um die Gültigkeit Ihrer Konfiguration zu testen:

      Sie sehen die folgende Ausgabe:

      Output

      Success! The configuration is valid.

      Führen Sie als Nächstes den Befehl plan aus, um zu sehen, wie Terraform sich verhält, um die Infrastruktur entsprechend Ihrer Konfiguration bereitzustellen:

      • terraform plan -var-file="definitions.tfvars"

      Terraform akzeptiert eine Variablendefinitionsdatei mit dem Parameter -var-file.

      Die Ausgabe wird ähnlich sein wie diese:

      Output

      Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.vault[0] will be created + resource "digitalocean_droplet" "vault" { ... } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.

      Das grüne + am Anfang der Zeile resource "digitalocean_droplet" "vault" bedeutet, dass Terraform ein neues Droplet mit dem Namen vault erstellt, wobei es folgende Parameter verwendet. Das ist korrekt und nun können Sie den Plan mit terraform apply ausführen:

      • terraform apply -var-file="definitions.tfvars"

      Geben Sie bei Nachfrage yes ein. Nach einigen Minuten ist die Bereitstellung durch das Droplet abgeschlossen und Sie sehen eine Ausgabe ähnlich wie diese:

      Output

      An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + digitalocean_droplet.vault-droplet ... Plan: 1 to add, 0 to change, 0 to destroy. ... digitalocean_droplet.vault-droplet: Creating... ... Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: instance_ip_addr = { "181254240" = "your_new_server_ip" }

      In der Ausgabe protokolliert Terraform die ausgeführten Aktionen (in diesem Fall zur Erstellung eines Droplets) und zeigt am Ende seine öffentliche IP-Adresse an. Diese nutzen Sie, um sich im nächsten Schritt mit Ihrem neuen Droplet zu verbinden.

      Sie haben ein neues Droplet aus dem Snapshot mit Vault erstellt und können es nun verifizieren.

      Schritt 5 — Verifizieren Ihres bereitgestellten Droplets

      In diesem Schritt greifen Sie mit SSH auf Ihr neues Droplet zu und verifizieren, dass Vault korrekt installiert wurde.

      Wenn Sie mit Windows arbeiten, können Sie Software wie Kitty oder Putty verwenden, um sich mit dem Droplet über einen SSH-Schlüssel zu verbinden.

      Auf Linux- und macOS-Rechnern können Sie den bereits verfügbaren Befehl ssh verwenden, um eine Verbindung herzustellen:

      Geben Sie bei Nachfrage yes ein. Nach der Anmeldung starten Sie Vault, indem Sie Folgendes ausführen:

      Sie sehen seine “Hilfe”-Ausgabe, die folgendermaßen aussieht:

      Output

      Usage: vault <command> [args] Common commands: read Read data and retrieves secrets write Write data, configuration, and secrets delete Delete secrets and configuration list List data or secrets login Authenticate locally agent Start a Vault agent server Start a Vault server status Print seal and HA status unwrap Unwrap a wrapped secret Other commands: audit Interact with audit devices auth Interact with auth methods debug Runs the debug command kv Interact with Vault's Key-Value storage lease Interact with leases namespace Interact with namespaces operator Perform operator-specific tasks path-help Retrieve API help for paths plugin Interact with Vault plugins and catalog policy Interact with policies print Prints runtime configurations secrets Interact with secrets engines ssh Initiate an SSH session token Interact with tokens

      Sie können die Verbindung durch Eingabe von exit beenden.

      Sie haben nun verifiziert, dass Ihr neu bereitgestelltes Droplet aus dem von Ihnen erstellten Snapshot kreiert wurde, und dass Vault korrekt installiert ist.

      Zusammenfassung

      Sie verfügen jetzt über ein automatisiertes System zur Bereitstellung von Hashicorp Vault auf DigitalOcean Droplets mit Unterstützung von Terraform und Packer. Sie können nun so viele Vault-Server bereitstellen, wie Sie benötigen. Um Vault zu verwenden, müssen Sie es initialisieren und weiter konfigurieren. Anweisungen hierzu finden Sie in den Offiziellen Dokumenten.

      Weitere Tutorials zur Verwendung von Terraform finden Sie auf der Terraform Content Page.



      Source link