Introdução

O Vault, da Hashicorp, é uma ferramenta de código aberto usada para armazenar segredos e dados confidenciais de maneira segura em ambientes dinâmicos em nuvem. O Packer e o Terraform, também desenvolvidos pelo Hashicorp, podem ser usados juntos para criar e implantar imagens do Vault.

Neste tutorial, você usará o Packer para criar um snapshot imutável do sistema com o Vault instalado e orquestrar sua implantação usando o Terraform.

Para obter uma versão mais detalhada deste tutorial, consulte Como construir um servidor Vault da Hashicorp usando o Packer e o Terraform na the cloud provider.

Pré-requisitos

cloud provider illustration for: Pré-requisitos
  • Uma chave SSH que você usará para autenticar-se com os Droplets implantados pelo Vault, disponível em sua máquina local e adicionada em sua conta the cloud provider. Você também precisará de suas digitais, que você pode copiar da página Security de sua conta assim que as tiver adicionado. Veja a documentação da the cloud provider para instruções detalhadas ou o tutorial sobre Como configurar chaves SSH.

Passo 1 — Como criar um template do Packer

Crie e mova-se para o diretório ~/ ~/vault-orchestration para armazenar seus arquivos do Vault:

				
					
mkdir ~/vault-orchestration

cd ~/vault-orchestration

				
			

Crie diretórios separados para a configuração do Packer e do Terraform, executando:

				
					
mkdir packer terraform

				
			

Navegue até o diretório do Packer:

				
					
cd packer

				
			

Como usar variáveis do modelo

Crie um variables.json em seu subdiretório packer para armazenar dados de sua variável privada:

				
					
nano variables.json

				
			

Adicione as linhas a seguir:

				
					
[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"

}

				
			

Você usará essas variáveis no modelo que está prestes a criar. É possível editar o tamanho de imagem base, região e do Droplet, de acordo com a documentação do desenvolvedor.

Substitua <^>your_do_api_key<^> pela sua chave API e, em seguida, salve e feche o arquivo.

Como criar compiladores e provisionadores

Crie seu modelo do Packer para o Vault em um arquivo chamado template.json:

				
					
nano template.json

				
			

Adicione as linhas a seguir:

				
					
[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"

       ]

}]

}

				
			

Você define um único construtor the cloud provider. O Packer criará um Droplet temporário do tamanho, imagem e região definidos usando a chave de API fornecida.

O provisionador se conectará a ele usando o SSH com o nome de usuário especificado e executará sequencialmente todos os provisionadores definidos antes da criação de um Snapshot da the cloud provider por meio do Droplet e da exclusão desse Snapshot.

Ele é do tipo shell, que executará os comandos dados no destino. Os comandos no modelo esperam 30 segundos para o sistema inicializar e então baixam e descompactam o Vault <^>1.3.2<^>. Verifique a página oficial de download do Vault para a versão mais atual do Linux.

Salve e feche o arquivo.

Verifique a validade do seu modelo:

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

				
			

Você verá o seguinte resultado:

				
					
[secondary_label Output]

Template validated successfully.

				
			

Passo 2 — Como compilar o Snapshot

Compile seu snapshot com o comando build do Packer:

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

				
			

Você verá um resultado extenso, que se parecerá com 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 '...'

				
			

A última linha contém o nome do snapshot (como packer-1581537927) e o ID dele entre parênteses, destacada aqui. Anote seu ID do snapshot, pois precisará dele no próximo passo.

Se o processo de compilação falhar devido a erros da API, espere alguns minutos e, em seguida, tente novamente.

Etapa 3 — Escrevendo a configuração do Terraform

Navegue até o subdiretório terraform:

				
					
cd ~/vault-orchestration/terraform

				
			

Crie um arquivo chamado do-provider.tf para armazenar o provedor:

				
					
nano do-provider.tf

				
			

Adicione as linhas a seguir:

				
					
[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 arquivo fornece uma chave de API ao provedor da the cloud provider. Para especificar os valores dessas variáveis, você criará um _arquivo de definições de variáveis_, de maneira similar ao do Packer. O nome do arquivo deve terminar em .tfvars ou .tfvars.json.

Salve e feche o arquivo.

Crie um arquivo de definições de variáveis:

				
					
nano definitions.tfvars

				
			

Adicione as linhas a seguir:

				
					
[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

				
			

Substitua <^>your_do_api_key<^>, <^>your_ssh_key_fingerprint<^> e <^>your_do_snapshot_id<^> (o ID do snapshot que você anotou no passo anterior). Os parâmetros do do_region e do_size devem ter os mesmos valores que no arquivo de variáveis do Packer.

Salve e feche o arquivo.

Crie o seguinte arquivo para armazenar a configuração de implantação do snapshot do Vault:

				
					
nano deployment.tf

				
			

Adicione as linhas a seguir:

				
					
[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."

}

				
			

Você define um único _recurso_ do tipo the cloud provider_droplet chamado vault. Então, define os parâmetros de acordo com os valores das variáveis e adiciona uma chave SSH (usando a digital dela) de sua conta the cloud provider para o recurso do Droplet. Por fim, você usa output para transmitir os endereços IP de todas as instâncias recém-implantadas para o console.

Salve e feche o arquivo.

Inicialize o diretório como um projeto Terraform:

				
					
terraform init

				
			

Você verá o seguinte 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.

				
			

Passo 4 — Como implantar o Vault usando o Terraform

Teste a validade da configuração:

				
					
terraform validate

				
			

Você verá o seguinte resultado:

				
					
[secondary_label Output]

Success! The configuration is valid.

				
			

Execute o comando plan para ver o que o Terraform tentará fazer em relação ao provisionamento da infraestrutura:

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

				
			

O resultado será semelhante a:

				
					
[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.

				
			

Execute o plano:

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

				
			

O Droplet terminará o provisionamento e você verá um resultado semelhante 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;"

}

				
			

Passo 5 — Como verificar seu Droplet implantado

Para se conectar ao seu novo Droplet, execute o seguinte:

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

				
			

Assim que estiver logado, execute o Vault com:

				
					
vault

				
			

Você verá o resultado "ajuda":

				
					
[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

				
			

Conclusão

Agora, você tem um sistema automatizado para implantar o Vault da Hashicorp em Droplets da the cloud provider usando o Terraform e o Packer. Para começar a usar o Vault, será necessário inicializá-lo e configurá-lo ainda mais. Para instruções sobre como fazer isso, visite os docs oficiais.

Para outros tutoriais usando o Terraform, confira nossa página de conteúdo do Terraform.