Table of Contents
*Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.*
Введение
Vault от Hashicorp — это инструмент с открытым исходным кодом, предназначенный для безопасного хранения секретов и конфиденциальных данных в динамических облачных средах. Он обеспечивает надежное шифрование данных, доступ на основе идентификации с помощью настраиваемых политик, возможность предоставления в аренду и аннулирования секретов, а также подробный журнал аудита, который поддерживается в любой момент времени. Также Vault содержит HTTP API, что делает его идеальным решением для хранения учетных данных при использовании распределенного сервисно-ориентированного развертывания, например, Kubernetes.
Packer и Terraform, также разработанные Hashicorp, могут использоваться совместно для создания и развертывания образов Vault. В рамках данного рабочего процесса разработчики могут использовать Packer для записи неизменяемых образов для различных платформ из одного файла конфигурации, который указывает, что должен содержать этот образ. После этого Terraform выполняет развертывание любого необходимого количества настраиваемых экземпляров созданных образов.
В этом обучающем модуле вы научитесь использовать Packer для создания неизменяемого снимка системы с установленным Vault, а также сможете организовать его развертывание с помощью Terraform. В результате вы получите автоматизированную систему для развертывания Vault, что позволит сосредоточиться непосредственно на работе с Vault, а не на процессе установки и выделения ресурсов.
Предварительные требования
- Packer, установленный на локальном компьютере. Для получения инструкций по установке ознакомьтесь с официальной документацией.
- Terraform, установленный на локальном компьютере. Дополнительную информацию можно найти в официальной документации.
- Персональный токен доступа (ключ API) с правами на чтение и запись для вашей учетной записи the cloud provider. Чтобы узнать, как получить этот токен, ознакомьтесь со статьей Создание персонального токена доступа в документации.
- Ключ SSH, который вы будете использовать для аутентификации с развернутыми дроплетами Vault, доступный на локальном компьютере и добавленный для вашей учетной записи the cloud provider. Также вам потребуется его отпечаток, который вы можете скопировать на странице Безопасность вашей учетной записи, после его добавления. Ознакомьтесь с документацией the cloud provider для получения подробных инструкций или с руководством Настройка ключей SSH.
Шаг 1 — Создание шаблона Packer
На данном шаге вы создадите файл конфигурации Packer с именем _template_, который будет указывать Packer, как следует собирать образ, который содержит предустановленный Vault. Вы будете использовать файл в формате JSON, широко используемый человекочитаемый формат файла конфигурации.
Для целей настоящего обучающего модуля все файлы следует хранить в каталоге ~/vault-orchestration. Создайте директорию, запустив следующую команду:
mkdir ~/vault-orchestration
Перейдите в директорию:
cd ~/vault-orchestration
Вы будете хранить файлы конфигурации для Packer и Terraform отдельно в разных поддиректориях. Создайте файлы с помощью следующей команды:
mkdir packer terraform
Поскольку сначала мы будем работать с Packer, перейдите в его директорию:
cd packer
Использование переменных шаблона
Хранение частных данных и секретов приложений в отдельном файле переменных является идеальным способом вынесения их из вашего шаблона. При создании образа Packer заменит указанные переменные на эти значения. Жесткое кодирование значений секретов в шаблоне влечет риски для безопасности, особенно если данные будут использоваться другими членами команды или публиковаться на общедоступных сайтов, например, GitHub.
Мы будем хранить их в подкаталоге packer в файле с именем variables.json. Создайте его с помощью текстового редактора:
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"
}
Файл переменных включает словарь JSON, который сопоставляет названия переменных с их значениями. Вы будете использовать эти переменные в шаблоне, который собираетесь создать. Вы можете изменить базовые значения образа, региона и размера дроплета согласно документации для разработчиков.
Не забудьте заменить <^>your_do_api_key<^> на ваш ключ API, созданный согласно предварительным требованиям, после чего сохраните и закройте файл.
Создание средств для сборки и поставщиков
После подготовки файла переменных вы сможете самостоятельно создать шаблон Packer.
Шаблон 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 <^>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"
]
}]
}
В шаблоне задаются массивы _средств для сборки_ и _поставщиков_. Средства сборки указывают Packer, как выполнять сбор образа системы (в зависимости от типа) и где его хранить, а поставщики содержат набор действий, которые Packer должен выполнять для системы, прежде чем преобразовывать ее в неизменяемый образ, например, установка или настройка ПО. Без поставщиков вы получите нетронутый образ базовой системы. Как средства сборки, так и поставщики предоставляют параметры для дальнейшей настройки рабочего процесса.
Сначала вы задаете единое средство сборки типа the cloud provider, что значит, что при необходимости создания образа Packer будет использовать предоставленные параметры для создания временного дроплета определенного размера с помощью предоставленного ключа API, который содержит заданный образ базовой системы и указанный регион. Формат для получения переменной — {{user '<^>variable_name<^>'}}, где выделенная часть является именем.
После предоставления временного дроплета поставщик будет подключаться к нему с помощью SSH с указанным именем пользователя и будет последовательно выполнять все указанные меры перед созданием снимка the cloud provider Snapshot из дроплета и удалением последнего.
Он имеет тип shell, который будет выполнять определенные команды для цели. Команды могут быть указаны как внутри в виде массива строк или определены в отдельных файлах скриптов, если их включение в шаблон будет затруднено из-за большого размера. Команды в шаблоне будут 30 секунд ждать загрузки системы, а затем будут загружать и распаковать Vault <^>1.3.2<^>. Проверьте официальную страницу загрузки Vault и замените ссылку в командах на самую последнюю версию для Linux, если таковая существует.
Внесите необходимые изменения, после чего сохраните и закройте файл.
Чтобы подтвердить валидность шаблона, запустите следующую команду:
packer validate -var-file=variables.json template.json
Packer принимает путь к файлу переменных с помощью аргумента -var-file.
Вывод должен выглядеть так:
[secondary_label Output]
Template validated successfully.
При получении ошибки Packer будет указывать точное место возникновения ошибки, поэтому вы сможете устранить ее.
Теперь у вас есть рабочий шаблон, который позволяет получить образ с установленным Vault, а ключ API и прочие параметры определены в отдельном файле. Теперь вы готовы к вызову Packer и сборке снимка.
Шаг 2 — Сборка снимка
На данном шаге вы выполните сборку снимка the cloud provider из вашего шаблона с помощью команды build в Packer.
Чтобы выполнить сборку снимка, запустите следующую команду:
packer build -var-file=variables.json template.json
Выполнение этой команды может занимать некоторое время. Вы увидите большое количество результатов, которые будут выглядеть примерно следующим образом:
[secondary_label Output]
the cloud provider: output will be in this color.
==> the cloud provider: Creating temporary ssh key for droplet...
==> the cloud provider: Creating droplet...
==> the cloud provider: Waiting for droplet to become active...
==> the cloud provider: Using ssh communicator to connect: ...
==> the cloud provider: Waiting for SSH to become available...
==> the cloud provider: Connected to SSH!
==> the cloud provider: Provisioning with shell script: /tmp/packer-shell035430322
...
==> the cloud provider: % Total % Received % Xferd Average Speed Time Time Time Current
==> the cloud provider: Dload Upload Total Spent Left Speed
the cloud provider: Archive: vault.zip
==> the cloud provider: 100 45.5M 100 45.5M 0 0 154M 0 --:--:-- --:--:-- --:--:-- 153M
the cloud provider: inflating: vault
==> the cloud provider: Gracefully shutting down droplet...
==> the cloud provider: Creating snapshot: packer-1581537927
==> the cloud provider: Waiting for snapshot to complete...
==> the cloud provider: Destroying droplet...
==> the cloud provider: Deleting temporary ssh key...
Build 'the cloud provider' finished.
==> Builds finished. The artifacts of successful builds are:
--> the cloud provider: A snapshot was created: 'packer-1581537927' <^>(ID: 58230938)<^> in regions '...'
Packer фиксирует в журнале все шаги в процессе сборки шаблона. Последняя строка содержит имя снимка (например, packer-1581537927), а также его идентификатор в скобках, выделенный красным. Запишите ваш идентификатор снимка, поскольку он потребуется на следующем шаге.
Если процесс сборки не удалось завершить из-за ошибок API, подождите несколько минут и повторите попытку.
Вы создали снимок the cloud provider с помощью вашего шаблона. Снимок содержит предустановленный Vault, и теперь вы можете развертывать дроплеты, используя его в качестве образа системы. На следующем шаге вы создадите конфигурацию Terraform для автоматизации таких развертываний.
Шаг 3 — Создание конфигурации Terraform
На данном шаге вы создадите конфигурацию Terraform для автоматизации развертываний дроплетов снимка с установленным Vault, который вы только что создали с помощью Packer.
Перед созданием реальной конфигурации Terraform для развертывания Vault из ранее собранного снимка вам потребуется настроить для него поставщика the cloud provider. Перейдите в подкаталог 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. Позднее вы будете использовать эти переменные в шаблоне Terraform, но сначала вам потребуется задать их значения. Для таких целей Terraform поддерживает указание значений переменных в _файле определений переменных_, как и Packer. Имя файла должно заканчиваться на .tfvars или .tfvars.json. Позже вы передадите этот файл в Terraform с помощью аргумента -var-file.
Сохраните и закройте файл.
Создайте файл определений переменных с именем definitions.tfvars с помощью текстового редактора:
nano definitions.tfvars
Добавьте следующие строки:
[label ~/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
Не забудьте заменить <^>your_do_api_key<^>, <^>your_ssh_key_fingerprint<^> и <^>your_do_snapshot_id<^> на ваш ключ API, отпечаток вашего ключа SSH и идентификатор снимка, который вы записали на предыдущем шаге. Параметры do_region и do_size должны иметь те же значения, что и в файле переменных Packer. Если вам потребуется выполнить развертывание сразу нескольких экземпляров, измените значение instance_count на желаемое.
После завершения редактирования сохраните и закройте файл.
Дополнительную информацию по поставщику the cloud provider Terraform можно найти в официальной документации.
Вы будете хранить конфигурацию развертывания снимка с Vault в файле deployment.tf в директории terraform. Создайте его с помощью текстового редактора:
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 => instance.ipv4_address
}
description = "The IP addresses of the deployed instances, paired with their IDs."
}
Здесь вы определяете единый _ресурс_ типа the cloud provider_droplet с именем vault. Затем вы задаете параметры в соответствии со значениями переменных и добавляете ключ SSH (с помощью его отпечатка) из вашей учетной записи the cloud provider в ресурс дроплета. Наконец, вы выводите 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 = "~> 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.
При инициализации каталога как проекта Terraform считывает доступные файлы конфигурации и загружает необходимые плагины, как показано в выводе.
Теперь у вас есть конфигурация Terraform для развертывания вашего снимка Vault. Теперь вы можете перейти к его проверке и развертыванию в дроплете.
Шаг 4 — Развертывание Vault с помощью Terraform
В этом разделе вы выполните проверку вашей конфигурации Terraform с помощью команды validate. После успешной проверки вы должны будете принять ее и развернуть дроплет в качестве результата.
Запустите следующую команду для проверки вашей конфигурации:
terraform validate
Вывод должен выглядеть так:
[secondary_label Output]
Success! The configuration is valid.
Далее запустите команду plan, чтобы увидеть, что будет пытаться делать Terraform при необходимости предоставления инфраструктуры в соответствии с вашей конфигурацией:
terraform plan -var-file="definitions.tfvars"
Terraform принимает файл определений переменных с помощью параметра -var-file.
Результат будет выглядеть примерно следующим образом:
[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.
Зеленый знак + в начале строки resource "the cloud provider_droplet" "vault" означает, что Terraform будет создавать новый дроплет с именем vault, используя следующие параметры. Это правильно, поэтому теперь вы можете воспользоваться командой terraform apply:
terraform apply -var-file="definitions.tfvars"
Введите yes при запросе. Через несколько минут дроплет завершит предоставление ресурсов, а вы увидите примерно следующее:
[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" = "<^>your_new_server_ip<^>"
}
На экране результатов Terraform показывает выполненные действия (в нашем случае — для создания дроплета) и отображает свой публичный IP-адрес в конце. Вы будете использовать его для подключения к вашему новому дроплету в следующем шаге.
Вы создали новый дроплет из снимка с Vault и теперь можете проверить его.
Шаг 5 — Проверка вашего развернутого дроплета
На данном шаге вы получите доступ к вашему новому дроплету с помощью SSH и убедитесь, что Vault установлен корректно.
На компьютерах Linux и macOS вы можете использовать уже имеющуюся команду ssh для подключения:
ssh root@<^>your_server_ip<^>
Введите yes при запросе. После входа запустите Vault с помощью следующей команды:
vault
:
[secondary_label 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
Подключение можно закрыть с помощью команды exit.
Теперь вы убедились, что недавно развернутый дроплет был создан из полученного снимка, а Vault установлен корректно.
Заключение
Вы создали автоматизированную систему для развертывания Hashicorp Vault в дроплетах the cloud provider с помощью Terraform и Packer. Теперь вы можете развернуть необходимое вам количество серверов Vault. Для начала использования Vault вам потребуется инициализировать его и выполнить настройку. Соответствующие инструкции можно найти в официальной документации.
Дополнительные обучающие материалы по работе с Terraform можно найти на странице материалов по Terraform.