Начало работы с Terraform
Примечание
В регионе Казахстан доступна только зона доступности kz1-a.
Terraform
Terraform распространяется под лицензией Business Source License
Подробная информация о ресурсах провайдера в документации на сайте Terraform
Чтобы создать первую инфраструктуру в Yandex Cloud с помощью Terraform:
- Подготовьте облако к работе.
- Установите Terraform.
- Получите данные для аутентификации.
- Создайте файл конфигурации Terraform.
- Настройте провайдер.
- Подготовьте план инфраструктуры.
- Проверьте и отформатируйте файлы конфигураций.
- Создайте ресурсы.
Если ресурсы больше вам не нужны, удалите их.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры, которую вы создадите с помощью Terraform, входят:
- плата за постоянно запущенные виртуальные машины (тарифы Yandex Compute Cloud);
- плата за использование динамических публичных IP-адресов (тарифы Yandex Virtual Private Cloud).
Установите Terraform
Из зеркала
Внимание
Зеркало может быть недоступно.
Вы можете скачать дистрибутив Terraform для вашей платформы из зеркалаPATH:
export PATH=$PATH:/path/to/terraform
С сайта HashiCorp
Используйте один из способов:
-
Скачайте дистрибутив Terraform
и установите его согласно инструкции . -
Установите Terraform с помощью пакетного менеджера Chocolatey
, используя команду:choco install terraform
Скачайте дистрибутив Terraform
Используйте один из способов:
-
Скачайте дистрибутив Terraform
и установите его согласно инструкции . -
Установите Terraform с помощью пакетного менеджера Homebrew
, используя команду:brew install terraform
Получите данные для аутентификации
Для аутентификации в Yandex Cloud и управления инфраструктурой используйте Terraform от имени сервисного аккаунта или пользователя: аккаунта на Яндексе, федеративного аккаунта или локального пользователя.
Использование сервисного аккаунта с помощью имперсонации является рекомендованным и наиболее безопасным способом аутентификации.
При создании IAM-токена используйте имперсонацию для созданного сервисного аккаунта, указав его идентификатор в параметре --impersonate-service-account-id. В результате Terraform будет от имени сервисного аккаунта управлять ресурсами в каталоге и использовать IAM-токен сервисного аккаунта.
Примечание
Для использования имперсонации пользователю должна быть назначена роль iam.serviceAccounts.tokenCreator на соответствующий сервисный аккаунт.
Для аутентификации от имени сервисного аккаунта:
-
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите.
-
В Yandex Cloud CLI создайте новый профиль или активируйте созданный ранее.
-
Аутентифицируйтесь от имени аккаунта на Яндексе, федеративного или локального пользователя.
-
Если у вас еще нет сервисного аккаунта, создайте его.
-
Назначьте сервисному аккаунту роли, необходимые для управления ресурсами Yandex Cloud.
-
Запишите аутентификационные данные в переменные окружения, используя имперсонацию:
BashPowerShellexport YC_TOKEN=$(yc iam create-token --impersonate-service-account-id <идентификатор_сервисного_аккаунта>) export YC_CLOUD_ID=$(yc config get cloud-id) export YC_FOLDER_ID=$(yc config get folder-id)$Env:YC_TOKEN=$(yc iam create-token --impersonate-service-account-id <идентификатор_сервисного_аккаунта>) $Env:YC_CLOUD_ID=$(yc config get cloud-id) $Env:YC_FOLDER_ID=$(yc config get folder-id)Где
<идентификатор_сервисного_аккаунта>— идентификатор сервисного аккаунта.
В результате в переменных окружения сохранятся IAM-токен сервисного аккаунта, а также идентификатор облака и идентификатор каталога.
Примечание
При каждой операции аутентификация будет происходить с помощью этого IAM-токена, пока не истечет время его жизни (не более 12 часов). После этого снова потребуется пройти аутентификацию. Для автоматического перевыпуска IAM-токена можно использовать скрипт или другие способы автоматизации.
Чтобы продлить срок, в течение которого не нужно аутентифицироваться в браузере, используйте refresh-токены, позволяющие перевыпускать IAM-токены без перехода в браузер. Для этого разрешите использовать refresh-токены на уровне организации и инициализируйте DPoP-защиту в CLI.
Настройки провайдера в конфигурационном файле Terraform без указания чувствительных параметров указываются следующим образом:
provider "yandex" {
zone = "<зона_доступности_по_умолчанию>"
endpoint = "api.yandexcloud.kz:443"
storage_endpoint = "https://storage.yandexcloud.kz"
}
Где zone — зона доступности, в которой по умолчанию будут создаваться все облачные ресурсы.
С такой конфигурацией используйте Terraform без дополнительных флагов, так как провайдер автоматически подхватит их из переменных окружения.
Важно
Управление ресурсами от имени пользовательского аккаунта является менее безопасным, чем использование сервисного аккаунта.
Для аутентификации от имени пользовательского аккаунта:
-
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите.
-
В Yandex Cloud CLI создайте новый профиль или активируйте созданный ранее.
-
Аутентифицируйтесь в зависимости от типа используемого аккаунта: аккаунта на Яндексе, федеративного или локального пользователя.
-
Запишите чувствительные данные профиля: IAM-токен, идентификатор облака и каталога в переменные окружения:
BashPowerShellexport YC_TOKEN=$(yc iam create-token) export YC_CLOUD_ID=$(yc config get cloud-id) export YC_FOLDER_ID=$(yc config get folder-id)$Env:YC_TOKEN=$(yc iam create-token) $Env:YC_CLOUD_ID=$(yc config get cloud-id) $Env:YC_FOLDER_ID=$(yc config get folder-id)Где:
yc iam create-token— получение IAM-токена для текущей сессии.
yc config get cloud-id— получение идентификатора облака из текущего профиля CLI.
yc config get folder-id— получение идентификатора каталога из текущего профиля CLI.В результате в переменных окружения сохранятся IAM-токен, а также идентификатор облака и идентификатор каталога.
Примечание
При каждой операции аутентификация будет происходить с помощью этого IAM-токена, пока не истечет время его жизни (не более 12 часов). После этого снова потребуется пройти аутентификацию. Для автоматического перевыпуска IAM-токена можно использовать скрипт или другие способы автоматизации.
Чтобы продлить срок, в течение которого не нужно аутентифицироваться в браузере, используйте refresh-токены, позволяющие перевыпускать IAM-токены без перехода в браузер. Для этого разрешите использовать refresh-токены на уровне организации и инициализируйте DPoP-защиту в CLI.
Настройки провайдера в конфигурационном файле Terraform без указания чувствительных параметров указываются следующим образом:
provider "yandex" {
zone = "<зона_доступности_по_умолчанию>"
endpoint = "api.yandexcloud.kz:443"
storage_endpoint = "https://storage.yandexcloud.kz"
}
Где zone — зона доступности, в которой по умолчанию будут создаваться все облачные ресурсы.
С такой конфигурацией используйте Terraform без дополнительных флагов, так как провайдер автоматически подхватит их из переменных окружения.
Создайте файл конфигурации Terraform
-
Создайте новую директорию с произвольным названием, например
cloud-terraform. В ней будут храниться конфигурационные файлы и сохраненные состояния Terraform и инфраструктуры.Важно
Каждая конфигурация должна находиться в отдельной директории.
-
Создайте в новой директории конфигурационный файл с расширением
.tf, напримерmain.tf.
Настройте провайдер
Примечание
Настройки применимы для Terraform 0.13 и более поздних версий. Рекомендуется использовать последнюю стабильную версию Terraform.
-
Если раньше у вас был настроен провайдер из реестра HashiCorp, сохраните его настройки:
Linux/macOSWindowsmv ~/.terraformrc ~/.terraformrc.oldMove-Item $env:APPDATA\terraform.rc $env:APPDATA\terraform.rc.old -
Укажите источник, из которого будет устанавливаться провайдер.
Linux/macOSWindowsОткройте файл конфигурации Terraform CLI:
nano ~/.terraformrcПримечание
Файл
.terraformrcдолжен располагаться в корне домашней папки пользователя, например,/home/user/или/User/user/.Откройте файл конфигурации Terraform CLI
terraform.rcв папке%APPDATA%вашего пользователя.Чтобы узнать абсолютный путь к папке
%APPDATA%, выполните командуecho %APPDATA%для cmd или$env:APPDATAдля PowerShell.Добавьте в него следующий блок:
provider_installation { network_mirror { url = "https://terraform-mirror.yandexcloud.net/" include = ["registry.terraform.io/*/*"] } direct { exclude = ["registry.terraform.io/*/*"] } }Подробнее о настройках зеркал в документации
. -
В начале конфигурационного файла
.tfдобавьте следующие блоки:terraform { required_providers { yandex = { source = "yandex-cloud/yandex" } } required_version = ">= 0.13" } provider "yandex" { zone = "<зона_доступности_по_умолчанию>" endpoint = "api.yandexcloud.kz:443" storage_endpoint = "https://storage.yandexcloud.kz" }Где:
source— глобальный адрес источника провайдера.required_version— минимальная версия Terraform, с которой совместим провайдер.provider— название провайдера.zone— зона доступности, в которой по умолчанию будут создаваться все облачные ресурсы.
-
Выполните команду
terraform initв папке с конфигурационным файлом.tf. Эта команда инициализирует провайдеров, указанных в конфигурационных файлах, и позволяет работать с ресурсами и источниками данных провайдера.
Если провайдер не установился, создайте обращение в поддержку
Если вы использовали файл .terraform.lock.hcl, перед инициализацией выполните команду terraform providers lock, указав адрес зеркала, откуда будет загружаться провайдер, и платформы, на которых будет использоваться конфигурация:
terraform providers lock -net-mirror=https://terraform-mirror.yandexcloud.net -platform=<название_платформы_1> -platform=<название_платформы_2> yandex-cloud/yandex
Где:
-
-net-mirror— адрес зеркала, откуда будет загружаться провайдер. -
-platform— платформы, на которых будет использоваться конфигурация. Возможные значения:windows_amd64— 64-bit Windows.linux_amd64— 64-bit Linux.darwin_arm64— 64-bit macOS.
Если вы использовали модули Terraform, сначала выполните terraform init, затем удалите lock-файл, а затем выполните команду terraform providers lock.
Подробнее о команде terraform providers lock в документации Terraform
Подготовьте план инфраструктуры
С помощью Terraform в Yandex Cloud можно создавать облачные ресурсы разных типов, например ВМ, диски и образы. Полный список ресурсов приведен в документации провайдера.
Для каждого ресурса укажите обязательные и необязательные параметры, которые определяют его свойства. Описания ресурсов составляют план инфраструктуры.
План включает две ВМ (terraform1 и terraform2), облачную сеть network1 и подсеть subnet1.
Имена ресурсов должны соответствовать следующим требованиям:
- длина — от 3 до 63 символов;
- может содержать строчные буквы латинского алфавита, цифры и дефисы;
- первый символ — буква, последний — не дефис.
ВМ будут различаться количеством ядер и объемом памяти: у terraform1 будет два ядра и 2 ГБ оперативной памяти, а у terraform2 — четыре ядра и 4 ГБ оперативной памяти. Обе ВМ автоматически получат публичные и внутренние IP-адреса из диапазона 192.168.10.0/24. Подсеть subnet1 находится в зоне доступности kz1-d и принадлежит сети network1. Для ВМ используйте образ Ubuntu.
В конфигурации ВМ укажите идентификатор образа загрузочного диска. Получите список доступных публичных образов с помощью команды CLI:
yc compute image list --folder-id standard-images
Для доступа к ВМ по SSH сгенерируйте пару SSH-ключей и укажите путь к публичной части ключа в параметре ssh-keys блока metadata.
Ниже приведены фрагменты конфигурации провайдера и одной ВМ для разных регионов. Полные конфигурации ресурсов приведены во вкладках Linux и Windows ниже.
terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
}
}
}
provider "yandex" {
zone = "<зона_доступности_по_умолчанию>"
endpoint = "api.yandexcloud.kz:443"
storage_endpoint = "https://storage.yandexcloud.kz"
}
resource "yandex_compute_instance" "vm-1" {
name = "terraform1"
}
По плану будут созданы следующие ресурсы:
- Облачная сеть
network1с подсетьюsubnet1в зоне доступностиkz1-d. - Две виртуальные машины Linux:
terraform1(2 ядра и 2 ГБ оперативной памяти) иterraform2(4 ядра и 4 ГБ оперативной памяти). Они автоматически получат публичные и внутренние IP-адреса из диапазона192.168.10.0/24в подсетиsubnet-1.
-
Выберите образ загрузочного диска в Yandex Cloud Marketplace, например Ubuntu 22.04 LTS. Получите список доступных публичных образов с помощью команды CLI:
yc compute image list --folder-id standard-images -
Сгенерируйте пару SSH-ключей для доступа к ВМ по SSH.
-
Опишите параметры ресурсов в файле
main.tf:- В параметре
ssh-keysблокаmetadataукажите путь к публичной части SSH-ключа. - В
image_idзадайте идентификатор образа загрузочного диска.
Файл main.tf
<настройки провайдера> resource "yandex_compute_disk" "boot-disk-1" { name = "boot-disk-1" type = "network-hdd" zone = "kz1-d" size = "20" image_id = "fd806c8slu9j********" } resource "yandex_compute_disk" "boot-disk-2" { name = "boot-disk-2" type = "network-hdd" zone = "kz1-d" size = "20" image_id = "fd806c8slu9j********" } resource "yandex_compute_instance" "vm-1" { name = "terraform1" platform_id = "standard-v3" resources { cores = 2 memory = 2 } boot_disk { disk_id = yandex_compute_disk.boot-disk-1.id } network_interface { subnet_id = yandex_vpc_subnet.subnet-1.id nat = true } metadata = { ssh-keys = "ubuntu:${file("<путь_к_публичной_части_SSH-ключа>")}" } } resource "yandex_compute_instance" "vm-2" { name = "terraform2" platform_id = "standard-v3" resources { cores = 4 memory = 4 } boot_disk { disk_id = yandex_compute_disk.boot-disk-2.id } network_interface { subnet_id = yandex_vpc_subnet.subnet-1.id nat = true } metadata = { ssh-keys = "ubuntu:${file("~/.ssh/id_ed25519.pub")}" } } resource "yandex_vpc_network" "network-1" { name = "network1" } resource "yandex_vpc_subnet" "subnet-1" { name = "subnet1" zone = "kz1-d" network_id = yandex_vpc_network.network-1.id v4_cidr_blocks = ["192.168.10.0/24"] } output "internal_ip_address_vm_1" { value = yandex_compute_instance.vm-1.network_interface.0.ip_address } output "internal_ip_address_vm_2" { value = yandex_compute_instance.vm-2.network_interface.0.ip_address } output "external_ip_address_vm_1" { value = yandex_compute_instance.vm-1.network_interface.0.nat_ip_address } output "external_ip_address_vm_2" { value = yandex_compute_instance.vm-2.network_interface.0.nat_ip_address } - В параметре
По плану будут созданы следующие ресурсы:
- Облачная сеть
ya-networkс подсетьюya-networkв зоне доступности, указанной по умолчанию. - Две виртуальные машины Windows:
terraform1(2 ядра и 4 ГБ оперативной памяти) иterraform2(4 ядра и 4 ГБ оперативной памяти). Они автоматически получат публичные и внутренние IP-адреса из диапазона192.168.10.0/16в подсетиya-network.
Создайте следующие файлы:
-
main.tf— основной файл с описанием инфраструктуры.Содержимое файла main.tf
terraform { required_providers { yandex = { source = "yandex-cloud/yandex" } } } provider "yandex" { zone = var.zone } resource "yandex_vpc_network" "default" { name = var.network } resource "yandex_vpc_subnet" "default" { network_id = yandex_vpc_network.default.id name = var.subnet v4_cidr_blocks = var.subnet_v4_cidr_blocks zone = var.zone } data "yandex_compute_image" "default" { family = var.image_family } data "template_file" "default" { template = file("${path.module}/init.ps1") vars = { user_name = var.user_name user_pass = var.user_pass admin_pass = var.admin_pass } } resource "yandex_compute_instance" "vm-1" { name = "terraform1" hostname = "terraform1" zone = var.zone platform_id = "standard-v3" resources { cores = 2 memory = 4 } boot_disk { initialize_params { image_id = data.yandex_compute_image.default.id size = var.disk_size type = var.disk_type } } network_interface { subnet_id = yandex_vpc_subnet.default.id nat = var.nat } metadata = { user-data = data.template_file.default.rendered } timeouts { create = var.timeout_create delete = var.timeout_delete } } resource "yandex_compute_instance" "vm-2" { name = "terraform2" hostname = "terraform2" zone = var.zone platform_id = "standard-v3" resources { cores = 4 memory = 4 } boot_disk { initialize_params { image_id = data.yandex_compute_image.default.id size = var.disk_size type = var.disk_type } } network_interface { subnet_id = yandex_vpc_subnet.default.id nat = var.nat } metadata = { user-data = data.template_file.default.rendered } timeouts { create = var.timeout_create delete = var.timeout_delete } } output "internal_ip_address_vm_1" { value = yandex_compute_instance.vm-1.network_interface.0.ip_address } output "internal_ip_address_vm_2" { value = yandex_compute_instance.vm-2.network_interface.0.ip_address } output "external_ip_address_vm_1" { value = yandex_compute_instance.vm-1.network_interface.0.nat_ip_address } output "external_ip_address_vm_2" { value = yandex_compute_instance.vm-2.network_interface.0.nat_ip_address } -
variables.tf— файл с описанием переменных для создаваемых ресурсов.Файл variables.tf
variable "zone" { type = string default = "kz1-d" } variable "network" { type = string default = "ya-network" } variable "subnet" { type = string default = "ya-network" } variable "subnet_v4_cidr_blocks" { type = list(string) default = ["192.168.10.0/16"] } variable "nat" { type = bool default = true } variable "image_family" { type = string default = "windows-2019-dc-gvlk" } variable "disk_size" { type = number default = 50 } variable "disk_type" { type = string default = "network-nvme" } variable "user_name" { type = string default = "" } variable "user_pass" { type = string default = "" } variable "admin_pass" { type = string default = "" } variable "timeout_create" { default = "10m" } variable "timeout_delete" { default = "10m" } -
terraform.tfvars— файл, где хранятся значения переменных для создаваемых внутри ВМ учетных записей.Файл terraform.tfvars
user_name = "<my_user>" user_pass = "<my_password>" admin_pass = "<my_password>"
Создайте пользователей
Для добавления пользователей, как и для изменения многих других параметров ОС создаваемой виртуальной машины, в Yandex Cloud используется механизм cloud-initcloud-init в параметре user-data в блоке metadata. В нашем случае это будут системные пользователи:
-
Создайте текстовый файл с метаданными в кодировке UTF-8, например:
#cloud-config users: - name: <имя_пользователя> groups: sudo shell: /bin/bash sudo: 'ALL=(ALL) NOPASSWD:ALL' ssh_authorized_keys: - <публичный_SSH-ключ_1> - <публичный_SSH-ключ_2> - ...Где:
-
name— имя пользователя ВМ. -
ssh_authorized_keys— список публичных SSH-ключей для доступа к ВМ.Пример ключа:
ssh-ed25519 AAAAB3Nza...Pu00jRN.
-
-
В файле
main.tfвместоssh-keysзадайте параметрuser-dataи укажите путь к файлу с метаданными:metadata = { user-data = "${file("<путь_к_файлу>/meta.txt")}" }
Подробнее о работе с метаданными читайте в разделе Метаданные виртуальной машины.
Чтобы создать пользователя и установить пароль учетной записи Administrator на виртуальную машину в Yandex Cloud можно использовать агент cloudbase-initinit.ps1, который будет выполняться агентом при первой загрузке системы. В качестве учетных сведений будут использоваться переменные из файла variables.tf.
Файл init.ps1
#ps1
# ^^^ 'ps1' is only for cloudbase-init, some sort of sha-bang in linux
# logging
Start-Transcript -Path "$ENV:SystemDrive\provision.txt" -IncludeInvocationHeader -Force
"Bootstrap script started" | Write-Host
# inserting value's from terraform
$MyUserName = "${ user_name }"
$MyPlainTextPassword = "${ user_pass }"
if (-not [string]::IsNullOrEmpty($MyUserName) -and -not [string]::IsNullOrEmpty($MyPlainTextPassword)) {
"Create user" | Write-Host
$MyPassword = $MyPlainTextPassword | ConvertTo-SecureString -AsPlainText -Force
$MyUser = New-LocalUser -Name $MyUserName -Password $MyPassword -PasswordNeverExpires -AccountNeverExpires
$MyUser | Add-LocalGroupMember -Group 'Administrators'
$MyUser | Add-LocalGroupMember -Group 'Remote Management Users'
}
# inserting value's from terraform
$MyAdministratorPlainTextPassword = "${ admin_pass }"
if (-not [string]::IsNullOrEmpty($MyAdministratorPlainTextPassword)) {
"Set local administrator password" | Write-Host
$MyAdministratorPassword = $MyAdministratorPlainTextPassword | ConvertTo-SecureString -AsPlainText -Force
# S-1-5-21domain-500 is a well-known SID for Administrator
# https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows
$MyAdministrator = Get-LocalUser | Where-Object -Property "SID" -like "S-1-5-21-*-500"
$MyAdministrator | Set-LocalUser -Password $MyAdministratorPassword
}
"Bootstrap script ended" | Write-Host
Проверьте и отформатируйте файлы конфигураций
-
Проверьте конфигурацию командой:
terraform validateЕсли конфигурация является допустимой, появится сообщение:
Success! The configuration is valid. -
Отформатируйте файлы конфигураций в текущем каталоге и подкаталогах:
terraform fmtКоманда выводит список отформатированных файлов, например:
main.tf
Создайте ресурсы
-
После проверки конфигурации выполните команду:
terraform planТерминал выведет список ресурсов и их параметров. На этом этапе ресурсы не создаются. Если конфигурация содержит ошибки, Terraform укажет на них.
Внимание
Все созданные с помощью Terraform ресурсы тарифицируются. Внимательно проверьте план.
-
Чтобы создать ресурсы, выполните команду:
terraform apply -
Подтвердите создание ресурсов: введите в терминал слово
yesи нажмите Enter.Terraform создаст ресурсы и выведет в терминале IP-адреса созданных виртуальных машин. Проверьте наличие ресурсов и их настройки в консоли управления
.
Удалите созданные ресурсы
Чтобы удалить ресурсы, созданные с помощью Terraform:
-
Удалите из конфигурации блоки
resourceиmodule, относящиеся к этой инфраструктуре, а также источники данных и выходные значенияoutput, которые на них ссылаются. Сохраните блокиterraformиprovider. -
Проверьте план удаления:
terraform planВнимание
Terraform удалит ресурсы, для которых вы убрали описания из конфигурации: кластеры, сети, подсети, виртуальные машины и другие ресурсы.
Проверьте список ресурсов, которые Terraform собирается удалить.
-
Примените изменения:
terraform apply -
Подтвердите удаление: введите
yesи нажмите Enter.
Проверить удаление ресурсов можно в консоли управления
Полезные ссылки
- Загрузка состояний Terraform в Object Storage.
- Блокировка состояний Terraform с помощью Managed Service for YDB.
- Использование модулей Yandex Cloud в Terraform.
- Источники данных Terraform.
- IaC: Terraform — обучающий курс по управлению инфраструктурой в облаке с помощью Terraform.