Table of Contents
*Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.*
Введение
Разработчики могут использовать Terraform для организации различных сред, отслеживания изменений посредством контроля версий и автоматизации повторяющихся задач для предотвращения человеческих ошибок. Также Terraform позволяет командам совместно работать над совершенствованием инфраструктуры посредством общих конфигураций.
В этом обучающем руководстве мы импортируем существующую инфраструктуру the cloud provider в Terraform. К завершению этого обучающего руководства вы сможете использовать Terraform для всей своей инфраструктуры, а также создавать новые ресурсы.
Предварительные требования
- Персональный токен доступа the cloud provider. Для его создания следует воспользоваться указаниями руководства Создание персонального токена доступа.
- Дроплет the cloud provider с тегом. Вы можете использовать указания обучающего руководства Создание дроплета из панели управления the cloud provider.
- Облачный брандмауэр the cloud provider Cloud Firewall, примененный к дроплету. Вы можете воспользоваться указаниями руководства Создание брандмауэров.
- Клиент командной строки the cloud provider, установленный на локальном компьютере в соответствии с указаниями по установке, приведенными на странице
doctlна GitHub. Также вы можете прочитать руководство Использование Doctl, официального клиента командной строки the cloud provider.
Шаг 1 — Локальная установка Terraform
На первом шаге следует установить Terraform на локальный компьютер. На этом шаге описывается установка двоичного файла Linux. Если вы используете операционную систему Windows или Mac, вы можете воспользоваться страницей загрузки Terraform на сайте Terraform.
Перейдите в папку на локальном компьютере, куда вы хотите загрузить Terraform, а затем используйте утилиту wget для загрузки двоичного файла Terraform <^>0.12.12<^>:
cd <^>/tmp<^>
wget https://releases.hashicorp.com/terraform/<^>0.12.12<^>/terraform_<^>0.12.12<^>_linux_amd64.zip
Чтобы проверить соответствие контрольной суммы sha256 указанному на сайте Terraform значению, загрузите файл контрольной суммы с помощью следующей команды:
wget -q https://releases.hashicorp.com/terraform/<^>0.12.12<^>/terraform_<^>0.12.12<^>_SHA256SUMS
Затем запустите следующую команду для проверки контрольных сумм:
sha256sum -c --ignore-missing terraform_<^>0.12.12<^>_SHA256SUMS
В загруженном вами файле SHA256SUMS содержится список имен файлов и значений хэш-сумм для этих файлов. Эта команда ищет локальный файл terraform_<^>0.12.12<^>_SHA256SUMS и проверяет соответствие хэш-сумм, используя флаг -c. Поскольку у этого файла имеется несколько имен файла, и указана его платформа, используйте флаг --ignore-missing для предотвращения ошибок, поскольку у вас нет копий других файлов.
Вы увидите следующий результат:
[secondary_label Output]
terraform_0.12.12_linux_amd64.zip: OK
Используйте unzip для распаковки двоичного файла:
sudo unzip terraform_<^>0.12.12<^>_linux_amd64.zip -d /usr/local/bin/
Убедитесь в правильности установки Terraform посредством проверки версии:
terraform version
Результат будет выглядеть примерно так:
[secondary_label Output]
Terraform v<^>0.12.12<^>
Мы установили Terraform на локальном компьютере и можем перейти к подготовке файлов конфигурации.
Шаг 2 — Подготовка файлов конфигурации Terraform
На этом шаге мы импортируем в Terraform имеющиеся ресурсы посредством создания директории проекта и записи файлов конфигурации. Поскольку Terraform не поддерживает генерирование конфигураций из команды import, эти конфигурации следует создать вручную.
Запустите следующую команду для создания директории вашего проекта:
mkdir -p <^>do_terraform_import<^>
Затем перейдите в эту директорию:
cd <^>do_terraform_import<^>
На этом шаге мы создадим три дополнительных файла, в которых будут содержаться требуемые конфигурации. Структура директорий этого проекта будет выглядеть следующим образом:
├── the cloud provider_droplet.tf
├── the cloud provider_firewall.tf
└── provider.tf
Для начала мы создадим файл provider.tf для определения токена доступа the cloud provider как переменной среды вместо его программирования в конфигурации.
[warning]
Предупреждение. Токен доступа предоставляет неограниченный доступ ко всей вашей инфраструктуре, поэтому с ним следует обращаться осторожно. Убедитесь, что доступ к компьютеру, где хранится токен, имеется только у вас.
Помимо токена доступа также следует указать, какого провайдера вы хотите использовать. Для целей данного обучающего руководства мы используем the cloud provider. Полный список доступных источников данных и ресурсов для the cloud provider с Terraform можно найти на странице провайдеров на соответствующем сайте.
Создайте файл provider.tf и откройте его для редактирования:
nano provider.tf
Добавьте в файл provider.tf следующие строки:
[label provider.tf]
variable "do_token" {}
provider "the cloud provider" {
token = "${var.do_token}"
version = "1.9.1"
}
В этом файле вы добавляете свой токен доступа the cloud provider как переменную, которую Terraform будет использовать для идентификации в cloud provider API. Также вы указываете версию плагина провайдера the cloud provider. Terraform рекомендует указать используемую версию провайдера, чтобы будущие обновления не нарушили имеющуюся систему.
Далее мы создадим файл the cloud provider_droplet.tf. Здесь мы указываем, какие ресурсы будем использовать. В данном случае это droplet.
Создайте файл с помощью следующей команды:
nano the cloud provider_droplet.tf
Добавьте следующую конфигурацию:
[label the cloud provider_droplet.tf]
resource "the cloud provider_droplet" "do_droplet" {
name = <^>"testing-terraform"<^>
region = <^>"fra1"<^>
tags = <^>["terraform-testing"]<^>
count = "1"
}
Здесь задается четыре параметра:
name: имя дроплета.
region: регион местонахождения дроплета.
tags: перечень всех тегов, применяемых к этому дроплету.
count: количество ресурсов, требуемых для этой конфигурации.
Далее мы создадим файл конфигурации брандмауэра. Создайте файл the cloud provider_firewall.tf с помощью следующей команды:
nano the cloud provider_firewall.tf
Добавьте в файл следующие строки:
[label the cloud provider_firewall.tf]
resource "the cloud provider_firewall" "do_firewall" {
name = <^>"testing-terraform-firewall"<^>
tags = <^>["terraform-testing"]<^>
count = "1"
}
Здесь указывается имя брандмауэра, который вы хотите импортировать, а также теги дроплетов, к которым применяются правила брандмауэра. Наконец, значение count 1 определяет требуемое количество соответствующего ресурса.
Примечание. Вы можете включить ресурсы брандмауэра в файл the cloud provider_droplet.tf, однако если вы используете несколько сред, где несколько дроплетов используют один брандмауэр, лучше разделить их на случай, если вы захотите удалить один из дроплетов. Это не повлияет на вывод брандмауэра.
Теперь следует инициализировать эти изменения, чтобы у Terraform была возможность загрузить требуемые зависимости. Для этого используется команда terraform init, позволяющая инициализировать рабочую директорию с файлами конфигурации Terraform.
Запустите в директории проекта следующую команду:
terraform init
Вывод должен выглядеть так:
[secondary_label Output]
Terraform has been successfully initialized!
Terraform успешно подготовил рабочую директорию, выполнив загрузку плагинов, поиск модулей и т. д. Теперь мы можем начать импорт ресурсов в Terraform.
Шаг 3 — Импорт ресурсов в Terraform
На этом шаге вы импортируете ресурсы the cloud provider в Terraform. Используйте doctl для определения идентификационных номеров дроплетов, прежде чем начать импорт ресурсов. Также вы можете проверить конфигурацию импорта с помощью команд terraform show и terraform plan.
Для начала экспортируйте токен доступа the cloud provider как переменную среды, которая будет использоваться Terraform во время выполнения.
Экспортируйте ее как переменную среды текущего сеанса оболочки с помощью следующей команды:
export DO_TOKEN="<^>YOUR_TOKEN<^>"
Чтобы импортировать существующие дроплет и брандмауэр, вам потребуются их идентификационные номера. Вы можете использовать doctl, интерфейс командной строки cloud provider API. Запустите следующую команду для вывода списка дроплетов и получения доступа к их идентификаторам:
doctl compute droplet list
Результат будет выглядеть примерно так:
[secondary_label Output]
ID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image Status Tags Features Volumes
<^>DROPLET-ID<^> <^>DROPLET-NAME<^> <^>DROPLET-IPv4<^> 1024 1 25 fra1 Ubuntu 18.04.3 (LTS) x64 active
<^>DROPLET-ID<^> <^>DROPLET-NAME<^> <^>DROPLET-IPv4<^> 2048 1 50 fra1 Ubuntu 18.04.3 (LTS) x64 active
<^>DROPLET-ID<^> <^>DROPLET-NAME<^> <^>DROPLET-IPv4<^> 1024 1 25 fra1 Ubuntu 18.04.3 (LTS) x64
Теперь вы импортируете существующий дроплет и брандмауэр в Terraform:
terraform import -var "do_token=${DO_TOKEN}" the cloud provider_droplet.do_droplet <^>DROPLET_ID<^>
Мы используем флаг -var, чтобы задать токен доступа the cloud provider, который вы ранее экспортировали в сеанс оболочки. Это требуется, чтобы cloud provider API мог проверить вашу личность и применить изменения к инфраструктуре.
Теперь запустите эту же команду для вашего брандмауэра:
terraform import -var "do_token=${DO_TOKEN}" the cloud provider_firewall.do_firewall <^>FIREWALL_ID<^>
Команда terraform show позволяет проверить, был ли импорт выполнен успешно. Эта команда позволяет получить удобочитаемые данные по состоянию инфраструктуры. Ее можно использовать для проверки плана, чтобы обеспечить выполнение желаемых изменений, или для проверки текущего состояния с точки зрения Terraform.
В этом контексте _state_ означает сопоставление ресурсов the cloud provider с записанной конфигурацией Terraform и отслеживание метаданных. Это позволяет подтвердить отсутствие различий между существующими ресурсами the cloud provider, которые вы хотите импортировать, и ресурсами, которые отслеживает Terraform:
terraform show
Вывод будет выглядеть следующим образом:
[secondary_label Output]
. . .
# the cloud provider_droplet.do_droplet:
resource "the cloud provider_droplet" "do_droplet" {
backups = false
created_at = "2020-02-03T16:12:02Z"
disk = 25
id = "<^>DROPLET-ID<^>"
image = "<^>DROPLET-IMAGE<^>"
ipv4_address = "<^>DROPLET-IP<^>"
ipv6 = false
locked = false
memory = 1024
monitoring = false
name = "testing-terraform-0"
price_hourly = 0.00744
price_monthly = 5
private_networking = false
region = "fra1"
resize_disk = true
size = "s-1vcpu-1gb"
status = "active"
tags = [
"terraform-testing",
]
urn = "<^>DROPLET-URN<^>"
vcpus = 1
volume_ids = []
. . .
}
В результатах вы увидите два ресурса совместно с атрибутами.
После импорта дроплета и брандмауэра в состояние Terraform необходимо убедиться, что конфигурации представляют текущее состояние импортируемых ресурсов. Для этого следует указать образ Droplet и его размер. Эти два значения можно увидеть в результатах выполнения команды terraform show для ресурса the cloud provider_droplet.do_droplet.
Откройте файл the cloud provider_droplet.tf:
nano the cloud provider_droplet.tf
В этом обучающем руководстве:
- Образ операционной системы, используемый для нашего дроплета:
ubuntu-16-04-x64.
- Регион, где находится ваш дроплет:
fra1.
- Тег существующего дроплета:
terraform-testing.
Дроплет, импортированный с помощью конфигурации в the cloud provider_droplet.tf, будет выглядеть следующим образом:
[label the cloud provider_droplet.tf]
resource "the cloud provider_droplet" "do_droplet" {
image = <^>"ubuntu-16-04-x64"<^>
name = <^>"testing-terraform"<^>
region = <^>"fra1"<^>
size = <^>"s-1vcpu-1gb"<^>
tags = <^>["terraform-testing"]<^>
}
Далее вы добавите правила брандмауэра. В нашем примере для входящего трафика открыты порты 22, 80 и 443. Все порты открыты для исходящего трафика. Вы можете изменить конфигурацию в зависимости от состава и количества открытых портов.
Откройте файл the cloud provider_firewall.tf:
nano the cloud provider_firewall.tf
Добавьте следующую конфигурацию:
[label the cloud provider_firewall.tf]
resource "the cloud provider_firewall" "do_firewall" {
name = <^>"testing-terraform-firewall"<^>
tags = <^>["terraform-testing"]<^>
count = "1"
inbound_rule {
protocol = <^>"tcp"<^>
port_range = <^>"22"<^>
source_addresses = <^>["0.0.0.0/0", "::/0"]<^>
}
inbound_rule {
protocol = <^>"tcp"<^>
port_range = <^>"80"<^>
source_addresses = <^>["0.0.0.0/0", "::/0"]<^>
}
inbound_rule {
protocol = <^>"tcp"<^>
port_range = <^>"443"<^>
source_addresses = <^>["0.0.0.0/0", "::/0"]<^>
}
outbound_rule {
protocol = <^>"tcp"<^>
port_range = <^>"all"<^>
destination_addresses = <^>["0.0.0.0/0", "::/0"]<^>
}
outbound_rule {
protocol = <^>"udp"<^>
port_range = <^>"all"<^>
destination_addresses = <^>["0.0.0.0/0", "::/0"]<^>
}
outbound_rule {
protocol = "icmp"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
}
Эти правила воспроизводят состояние существующего образца брандмауэра. Если вы хотите ограничить трафик для других IP-адресов, портов или протоколов, вы можете изменить файл для соответствия настройкам вашего брандмауэра.
После обновления файлов Terraform используйте команду plan, чтобы увидеть, соответствуют ли внесенные изменения состоянию существующих ресурсов в the cloud provider.
Команда terraform plan используется для пробного прогона. С ее помощью вы можете проверить, соответствуют ли вносимые Terraform изменения желаемым. Эту команду всегда полезно запускать для подтверждения перед применением изменений.
Запустите команду terraform plan со следующим синтаксисом:
terraform plan -var "do_token=$DO_TOKEN"
Вы увидите следующие результаты:
[secondary_label Output]
No changes. Infrastructure is up-to-date.
Вы успешно импортировали существующие ресурсы the cloud provider в Terraform и теперь можете вносить через Terraform изменения в инфраструктуру без риска случайного удаления или изменения существующих ресурсов.
Шаг 4 — Создание новых ресурсов через Terraform
На этом шаге мы добавляем два дополнительных дроплета в существующую инфраструктуру. Например, такое добавление ресурсов в существующую инфраструктуру может быть полезным, если у вас запущен сайт и вы не хотите нарушить его работу во время внесения изменений. Вместо этого вы можете добавить еще один дроплет в качестве среды разработки и поработать над проектом в той же среде, где находится производственный дроплет, без каких-либо потенциальных рисков.
Откройте файл the cloud provider_droplet.tf для добавления правил для новых дроплетов:
nano the cloud provider_droplet.tf
Добавьте в файл следующие строки:
[label the cloud provider_droplet.tf]
resource "the cloud provider_droplet" "do_droplet" {
image = <^>"ubuntu-16-04-x64"<^>
name = <^>"testing-terraform"<^>
region = <^>"fra1"<^>
size = <^>"s-1vcpu-1gb"<^>
tags = <^>["terraform-testing"]<^>
count = "1"
}
resource "the cloud provider_droplet" "do_droplet_new" {
image = <^>"ubuntu-18-04-x64"<^>
name = <^>"testing-terraform-${count.index}"<^>
region = <^>"fra1"<^>
size = <^>"s-1vcpu-1gb"<^>
tags = <^>["terraform-testing"]<^>
count = "2"
}
Вы используете мета-аргумент count, чтобы указать Terraform, сколько дроплетов с такими же спецификациями вам потребуется. Эти новые дроплеты также будут добавлены в брандмауэр, поскольку вы указываете тот же тег, что и для брандмауэра.
Примените эти правила для проверки изменений, задаваемых в the cloud provider_droplet.tf:
terraform plan -var "do_token=$DO_TOKEN"
Убедитесь, что желаемые изменения отражаются в результатах выполнения команды.
Результат будет выглядеть примерно так:
. . .
[secondary_label Output]
# the cloud provider_droplet.do_droplet_new[1] will be created
+ resource "the cloud provider_droplet" "do_droplet_new" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ id = (known after apply)
+ image = "<^>ubuntu-18-04-x64<^>"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ ipv6_address_private = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "<^>testing-terraform-1<^>"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = true
+ region = "<^>fra1<^>"
+ resize_disk = true
+ size = "<^>s-1vcpu-1gb<^>"
+ status = (known after apply)
+ tags = [
+ "<^>terraform-testing<^>",
]
+ urn = (known after apply)
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
}
Plan: 2 to add, 1 to change, 0 to destroy.
Когда вы будете довольны результатами, используйте команду terraform apply для применения указанных изменений к состоянию конфигурации:
terraform apply -var "do_token=$DO_TOKEN"
Подтвердите внесение изменений, введя yes в командной строке. После успешного выполнения вы увидите примерно следующее:
[secondary_label Output]
. . .
the cloud provider_droplet.do_droplet_new[1]: Creating...
the cloud provider_droplet.do_droplet_new[0]: Creating...
the cloud provider_firewall.do_firewall[0]: Modifying... [id=<^>FIREWALL-ID<^>]
the cloud provider_firewall.do_firewall[0]: Modifications complete after 1s [id=<^>FIREWALL-ID<^>]
the cloud provider_droplet.do_droplet_new[0]: Still creating... [10s elapsed]
the cloud provider_droplet.do_droplet_new[1]: Still creating... [10s elapsed]
the cloud provider_droplet.do_droplet_new[0]: Creation complete after 16s [id=<^>DROPLET-ID<^>]
the cloud provider_droplet.do_droplet_new[1]: Still creating... [20s elapsed]
the cloud provider_droplet.do_droplet_new[1]: Creation complete after 22s [id=<^>DROPLET-ID<^>]
Apply complete! Resources: 2 added, 1 changed, 0 destroyed.
Вы увидите два новых дроплета на веб-панели the cloud provider: !новые дроплеты
Также вы увидите, что они прикреплены к существующему брандмауэру: !существующий брандмауэр
Вы создали с помощью Terraform новые ресурсы, использовав для этого имеющиеся ресурсы. На следующем шаге вы можете узнать, как уничтожить эти ресурсы.
Шаг 5 — Уничтожение импортированных и созданных ресурсов (необязательно)
На этом шаге мы уничтожим импортированные и созданные ресурсы посредством изменения конфигурации.
Откройте the cloud provider_droplet.tf:
nano the cloud provider_droplet.tf
Задайте в файле для параметра count значение 0, как показано здесь:
[label the cloud provider_droplet.tf]
resource "the cloud provider_droplet" "do_droplet" {
image = "ubuntu-16-04-x64"
name = "testing-terraform"
region = "fra1"
size = "s-1vcpu-1gb"
tags = ["terraform-testing"]
<^>count = "0"<^>
}
resource "the cloud provider_droplet" "do_droplet_new" {
image = "ubuntu-18-04-x64"
name = "testing-terraform-${count.index}"
region = "fra1"
size = "s-1vcpu-1gb"
tags = ["terraform-testing"]
<^>count = "0"<^>
}
Сохраните и закройте файл.
Откройте файл конфигурации брандмауэра и измените в нем параметр count:
nano the cloud provider_firewall.tf
Задайте для параметра count значение 0, как в следующей строке:
[label the cloud provider_firewall.tf]
resource "the cloud provider_firewall" "do_firewall" {
name = "testing-terraform-firewall"
tags = ["terraform-testing"]
<^>count = "0"<^>
inbound_rule {
protocol = "tcp"
port_range = "22"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "80"
source_addresses = ["0.0.0.0/0", "::/0"]
}
inbound_rule {
protocol = "tcp"
port_range = "443"
source_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "tcp"
port_range = "all"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "udp"
port_range = "all"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
outbound_rule {
protocol = "icmp"
destination_addresses = ["0.0.0.0/0", "::/0"]
}
}
Сохраните и закройте файл.
Примените изменения с помощью следующей команды:
terraform apply -var "do_token=${DO_TOKEN}"
Terraform предложит подтвердить уничтожение дроплетов и брандмауэра. Эта команда уничтожит все ресурсы, импортированные и созданные с помощью Terraform, так что вводите yes, только если уверены, что хотите продолжить.
Результат будет выглядеть примерно так:
[secondary_label Output]
. . .
the cloud provider_droplet.do_droplet[0]: Destroying... [id=<^>YOUR-DROPLET-ID<^>]]
the cloud provider_droplet.do_droplet_new[0]: Destroying... [id=<^>YOUR-DROPLET-ID<^>]
the cloud provider_droplet.do_droplet_new[1]: Destroying... [id=<^>YOUR-DROPLET-ID<^>]
the cloud provider_firewall.do_firewall[0]: Destroying... [id=<^>YOUR-FIREWALL-ID<^>]
the cloud provider_firewall.do_firewall[0]: Destruction complete after 1s
the cloud provider_droplet.do_droplet_new[1]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 10s elapsed]
the cloud provider_droplet.do_droplet[0]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 10s elapsed]
the cloud provider_droplet.do_droplet_new[0]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 10s elapsed]
the cloud provider_droplet.do_droplet_new[1]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 20s elapsed]
the cloud provider_droplet.do_droplet_new[0]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 20s elapsed]
the cloud provider_droplet.do_droplet[0]: Still destroying... [id=<^>YOUR-DROPLET-ID<^>, 20s elapsed]
the cloud provider_droplet.do_droplet_new[1]: Destruction complete after 22s
the cloud provider_droplet.do_droplet[0]: Destruction complete after 22s
the cloud provider_droplet.do_droplet_new[0]: Destruction complete after 22s
Apply complete! Resources: 0 added, 0 changed, 4 destroyed.
Вы удалили все ресурсы, управляемые Terraform. Это полезный рабочий процесс для удаления ненужных ресурсов или в случае уменьшения масштаба.
Заключение
В этом обучающем руководстве мы выполнили установку Terraform, импортировали существующие ресурсы, создали новые ресурсы и (при желании) уничтожили эти ресурсы. Вы можете использовать этот рабочий процесс и в более масштабном проекте, например для развертывания кластера Kubernetes в производственной среде. С помощью Terraform вы сможете управлять всеми узлами, записями DNS, брандмауэрами, ресурсами хранения и другими ресурсами, а также использовать систему контроля версий для отслеживания изменений и совместной работы в команде.
Дополнительные сведения о возможностях Terraform можно найти в документации. Также вы можете ознакомиться с другими обучающими руководствами и ответами на вопросы в материалах the cloud provider по Terraform.