Terraform — это средство для создания и управления инфраструктурой в коде, которое дает возможность развертывать, модифицировать и удалять разнообразные ресурсы в облачных сервисах, такие как виртуальные сервера, сетевые элементы, хранилища данных и т.д. Он применяет язык настроек HCL (HashiCorp Configuration Language), который имеет декларативный и понятный человеку синтаксис. HCL позволяет задавать требуемое состояние инфраструктуры с помощью секций, параметров и формул.
Преимущества использования:
По умолчанию Terraform сохраняет своё состояние в локальном файле .tfstate
. Однако при работе в команде использование локального файла усложняет работу с этим инструментом — каждый пользователь должен убедиться, что у него наиболее свежая версия файла с состоянием и что никто другой в данный момент времени не запускает создание ресурсов с аналогичным провайдером.
Механизм Remote State позволяет хранить файлы состояния в удалённом хранилище, что позволяет пользователям работать с самой свежей версией состояния и не думать о синхронизации. Terraform поддерживает следующие хранилища:
Хранение состояния настраивается в конфигурации в блоке backend
, например:
backend "s3" {
endpoint = ""
bucket = ""
…
}
Подробнее о конфигурации бэкэнда можно прочитать на сайте Terraform: Backend Configuration.
На данный момент Timeweb Cloud не поддерживает загрузку состояний в S3 для версий Terraform 1.6.0 и выше из-за изменений в структуре конфигурации.
Предварительные шаги для создания инфраструктуры.
В этой статье будут созданы:
Чтобы использовать 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
.
В настоящий момент мы поддерживаем два кластера S3: с эндпойнтом s3.timeweb.com и s3.timeweb.cloud. Проверить эндпойнт можно в панели управления в настройках бакета.
Кластер s3.timeweb.cloud
backend "s3" {
endpoint = "https://s3.timeweb.cloud"
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
}
Кластер s3.timeweb.com
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
}
}
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
сначала во второй конфигурации, а затем в первой.
Так же в 1.6 ломается работа с S3 - последняя рабочая:
required_version = "1.5.7"
Здравствуйте! Обновили скриншот в статье и добавили уточнение относительно поддерживаемых сейчас версий. Спасибо, что обратили внимание 🙂
будет ли поддержка 1.6?
Поддержка будет точно, но пока сложно сказать по срокам — ориентировочно, в первой половине этого года.
Выдержка из https://timeweb.cloud/docs/s3-storage/manage-storage#sozdanie-baketa Для доступа к данным в публичном бакете не требуется авторизация. Этот тип подойдет для хранения данных, которые могут быть доступны широкому кругу лиц.
На скриншоте явно ошибка с типом хранилища. tfstate так же хранит и пароли, если они были в конфигурации