Использование Object Storage для работы с файлами состояния
После создания ресурсов Terraform создает файл с расширением .tfstate, в котором текущее состояние ресурсов описано в формате JSON. Он называется файлом состояния (англ. state file).
Если вы измените описание ресурсов, а затем выполните команду terraform plan, Terraform перечитает этот файл, сравнит желаемое состояние ресурсов с фактическим и выведет список нужных изменений. При выполнении команды terraform apply ресурсы, у которых желаемое состояние отличается от фактического, будут изменены. Ресурсы, которые фактически существуют в проекте, но отсутствуют в описании, будут удалены.
Чтобы организовать совместную работу, избежать конфликтов при изменении ресурсов и обеспечить интеграцию с CI/CD, файлы состояния рекомендуется помещать в удаленные хранилища. Файлы состояния можно получать из удаленного хранилища и выполнять на их основе операции с ресурсами.
Чтобы настроить хранение файлов состояний в Object Storage и выполнять с их помощью операции с ресурсами:
1. Подготовьте окружение
В веб-консоли выберите нужный проект или создайте новый.
Создайте бакет для хранения файлов состояния Terraform в сервисе Object Storage.
Создайте сервисный аккаунт и назначьте ему роль
editorили выше на проект.Создайте директорию для хранения конфигурационных файлов Terraform. Например,
terraform-config:bashmkdir terraform-config
2. Получите аутентификационные данные
- Создайте авторизованный ключ для сервисного аккаунта.
- Скачайте и сохраните файл с авторизованным ключом.
3. Настройте провайдер
Создайте файл
~/.terraformrcи укажите в нем параметры для установки провайдера:hclprovider_installation { network_mirror { url = "https://storage.mwsapis.ru/mws-terraform/", include = ["registry.terraform.io/mws-cloud/*"] } direct { exclude = ["registry.terraform.io/mws-cloud/*"] } }Создайте файл
provider.tfи добавьте в него блок с настройками провайдера:hclterraform { required_providers { mws = { source = "mws-cloud/mws" } } required_version = ">= 1.11" } provider "mws" { service_account_authorized_key_path = "<путь к файлу с авторизованным ключом>" project = "my-project" # имя проекта zone = "ru-central1-a" # зона доступности }
4. Настройте бэкенд
Создайте HMAC-ключ для сервисного аккаунта, который будет использоваться для работы с Terraform.
Создайте файл
backend.hclи добавьте в него обе части HMAC-ключа —Access keyиSecret key:hclaccess_key = "<Access key из HMAC-ключа>" secret_key = "<Secret key из HMAC-ключа>"Создайте файл
backend.tfи добавьте в него блок с настройками бэкенда:hclterraform { backend "s3" { bucket = "<имя бакета для хранения файлов состояния>" key = "<имя файла состояния>" region = "ru-central1" endpoints = { s3 = "https://storage.mwsapis.ru" } skip_region_validation = true skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true use_path_style = true use_dualstack_endpoint = false use_fips_endpoint = false } }Инициализируйте Terraform:
bashterraform init -backend-config=backend.hclЭта команда загрузит провайдер и установит соединение с Object Storage, где будут храниться файлы состояния.
5. Подготовьте план инфраструктуры
После инициализации Terraform нужно описать характеристики ресурсов, которые будут созданы с его помощью. В примере показан конфигурационный файл Terraform, на основе которого будут созданы:
- сеть с именем
example-network; - подсеть с именем
example-subnetи CIDR192.168.0.0/16; - виртуальная машина с именем
example-vm, с двумя ядрами vCPU, 4ГБ RAM, диском размером в 10 ГБ и ОС Ubuntu 24.04. Она получит внутренний IP-адрес из подсетиexample-subnet.
Чтобы создать виртуальную машину:
Добавьте в файл
main.tfсодержимое из примера ниже.Пример конфигурационного файла
hclresource "mws_vpc_network" "network" { network = "example-network" internet_access = true mtu = 1500 } resource "mws_vpc_subnet" "subnet" { subnet = "example-subnet" network = mws_vpc_network.network.network cidr = "192.168.0.0/16" } data "mws_compute_image" "image" { image = "mws-ubuntu-2404-lts-v20250529" project = "mws-ubuntu" } resource "mws_vpc_address" "vm_primary_network_interface_address" { network = mws_vpc_network.network.network subnet = mws_vpc_subnet.subnet.metadata.id address = "example-vm-primary-network-interface-address" } resource "mws_vpc_external_address" "vm_external_address" { external_address = "example-vm-external-address" } resource "mws_compute_disk" "disk" { disk = "example-disk" disk_type = "diskTypes/nbs-pl2" iops = 1000 size = "10GB" source = { image = data.mws_compute_image.image.metadata.id } } resource "mws_compute_virtual_machine" "vm" { virtual_machine = "example-vm" vm_type = "vmTypes/gen-2-8" hardware = { power = "ON" graceful_shutdown_timeout = "1m 30s" } os = { hostname = "example" local_domain = "vm" metadata = { attributes = { user-data = <cкрипт cloud-init> } } } storage = { disks = [ { name = "boot" boot = true disk = { ref = mws_compute_disk.disk.metadata.id } } ] } network = { network_interfaces = [ { name = "example-vm-network-interface-primary" primary = true addresses = [ { address = { ref = mws_vpc_address.vm_primary_network_interface_address.metadata.id } one_to_one_nat = { external = { address = { ref = mws_vpc_external_address.vm_external_address.metadata.id } } } } ] } ] } } output "network_id" { value = mws_vpc_network.network.network description = "Network ID" } output "subnet_id" { value = mws_vpc_subnet.subnet.id description = "Subnet ID" } output "internal_ip_id" { value = mws_vpc_address.vm_primary_network_interface_address.id description = "Internal IP address ID" } output "external_ip_id" { value = mws_vpc_external_address.vm_external_address.id description = "External IP address ID" }Проверьте файл
main.tfна наличие синтаксических ошибок:bashterraform validateЕсли ошибок нет, вы получите следующее сообщение:
bashSuccess! The configuration is valid.Выполните команду:
bashterraform planTerraform проверит конфигурационные файлы, сопоставит описание желаемого состояния облачной инфраструктуры с фактическим и укажет, какие операции с ресурсами будут выполнены.
6. Создайте ресурсы
Выполните команду:
bashterraform applyПодтвердите выполнение операций: введите слово
yesи нажмите Enter.Во время создания ресурсов Terraform будет выводить краткие сообщения о выполняемых операциях. Проверить, что ресурсы созданы и настроены корректно, можно в веб-консоли.
7. Проверьте сохраненное состояние
- В веб-консоли в списке сервисов выберите Object Storage.
- Нажмите на имя бакета, который вы создали ранее для хранения файлов состояния Terraform.
- Убедитесь, что в бакете появился файл с расширением
*.tfstate.
8. Получите состояние из бэкенда
Файлы состояния можно запрашивать из бэкенда и использовать при создании ресурсов. В примере ниже показано, как запросить состояние и создать еще одну виртуальную машину в подсети, созданной на предыдущем шаге.
Чтобы получить состояние и создать еще одну виртуальную машину:
Создайте новую директорию для конфигураций и перейдите в нее:
bashmkdir remote-state cd remote-stateСкопируйте в нее файл
provider.tfиз директорииterraform-config, созданной ранее:bashcp ../terraform-config/provider.tf $(pwd)Инициализируйте Terraform:
bashterraform initСоздайте файл
example.tfи добавьте конфигурацию из примера ниже. На базе этой конфигурации Terraform выполнит следующие действия:получит файл состояния из Object Storage;
получит из файла состояния информацию о сети и подсети, где нужно создать виртуальную машину;
создаст виртуальную машину с именем
example-vm2, с двумя ядрами vCPU, 4ГБ RAM, диском размером в 10 ГБ и ОС Ubuntu 24.04. Она получит внутренний IP-адрес из подсетиexample-subnet.Пример конфигурации
hcldata "terraform_remote_state" "vpc" { backend = "s3" config = { bucket = "my-terraform-states" key = "terraform.tfstate" region = "ru-central1" endpoints = { s3 = "https://storage.mwsapis.ru" } access_key = "<Access key из HMAC-ключа>" secret_key = "<Secret key из HMAC-ключа>" skip_region_validation = true skip_credentials_validation = true skip_metadata_api_check = true skip_requesting_account_id = true use_path_style = true } } data "mws_compute_image" "image" { image = "mws-ubuntu-2204-lts-v20250529" project = "mws-ubuntu" } resource "mws_vpc_address" "vm2_primary_network_interface_address" { # Получаем значения из remote state network = data.terraform_remote_state.vpc.outputs.network_id subnet = data.terraform_remote_state.vpc.outputs.subnet_id address = "example-vm2-primary-network-interface-address" } resource "mws_vpc_external_address" "vm2_external_address" { external_address = "example-vm2-external-address" } resource "mws_compute_disk" "disk2" { disk = "example-disk2" disk_type = "diskTypes/nbs-pl2" iops = 1000 size = "10GB" source = { image = data.mws_compute_image.image.metadata.id } } resource "mws_compute_virtual_machine" "vm2" { virtual_machine = "example-vm2" vm_type = "vmTypes/gen-2-8" hardware = { power = "ON" graceful_shutdown_timeout = "1m 30s" } os = { hostname = "example2" local_domain = "vm" metadata = { attributes = { user-data = "<скрипт cloud-init>" } } } storage = { disks = [ { name = "boot" boot = true disk = { ref = mws_compute_disk.disk2.metadata.id } } ] } network = { network_interfaces = [ { name = "example-vm2-network-interface-primary" primary = true addresses = [ { address = { ref = mws_vpc_address.vm2_primary_network_interface_address.metadata.id } one_to_one_nat = { external = { address = { ref = mws_vpc_external_address.vm2_external_address.metadata.id } } } } ] } ] } }
Проверьте файл
example.tfна наличие синтаксических ошибок:bashterraform validateЕсли ошибок нет, вы получите следующее сообщение:
bashSuccess! The configuration is valid.Выполните команду:
bashterraform planTerraform проверит конфигурационные файлы, сопоставит описание желаемого состояния облачной инфраструктуры с фактическим и укажет, какие операции с ресурсами будут выполнены.
Создайте вторую виртуальную машину:
bashterraform applyУбедитесь, что в созданной ранее подсети появилась виртуальная машина с именем
example-vm2.
Удалите созданные ресурсы
Ресурсы, созданные с помощью Terraform, могут тарифицироваться. Не забудьте удалить ресурсы, если вы создали их в тестовых целях, и они вам больше не нужны.
Чтобы удалить ресурсы:
Выполните команду:
bashterraform destroyПодтвердите удаление: введите слово
yesи нажмите Enter.