Введение

Vault от Hashicorp — это инструмент с открытым исходным кодом, предназначенный для безопасного хранения секретов и конфиденциальных данных в динамических облачных средах. Packer и Terraform, также разработанные Hashicorp, могут использоваться совместно для создания и развертывания образов Vault.

В этом обучающем модуле вы научитесь использовать Packer для создания неизменяемого снимка системы с установленным Vault, а также сможете организовать его развертывание с помощью Terraform.

Более подробная версия настоящего руководства содержится в документе «Создание сервера Hashicorp Vault с помощью Packer и Terraform в the cloud provider».

Предварительные требования

cloud provider illustration for: Предварительные требования
  • Ключ SSH, который вы будете использовать для аутентификации с развернутыми дроплетами Vault, доступный на локальном компьютере и добавленный для вашей учетной записи the cloud provider. Также вам потребуется его отпечаток, который вы можете скопировать на странице Безопасность вашей учетной записи, после его добавления. Ознакомьтесь с документацией the cloud provider для получения подробных инструкций или с руководством Настройка ключей SSH.

Шаг 1 — Создание шаблона Packer

Создайте и перейдите в каталог ~/vault-orchestration для хранения ваших файлов Vault:

				
					
mkdir ~/vault-orchestration

cd ~/vault-orchestration

				
			

Создайте отдельные каталоги для Packer и Terraform с помощью следующей команды:

				
					
mkdir packer terraform

				
			

Перейдите в каталог Packer:

				
					
cd packer

				
			

Использование переменных шаблона

Создайте файл variables.json в подкаталоге packer для хранения данных частных переменных:

				
					
nano variables.json

				
			

Добавьте следующие строки:

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

}

				
			

Вы будете использовать эти переменные в шаблоне, который собираетесь создать. Вы можете изменить базовые значения образа, региона и размера дроплета согласно документации для разработчиков.

Замените <^>your_do_api_key<^> на ваш ключ API, затем сохраните и закройте файл.

Создание средств для сборки и поставщиков

Создайте шаблон Packer для Vault в файле с именем template.json:

				
					
nano template.json

				
			

Добавьте следующие строки:

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

       ]

}]

}

				
			

Вы определяете один конструктор the cloud provider. Packer создаст временный Droplet заданного размера, образа и региона с помощью предоставленного ключа API.

Провайдер подключится к нему при помощи SSH с указанным именем пользователя и последовательно выполнит всех определенных провайдеров перед созданием снимка the cloud provider из Droplet и его удалением.

Он имеет тип shell, который будет выполнять определенные команды для цели. Команды в шаблоне будут 30 секунд ждать загрузки системы, а затем будут загружать и распаковать Vault <^>1.3.2<^>. Последнюю актуальную версию для Linux можно найти на официальной странице загрузки Vault.

Сохраните и закройте файл.

Подтвердите корректность шаблона:

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

				
			

Вывод должен выглядеть так:

				
					
[secondary_label Output]

Template validated successfully.

				
			

Шаг 2 — Сборка снимка

Создайте снимок с помощью команды Packer build:

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

				
			

Вы увидите большое количество результатов, которые будут выглядеть примерно следующим образом:

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

				
			

Последняя строка содержит имя снимка (например, packer-1581537927) и его идентификатор в скобках, выделенный здесь. Запишите идентификатор снимка, так как он потребуется на следующем шаге.

Если процесс сборки не удалось завершить из-за ошибок API, подождите несколько минут и повторите попытку.

Шаг 3 — Создание конфигурации Terraform

Перейдите в подкаталог terraform:

				
					
cd ~/vault-orchestration/terraform

				
			

Создайте файл с именем do-provider.tf для хранения провайдера:

				
					
nano do-provider.tf

				
			

Добавьте следующие строки:

				
					
[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

}

				
			

Данный файл предоставляет провайдер the cloud provider с помощью ключа API. Для указания значений этих переменных вы создадите _файл определений переменных_ аналогично шаблону Packer. Имя файла должно заканчиваться на .tfvars или .tfvars.json.

Сохраните и закройте файл.

Создайте файл определений переменных:

				
					
nano definitions.tfvars

				
			

Добавьте следующие строки:

				
					
[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

				
			

Замените <^>your_do_api_key<^>, <^>your_ssh_key_fingerprint<^> и <^>your_do_snapshot_id<^> (идентификатор снимка, который вы отметили на предыдущем шаге). Параметры do_region и do_size должны иметь те же значения, что и в файле переменных Packer.

Сохраните и закройте файл.

Создайте следующий файл для хранения конфигурации со снимками развертывания Vault:

				
					
nano deployment.tf

				
			

Добавьте следующие строки:

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

}

				
			

Вы определяете единый _ресурс_ типа the cloud provider_droplet с именем vault. Вы задаете его параметры в соответствии со значениями переменных и добавляете ключ SSH (с помощью его отпечатка) с вашей учетной записи the cloud provider на ресурс Droplet. Вы выводите IP-адреса всех вновь развернутых экземпляров в консоль.

Сохраните и закройте файл.

Инициализируйте директорию как проект Terraform:

				
					
terraform init

				
			

Вывод должен выглядеть так:

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

				
			

Шаг 4 — Развертывание Vault с помощью Terraform

Проверьте корректность конфигурации:

				
					
terraform validate

				
			

Вывод должен выглядеть так:

				
					
[secondary_label Output]

Success! The configuration is valid.

				
			

Запустите команду plan, чтобы увидеть, что будет пытаться настроить Terraform при получении базы для инфраструктуры:

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

				
			

Результат будет выглядеть примерно следующим образом:

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

				
			

Выполните команду plan:

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

				
			

Droplet завершит предоставление, и вы увидите примерно следующее:

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

}

				
			

Шаг 5 — Проверка вашего развернутого дроплета

Запустите следующее для подключения к вашему новому Droplet:

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

				
			

После входа запустите Vault с помощью следующей команды:

				
					
vault

				
			

Вы увидите его результат "help":

				
					
[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

				
			

Заключение

Вы создали автоматизированную систему для развертывания Hashicorp Vault в дроплетах the cloud provider с помощью Terraform и Packer. Для начала использования Vault вам потребуется инициализировать его и выполнить настройку. Соответствующие инструкции можно найти в официальной документации.

Дополнительные обучающие материалы по работе с Terraform можно найти на странице материалов по Terraform.