Introducción

Vault, de Hashicorp, es una herramienta de código abierto que permite almacenar de forma segura datos secretos y sensibles en entornos dinámicos en la nube. Packer y Terraform, también desarrollados por Hashicorp, pueden usarse juntos para crear e implementar imágenes de Vault.

En este tutorial, usará Packer para crear una instantánea inmutable del sistema con Vault instalado y orquestará su implementación usando Terraform.

Para acceder a una versión más detallada de este tutorial, consulte Cómo crear un servidor de Vault de Hashicorp usando Packer y Terraform en the cloud provider.

Requisitos previos

cloud provider illustration for: Requisitos previos
  • Una clave SSH que usará para la autenticación con los Droplets de Vault implementados, disponible en su equipo local y añadida a su cuenta de the cloud provider. También necesitará su huella; podrá copiarla de la página Seguridad de su cuenta una vez que la haya añadido. Consulte la documentación de the cloud provider para hallar instrucciones detalladas o el tutorial Cómo configurar claves SSH.

Paso 1: Crear una plantilla de Packer

Cree el directorio ~/vault-orchestration y posiciónese en él para almacenar sus archivos de Vault:

				
					
mkdir ~/vault-orchestration

cd ~/vault-orchestration

				
			

Cree directorios separados para la configuración de Packer y Terraform ejecutando lo siguiente:

				
					
mkdir packer terraform

				
			

Diríjase al directorio de Packer:

				
					
cd packer

				
			

Usar variables de plantilla

Cree variables.json en el subdirectorio packer para almacenar sus datos de variables privadas:

				
					
nano variables.json

				
			

Añada las siguientes líneas:

				
					
[label ~/vault-orchestration/packer/variables.json]

{

  "do_token": "<^>your_do_api_key<^>",

  "base_system_image": "ubuntu-18-04-x64",

  "region": "nyc3",

  "size": "s-1vcpu-1gb"

}

				
			

Usará estas variables en la plantilla que está a punto de crear. Puede editar los valores básicos de imagen, región y tamaño de Droplet conforme a los documentos para desarrolladores.

Sustituya <^>your_do_api_key<^> por su clave de API y, luego, guarde y cierre el archivo.

Crear compiladores y aprovisionadores

Cree su plantilla de Packer para Vault en un archivo llamado template.json:

				
					
nano template.json

				
			

Añada las siguientes líneas:

				
					
[label ~/vault-orchestration/packer/template.json]

{

   "builders": [{

       "type": "the cloud provider",

       "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 &lt;^&gt;https://releases.hashicorp.com/vault/1.3.2/vault_1.3.2_linux_amd64.zip&lt;^&gt; -o vault.zip",

           "unzip vault.zip",

           "sudo chown root:root vault",

           "mv vault /usr/local/bin/",

           "rm -f vault.zip"

       ]

}]

}

				
			

Definirá un solo generador the cloud provider. Packer creará un Droplet temporal con el tamaño, la imagen y la región definidos usando la clave API proporcionada.

El proveedor establecerá conexión con él usando SSH con el nombre de usuario especificado y ejecutará todos los proveedores definidos antes de crear una instantánea de the cloud provider del Droplet y eliminarlo.

Es del tipo shell, que ejecutará los comando determinados en el destino. Los comandos de la plantilla esperarán 30 segundos para que el sistema arranque, y luego descargarán y desempaquetarán Vault <^>1.3.2<^>. Consulte la página oficial de descarga de Vault para acceder a la versión más reciente para Linux.

Guarde y cierre el archivo.

Verifique la validez de su plantilla:

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

				
			

Verá el siguiente resultado:

				
					
[secondary_label Output]

Template validated successfully.

				
			

Paso 2: Crear la instantánea

Cree su instantánea con el comando build de Packer:

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

				
			

Verá muchos resultados que tendrán un aspecto similar a este:

				
					
[secondary_label Output]

the cloud provider: output will be in this color.



==&gt; the cloud provider: Creating temporary ssh key for droplet...

==&gt; the cloud provider: Creating droplet...

==&gt; the cloud provider: Waiting for droplet to become active...

==&gt; the cloud provider: Using ssh communicator to connect: ...

==&gt; the cloud provider: Waiting for SSH to become available...

==&gt; the cloud provider: Connected to SSH!

==&gt; the cloud provider: Provisioning with shell script: /tmp/packer-shell035430322

...

==&gt; the cloud provider:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

==&gt; the cloud provider:                                  Dload  Upload   Total   Spent    Left  Speed

  the cloud provider: Archive:  vault.zip

==&gt; the cloud provider: 100 45.5M  100 45.5M    0     0   154M      0 --:--:-- --:--:-- --:--:--  153M

  the cloud provider:   inflating: vault

==&gt; the cloud provider: Gracefully shutting down droplet...

==&gt; the cloud provider: Creating snapshot: packer-1581537927

==&gt; the cloud provider: Waiting for snapshot to complete...

==&gt; the cloud provider: Destroying droplet...

==&gt; the cloud provider: Deleting temporary ssh key...

Build 'the cloud provider' finished.



