Истории успеха наших клиентов — лучшие проекты
Вход/ Регистрация

Загрузка состояний Terraform в Object Storage

Terraform — это средство для создания и управления инфраструктурой в коде, которое дает возможность развертывать, модифицировать и удалять разнообразные ресурсы в облачных сервисах, такие как виртуальные сервера, сетевые элементы, хранилища данных и т.д. Он применяет язык настроек HCL (HashiCorp Configuration Language), который имеет декларативный и понятный человеку синтаксис. HCL позволяет задавать требуемое состояние инфраструктуры с помощью секций, параметров и формул.

Преимущества использования: 

  • Вы можете запустить одинаковый код Terraform на различных платформах и получать одинаковые результаты. 
  • Вы можете разделять свою инфраструктуру на отдельные модули и использовать их в разных задачах. 
  • Вы можете работать с разными облачными провайдерами и услугами с помощью единого интерфейса. 
  • Вы можете сохранять свой код настроек в системе управления версиями и отслеживать изменения по времени. 
  • Вы можете работать над своей инфраструктурой в команде и согласовывать свои действия с помощью удаленного хранилища состояний.

Remote State

По умолчанию Terraform сохраняет своё состояние в локальном файле .tfstate. Однако при работе в команде использование локального файла усложняет работу с этим инструментом — каждый пользователь должен убедиться, что у него наиболее свежая версия файла с состоянием и что никто другой в данный момент времени не запускает создание ресурсов с аналогичным провайдером.

Механизм Remote State позволяет хранить файлы состояния в удалённом хранилище, что позволяет пользователям работать с самой свежей версией состояния и не думать о синхронизации. Terraform поддерживает следующие хранилища:

  • Terraform Cloud
  • HashiCorp Consul
  • Amason S3 (или другое S3-совместимое хранилище)
  • Google Cloud Storage
  • Azure Blob Storage
  • многие другие

Хранение состояния настраивается в конфигурации в блоке backend, например:

    
backend "s3" {      endpoint   = ""      bucket     = ""     …   }

Подробнее о конфигурации бэкэнда можно прочитать на сайте Terraform: Backend Configuration.

На данный момент Timeweb Cloud не поддерживает загрузку состояний в S3 для версий Terraform 1.6.0 и выше из-за изменений в структуре конфигурации.

Подготовка

Предварительные шаги для создания инфраструктуры.

Необходимые платные ресурсы

В этой статье будут созданы:

  • Две виртуальные машины (тарифы)
  • Один бакет Object Storage (тарифы)
  • Одна локальная сеть

Создаём бакет

Чтобы использовать S3 в качестве хранилища состояния, нам необходимо создать бакет. Для этого перейдём в панель управления, в раздел «Хранилище S3».

Image6

Нажмём на кнопку «Заказать». Для примера возьмём минимальную конфигурацию:

Screenshot 04 17 25 16:47:13

На вкладке «Дашборд» бакета, который мы только что создали, отображаются настройки, которые позже укажем в файле .tf:

Selection 255

Пишем конфигурацию

Теперь приступим к написанию конфигурации. 

  1. Добавляем папку terraform_s3, в которой будет наш проект.
  2. Создаём там файл main.tf.
  3. По инструкции заполняем информацию о провайдере.

Должна получиться следующая структура файлов:

    
├── terraform_s3 │   ├── main.tf

