El autor seleccionó la Free and Open Source Fund para recibir una donación como parte del programa Write for DOnations.
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. Ofrece un cifrado de datos seguro, acceso basado en identidad usando políticas personalizadas, y arrendamiento y revocación de secretos, además de un registro de auditoría detallado que se asienta en todo momento. Vault también cuenta con una API HTTP, lo que lo convierte en la opción ideal para almacenar credenciales en implementaciones diseminadas orientadas al servicio, como Kubernetes.
Packer y Terraform, también desarrollados por Hashicorp, pueden usarse juntos para crear e implementar imágenes de Vault. En este flujo de trabajo, los desarrolladores pueden usar Packer para escribir imágenes inmutables para diferentes plataformas desde un único archivo de configuración, que especifica lo que la imagen debería contener. Posteriormente, Terraform implementa tantas instancias personalizadas de las imágenes creadas como sea necesario.
En este tutorial, usará Packer para crear una instantánea inmutable del sistema con Vault instalado y orquestará su implementación usando Terraform. Al final, tendrá un sistema automatizado para implementar Vault, lo que le permitirá centrarse en trabajar con Vault y no en el proceso de instalación y aprovisionamiento subyacente.
En este paso, escribirá un archivo de configuración de Packer, llamado template, que indicará a Packer cómo crear una imagen que tenga Vault previamente instalado. Escribirá la configuración en formato JSON, un formato de archivo de configuración legible para humanos que se usa comúnmente.
A los efectos de este tutorial, almacenará todos los archivos en ~/vault-orchestration
. Cree el directorio ejecutando el siguiente comando:
- mkdir ~/vault-orchestration
Diríjase a este:
- cd ~/vault-orchestration
Almacenará los archivos de configuración para Packer y Terraform por separado, en subdirectorios diferentes. Créelos usando el siguiente comando:
- mkdir packer terraform
Debido a que primero trabajará con Packer, diríjase al directorio de este:
- cd packer
Almacenar datos privados y secretos de la aplicación en un archivo de variables independiente es una excelente alternativa para mantenerlos fuera de su plantilla. Cuando se cree la imagen, Packer sustituirá las variables referenciadas por sus valores. Codificar de forma rígida valores secretos en su plantilla es un riesgo de seguridad, en particular si se compartirá con miembros del equipo o se dispondrá en sitios públicos, como GitHub.
Los almacenará en el subdirectorio packer
, en un archivo llamado variables.json
. Créelo usando su editor de texto favorito:
- nano variables.json
Añada las siguientes líneas:
{
"do_token": "your_do_api_key",
"base_system_image": "ubuntu-18-04-x64",
"region": "nyc3",
"size": "s-1vcpu-1gb"
}
El archivo de variables consiste en un diccionario JSON, que asigna los nombres de variables a sus valores. Usará estas variables en la plantilla que está a punto de crear. Si lo desea, puede editar los valores básicos de imagen, región y tamaño del Droplet conforme a los documentos para desarrolladores.
Recuerde sustituir your_do_api_key
por la clave de API que creó como parte de los requisitos previos, y luego guarde y cierre el archivo.
Una vez que esté listo el archivo de variables, creará la plantilla de Packer.
Guardará la plantilla de Packer para Vault en un archivo llamado template.json
. Créelo usando su editor de texto:
- nano template.json
Añada las siguientes líneas:
{
"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"
]
}]
}
En la plantilla, se definen conjuntos de compiladores y aprovisionadores. Los compiladores indican a Packer la manera de compilar la imagen del sistema (según su tipo) y el espacio en el que se almacenará, mientras que los aprovisionadores contienen conjuntos de acciones que Packer debería realizar en el sistema antes de convertirlo en una imagen inmutable; por ejemplo, instalar o configurar software. Sin aprovisionadores, obtendría una imagen de sistema básica intacta. Tanto los compiladores como los aprovisionadores exponen parámetros para una personalización del flujo de trabajo más completa.
Primero se define un compilador individual del tipo digitalocean
; esto significa que, cuando se le ordene crear una imagen, Packer usará los parámetros proporcionados para crear un Droplet temporal del tamaño definido usando la clave de API proporcionada, con la imagen del sistema básica y en la región especificada. El formato para obtener una variable es {{user 'variable_name'}}
, donde la parte resaltada es su nombre.
Cuando se proporcione el Droplet temporal, el proveedor establecerá conexión con él usando SSH con el nombre de usuario especificado y de forma secuencial ejecutará todos los proveedores definidos antes de crear una instantánea de DigitalOcean desde el Droplet y eliminarlo.
Es del tipo shell
, que ejecutará los comando determinados en el destino. Los comandos pueden especificarse inline
, como un conjunto de cadenas, o definirse en archivos de secuencias de comandos independientes si su inserción en la plantilla dificulta la manipulación debido al tamaño. 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 y sustituya el enlace de los comandos por una versión más reciente de Linux, si está disponible.
Cuando termine, guarde y cierre el archivo.
Para verificar la validez de su plantilla, ejecute el siguiente comando:
- packer validate -var-file=variables.json template.json
Packer acepta una ruta al archivo de variables a través del argumento -var-file
.
Verá el siguiente resultado:
OutputTemplate validated successfully.
Si ve un error, Packer especificará con exactitud dónde se produjo para que pueda corregirlo.
Ahora tiene una plantilla en funcionamiento que produce una imagen con Vault instalado, con su clave de API y otros parámetros definidos en un archivo independiente. Con esto, estará listo para invocar Packer y crear la instantánea.
En este paso, creará una instantánea de DigitalOcean desde su plantilla usando el comando build
de Packer.
Para crear su instantánea, ejecute el siguiente comando:
- packer build -var-file=variables.json template.json
Este comando tardará un tiempo en ejecutarse. Verá muchos resultados que tendrán un aspecto similar a este:
Outputdigitalocean: 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 registra todos los pasos que realizó al crear su plantilla. La última línea contiene el nombre de la instantánea (como packer-1581537927
) y su ID entre paréntesis marcado en rojo. Anote el ID de la instantánea, lo necesitará en el paso siguiente.
Si el proceso de creación falla debido a errores de API, espere unos minutos y realice un nuevo intento.
Creó una instantánea de DigitalOcean conforme a su plantilla. La instantánea tiene Vault previamente instalado, y ahora puede implementar Droplets con él como su imagen de sistema. En el siguiente paso, escribirá la configuración de Terraform para automatizar dichas implementaciones.
En este paso, escribirá la configuración de Terraform para automatizar implementaciones de Droplets de la instantánea que contiene el Vault que acaba de crear usando Packer.
Antes de escribir la configuración real de Terraform para implementar Vault desde la instantánea creada previamente, primero deberá configurar el proveedor de DigitalOcean. Diríjase al subdirectorio terraform
ejecutando lo siguiente:
- cd ~/vault-orchestration/terraform
A continuación, cree un archivo llamado do-provider.tf
en el que almacenará el proveedor:
- nano do-provider.tf
Añada las siguientes líneas:
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
}
Este archivo declara las variables del parámetro y proporciona al proveedor digitalocean
una clave de API. Posteriormente, usará estas variables en su plantilla de Terraform, pero primero deberá especificar sus valores. Para ello, Terraform admite la especificación de valores de variables en un archivo de definiciones de variables de forma similar a Packer. El nombre del archivo debe terminar en .tfvars
o .tfvars.jason
. Luego, pasará ese archivo a Terraform usando el argumento -var-file
.
Guarde y cierre el archivo.
Cree un archivo de definiciones de variables llamado definitions.tfvars
usando su editor de texto:
- nano definitions.tfvars
Añada las siguientes líneas:
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
Recuerde sustituir your_do_api_key,
your_ssh_key_fingerprint
y your_do_snapshot_id
por la clave de API de su cuenta, la huella de su clave SSH y el ID de la instantánea que anotó en el paso anterior, respectivamente. Los parámetros do_region
y do_size
deben tener los mismos valores que en el archivo de variables de Packer. Si desea implementar varias instancias de una vez, ajuste instance_count
según su valor deseado.
Cuando termine, guarde y cierre el archivo.
Para obtener más información sobre el proveedor de Terraform de DigitalOcean, consulte los documentos oficiales.
Guardará la configuración de la implementación de la instantánea de Vault en un archivo llamado deployment.tf
, en el directorio terraform
. Créelo usando su editor de texto:
- nano deployment.tf
Añada las siguientes líneas:
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."
}
Aquí, define un único recurso del tipo digitalocean_droplet
llamado vault
. A continuación, establecerá sus parámetros según los valores de las variables y añadirá una clave SSH (usando la huella de esta) de su cuenta de DigitalOcean al recurso del Droplet. Finalmente, usará output
para mostrar las direcciones IP de todas las instancias recién implementadas en la consola.
Guarde y cierre el archivo.
Antes de aplicar cualquier otra acción a la configuración de su implementación, deberá inicializar el directorio como proyecto de Terraform:
- terraform init
Verá el siguiente resultado:
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.
Cuando se inicia un directorio como un proyecto, Terraform lee los archivos de configuración disponibles y los complementos de descargas considerados necesarios, según lo que se registre en el resultado.
Ahora cuenta con la configuración de Terraform para implementar su instantánea de Vault. Podrá proceder a validarla e implementarla en un Droplet.
En esta sección, verificará su configuración de Terraform usando el comando validate
. Una vez que se verifique correctamente, utilizará apply
en ella e implementará un Droplet como resultado.
Ejecute el siguiente comando para probar la validez de su configuración:
- terraform validate
Verá el siguiente resultado:
OutputSuccess! The configuration is valid.
A continuación, ejecute el comando plan
para ver qué intentará hacer Terraform cuando se aprovisione la infraestructura según su configuración:
- terraform plan -var-file="definitions.tfvars"
Terraform acepta un archivo de definiciones de variables a través del parámetro -var-file
.
El resultado será similar a este:
OutputRefreshing 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.
El signo +
verde al principio de la línea resource "digitalocean_droplet" "vault"
implica que Terraform creará un nuevo Droplet llamado vault
y usará los parámetros que siguen. Esto es correcto; por ello, ahora podrá implementar el plan ejecutando terraform apply
:
- terraform apply -var-file="definitions.tfvars"
Introduzca yes
cuando se solicite. Después de unos minutos, el Droplet finalizará el aprovisionamiento y verá un resultado similar a este:
OutputAn 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"
}
En el resultado, Terraform registra las acciones que realizó (en este caso, para crear un Droplet) y muestra su dirección IP pública al final. La usará para establecer conexión con su nuevo Droplet en el siguiente paso.
Creó un nuevo Droplet a partir de la instantánea que contiene Vault y ahora está listo para verificarlo.
En este paso, accederá a su nuevo Droplet usando SSH y verificará que Vault se haya instalado correctamente.
En equipos con Windows, puede usar un software como Kitty o Putty para establecer conexión con el Droplet con una clave SSH.
En equipos con Linux o macOS, puede usar el comando ssh
disponible para la conexión.
- ssh root@your_server_ip
Responda yes
cuando se solicite. Una vez que acceda, inicie Vault ejecutanto lo siguiente:
- vault
Verá el resultado de “ayuda”, que tiene este aspecto:
OutputUsage: 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
Puede cerrar la conexión escribiendo exit
.
De esta manera, habrá verificado verificó que su Droplet recién implementado se creó a partir de la instantánea que realizó y que Vault se instaló correctamente.
Ahora dispone de un sistema automatizado para implementar Hashicorp Vault en Droplets de DigitalOcean usando Terraform y Packer. Ahora puede implementar tantos servidores Vault como necesite. 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.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!