==&gt; Builds finished. The artifacts of successful builds are:

--&gt; the cloud provider: A snapshot was created: 'packer-1581537927' &lt;^&gt;(ID: 58230938)&lt;^&gt; in regions '...'

				
			

La última línea contiene el nombre de la instantánea (como packer-1581537927) y su ID entre paréntesis, resaltados aquí. Tome nota del ID de la instantánea, ya que lo necesitará en el siguiente paso.

Si el proceso de creación falla debido a errores de API, espere unos minutos y realice un nuevo intento.

Paso 3: Escribir la configuración de Terraform

Diríjase al subdirectorio terraform:

				
					
cd ~/vault-orchestration/terraform

				
			

Cree un archivo llamado do-provider.tf para almacenar el proveedor:

				
					
nano do-provider.tf

				
			

Añada las siguientes líneas:

				
					
[label ~/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 "the cloud provider" {

token = var.do_token

}

				
			

Este archivo proporciona una clave de API al proveedor the cloud provider. Para especificar los valores de estas variables, creará un _archivo de definiciones de variables_ similar a Packer. El nombre del archivo debe terminar en .tfvars o .tfvars.jason.

Guarde y cierre el archivo.

Cree un archivo de definiciones de variables:

				
					
nano definitions.tfvars

				
			

Añada las siguientes líneas:

				
					
[label ~/vault-orchestration/terraform/definitions.tf]

do_token         = "&lt;^&gt;your_do_api_key&lt;^&gt;"

ssh_fingerprint  = "&lt;^&gt;your_ssh_key_fingerprint&lt;^&gt;"

do_snapshot_id   = &lt;^&gt;your_do_snapshot_id&lt;^&gt;

do_name          = "vault"

do_region        = "nyc3"

do_size          = "s-1vcpu-1gb"

instance_count   = 1

				
			

Sustituya <^>your_do_api_key<^>, <^>your_ssh_key_fingerprint<^> y <^>your_do_snapshot_id<^>, (el ID de la instantánea del que tomó nota en el paso anterior). ​​ Los parámetros do_region y do_size deben tener los mismos valores que en el archivo de variables de Packer.

Guarde y cierre el archivo.

Cree el siguiente archivo para almacenar la configuración de la implementación de la instantánea de Vault:

				
					
nano deployment.tf

				
			

Añada las siguientes líneas:

				
					
[label ~/vault-orchestration/terraform/deployment.tf]

resource "the cloud provider_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 the cloud provider_droplet.vault:

  instance.id =&gt; instance.ipv4_address

}

description = "The IP addresses of the deployed instances, paired with their IDs."

}

				
			

Defina un único _recurso_ del tipo the cloud provider_droplet llamado vault. Establezca sus parámetros según los valores de las variables y añada una clave SSH (usando su huella) de su cuenta de the cloud provider al recurso del Droplet. Use output para mostrar las direcciones IP de todas las instancias recientemente implementadas en la consola.

Guarde y cierre el archivo.

Inicie el directorio como proyecto de Terraform:

				
					
terraform init

				
			

Verá el siguiente resultado:

				
					
[secondary_label 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.the cloud provider: version = "~&gt; 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.

				
			

Paso 4: Implementar Vault usando Terraform

Pruebe la validez de la configuración:

				
					
terraform validate

				
			

Verá el siguiente resultado:

				
					
[secondary_label Output]

Success! The configuration is valid.

				
			

Ejecute el comando plan para ver qué intentará hacer Terraform respecto del aprovisionamiento de la infraestructura:

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

				
			

El resultado será similar a este:

				
					
[secondary_label 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:



# the cloud provider_droplet.vault[0] will be created

+ resource "the cloud provider_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.

				
			

Ejecute el plan:

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

				
			

El Droplet finalizará el aprovisionamiento y verá un resultado similar a este:

				
					
[secondary_label 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:



+ the cloud provider_droplet.vault-droplet



...



Plan: 1 to add, 0 to change, 0 to destroy.



...



the cloud provider_droplet.vault-droplet: Creating...



...



Apply complete! Resources: 1 added, 0 changed, 0 destroyed.



Outputs:



instance_ip_addr = {

"181254240" = "&lt;^&gt;your_new_server_ip&lt;^&gt;"

}

				
			

Paso 5: Verificar su Droplet implementado

Ejecute lo siguiente para establecer conexión con su nuevo Droplet:

				
					
ssh root@&lt;^&gt;your_server_ip&lt;^&gt;

				
			

Una vez que inicie sesión, ejecute Vault con lo siguiente:

				
					
vault

				
			

Verá su resultado de “ayuda”:

				
					
[secondary_label Output]

Usage: vault &lt;command&gt; [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

				
			

Conclusión

Ahora dispone de un sistema automatizado para implementar Hashicorp Vault en Droplets de the cloud provider usando Terraform y Packer. Para comenzar a usar Vault, deberá iniciarlo y realizar algunas configuraciones adicionales. Para hallar instrucciones sobre cómo hacerlo, consulte la documentación oficial.

Para hallar más tutoriales sobre Terraform, consulte nuestra página de contenido de Terraform.