И следующее содержимое файла main.tf:

    
terraform {   required_providers {     twc = {       source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"     }   }   required_version = ">= 1.5.3" } provider "twc" {   token = "<your token>" }

Теперь добавим настройки бэкенда в блок terraform.

    
backend "s3" {      endpoint = "https://s3.twcstorage.ru"      region = "ru-1"      bucket = "<bucket name>"      key = "states/terraform.tfstate"      access_key = "<your access key>"      secret_key = "<your secret key>"      skip_region_validation = true      skip_credentials_validation = true      skip_metadata_api_check = true      skip_requesting_account_id = true      skip_s3_checksum = true    }

Параметры:

  1. endpoint — адрес S3-хранилища из панели управления.
  2. region — регион из панели управления.
  3. bucket — название бакета, где буду храниться наши конфигурации.
  4. key — путь к файлу в бакете вместе с названием файла. Например, states/<название файла>.tfstate.
  5. access_key и secret_key — ключи для доступа к бакету. Их можно получить в панели управления, на странице созданного ранее бакета
  6. skip_region_validation и skip_credentials_validation — флаги, с помощью которых мы пропускаем валидацию региона и ключей доступа на стороне AWS. Они нужны, так как мы используем не оригинальный AWS S3, а другое облако.

Вот пример, как должен выглядеть полный код файла main.tf:

    
terraform {   required_providers {     twc = {       source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"     }   }   required_version = ">= 1.5.3"   backend "s3" {   endpoint = "s3.twcstorage.ru"     region = "ru-1"     bucket = "<bucket name>"     key  = "states/terraform.tfstate"     access_key = "<your access key>"     secret_key = "<your secret key>"     skip_region_validation = true     skip_credentials_validation = true     } } provider "twc" {   token = "<your token>" }

После всех настроек выполним команду terraform init:

Image1

Защита данных

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

  1. Можно установить переменные окружения AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY с соответствующими значениями ключей доступа к бакету. Тогда Terraform будет автоматически читать эти переменные при работе с бэкэндом.
  2. Использование параметров командной строки. Можно использовать параметр -backend-config при выполнении команды init:
    
terraform init -backend-config="access_key=1234" -backend-config="secret_key=1234" 

Создаём инфраструктуру

В файле main.tf опишем создание виртуальной машины и локальной сети:

  1. Укажем ОС.
    
data "twc_os" "example-os" {   name = "ubuntu"  version = "22.04" }
  1. Укажем пресет.
    
data "twc_presets" "example-preset" {   price_filter {     from = 300     to = 400   } }
  1. Добавим VPC.
    
resource "twc_vpc" "example-vpc" {   name = "Example VPC"   description = "Some example VPC"   subnet_v4 = "192.168.0.0/24"   location = "ru-1" }
  1. Опишем конфигурацию сервера.
    
resource "twc_server" "example-server-with-local-network" {   name = "Example server with local network"   os_id = data.twc_os.example-os.id   preset_id = data.twc_presets.example-preset.id   local_network {     id = twc_vpc.example-vpc.id   } }
  1. Добавим идентификатор приватной сети в выходные параметры, чтобы мы могли использовать его в других конфигурациях
    
output "tw-vpc" {     value = twc_vpc.example-vpc.id }

Содержимое конфигурации main.tf будет выглядеть так:

    
terraform {   required_providers {     twc = {       source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"     }   }   required_version = ">= 1.5.3"   backend "s3" {   endpoint = "s3.twcstorage.ru"     region = "ru-1"     bucket = "<bucket name>"     key  = "states/terraform.tfstate"     access_key = "<your access key>"     secret_key = "<your secret key>"     skip_region_validation = true     skip_credentials_validation = true     } } provider "twc" {   token = "<your token>" } data "twc_os" "example-os" {   name = "ubuntu"   version = "22.04" } data "twc_presets" "example-preset" {   price_filter {     from = 300     to = 400   } } resource "twc_vpc" "example-vpc" {   name = "Example VPC"   description = "Some example VPC"   subnet_v4 = "192.168.0.0/24"   location = "ru-1" } resource "twc_server" "example-server-with-local-network" {   name = "Example server with local network"   os_id = data.twc_os.example-os.id   preset_id = data.twc_presets.example-preset.id   local_network {     id = twc_vpc.example-vpc.id   } } output "tw-vpc" {     value = twc_vpc.example-vpc.id }

Выполним команду terraform validate:

D067189e 35ec 4bc3 8060 765d5f9ffb79

Затем terraform plan:

A8ecc713 91cf 44ab 9110 E1fd97806e32

И terraform apply:

41ef13cf F6e3 42c9 B98b 0ceacdb3b9dd

После применения конфигурации в бакете автоматически будет создан файл состояния.

Проверка и использование состояния

В панели управления можно проверить наличие файла состояния в бакете:

Image7

Теперь попробуем использовать сохранённое состояние в другой конфигурации. 

Добавим новую папку remote-state:

    
mkdir remote-state cd remote-state

Добавим файл remote-state.tf и заполним его следующим образом:

    
terraform {   required_providers {     twc = {       source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"     }   }   required_version = ">= 1.5.3" } provider "twc" {   token = "<your token>" } data "terraform_remote_state" "vpc" {   backend = "s3"     config = {   endpoint = "s3.twcstorage.ru"     region = "ru-1"     bucket = "<bucket name>"     key  = "states/terraform.tfstate"     skip_region_validation = true     skip_credentials_validation = true     access_key = "<your access key>"     secret_key = "<your secret key>"     } } data "twc_os" "example-os" {   name = "ubuntu"   version = "22.04" } data "twc_presets" "example-preset" {   price_filter {     from = 300     to = 400   } } resource "twc_server" "example-server-with-local-network" {   name = "Example server with local network"   os_id = data.twc_os.example-os.id   preset_id = data.twc_presets.example-preset.id   local_network {     id = data.terraform_remote_state.vpc.outputs.tw-vpc   } }

В этом примере мы используем outputs из предыдущего файла main.tf для получения идентификатора локальной сети, и добавляем в эту сеть новый VPS.

Выполним команды:

  • terraform init
  • terraform validate
  • terraform plan 
  • terraform apply

Будет создан второй сервер в нужной локальной сети:

Image4

Чтобы удалить созданные ресурсы, выполните команду terraform destroy сначала во второй конфигурации, а затем в первой.

Полезные ссылки

Была ли статья полезна?
Ваша оценка очень важна
Пока нет комментариев