На главную
Загрузка состояний 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.
Подготовка
Необходимые платные ресурсы
В этой статье будут созданы:
Создаём бакет
Чтобы использовать S3 в качестве хранилища состояния, нам необходимо создать бакет. Для этого перейдём в панель управления, в раздел «Хранилище S3».
Нажмём на кнопку «Создать». Для примера возьмём минимальную конфигурацию:
В бакете, который мы только что создали, видим настройки, которые в дальнейшем укажем в файле .tf
:
Пишем конфигурацию
Теперь приступим к написанию конфигурации.
- Добавляем папку
terraform_s3
, в которой будет наш проект. - Создаём там файл
main.tf
. - По инструкции заполняем информацию о провайдере.
Должна получиться следующая структура файлов:
├── 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 = "s3.timeweb.com"
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
}
Параметры:
endpoint
— адрес S3-хранилища из панели управления.region
— регион из панели управления.bucket
— название бакета, где буду храниться наши конфигурации.key
— путь к файлу в бакете вместе с названием файла. Например,states/<название файла>.tfstate
.access_key
иsecret_key
— ключи для доступа к бакету. Их можно получить в панели управления, на странице созданного ранее бакета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.timeweb.com"
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
:
Защита данных
В конфигурации бэкэнда параметры access_key
и secret_key
содержат чувствительные данные, которые не должны быть доступны посторонним лицам. Их не рекомендуется хранить в явном виде в файле конфигурации.
- Можно установить переменные окружения
AWS_ACCESS_KEY_ID
иAWS_SECRET_ACCESS_KEY
с соответствующими значениями ключей доступа к бакету. Тогда Terraform будет автоматически читать эти переменные при работе с бэкэндом. - Использование параметров командной строки. Можно использовать параметр
-backend-config
при выполнении командыinit
:
terraform init -backend-config="access_key=1234" -backend-config="secret_key=1234"
Создаём инфраструктуру
В файле main.tf
опишем создание виртуальной машины и локальной сети:
- Укажем ОС.
data "twc_os" "example-os" {
name = "ubuntu"
version = "22.04"
}
- Укажем пресет.
data "twc_presets" "example-preset" {
price_filter {
from = 300
to = 400
}
}
- Добавим VPC.
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
}
Содержимое конфигурации main.tf
будет выглядеть так:
terraform {
required_providers {
twc = {
source = "tf.timeweb.cloud/timeweb-cloud/timeweb-cloud"
}
}
required_version = ">= 1.5.3"
backend "s3" {
endpoint = "s3.timeweb.com"
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
:
Затем terraform plan
:
И terraform apply
:
После применения конфигурации в бакете автоматически будет создан файл состояния.
Проверка и использование состояния
В панели управления можно проверить наличие файла состояния в бакете:
Теперь попробуем использовать сохранённое состояние в другой конфигурации.
Добавим новую папку 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.timeweb.com"
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
Будет создан второй сервер в нужной локальной сети:
Чтобы удалить созданные ресурсы, выполните команду terraform destroy
сначала во второй конфигурации, а затем в первой.