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, например:
Подробнее о конфигурации бэкэнда можно прочитать на сайте Terraform: Backend Configuration.
На данный момент Timeweb Cloud не поддерживает загрузку состояний в S3 для версий Terraform 1.6.0 и выше из-за изменений в структуре конфигурации.
Подготовка
Предварительные шаги для создания инфраструктуры.
Необходимые платные ресурсы
В этой статье будут созданы:
Создаём бакет
Чтобы использовать S3 в качестве хранилища состояния, нам необходимо создать бакет. Для этого перейдём в панель управления, в раздел «Хранилище S3».
Нажмём на кнопку «Заказать». Для примера возьмём минимальную конфигурацию:

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

Пишем конфигурацию
Теперь приступим к написанию конфигурации.
- Добавляем папку
terraform_s3, в которой будет наш проект. - Создаём там файл
main.tf. - По инструкции заполняем информацию о провайдере.
Должна получиться следующая структура файлов:
И следующее содержимое файла main.tf:
Теперь добавим настройки бэкенда в блок terraform.
Параметры:
endpoint— адрес S3-хранилища из панели управления.region— регион из панели управления.bucket— название бакета, где буду храниться наши конфигурации.key— путь к файлу в бакете вместе с названием файла. Например,states/<название файла>.tfstate.access_keyиsecret_key— ключи для доступа к бакету. Их можно получить в панели управления, на странице созданного ранее бакетаskip_region_validationиskip_credentials_validation— флаги, с помощью которых мы пропускаем валидацию региона и ключей доступа на стороне AWS. Они нужны, так как мы используем не оригинальный AWS S3, а другое облако.
Вот пример, как должен выглядеть полный код файла main.tf:
После всех настроек выполним команду terraform init:
Защита данных
В конфигурации бэкэнда параметры access_key и secret_key содержат чувствительные данные, которые не должны быть доступны посторонним лицам. Их не рекомендуется хранить в явном виде в файле конфигурации.
- Можно установить переменные окружения
AWS_ACCESS_KEY_IDиAWS_SECRET_ACCESS_KEYс соответствующими значениями ключей доступа к бакету. Тогда Terraform будет автоматически читать эти переменные при работе с бэкэндом. - Использование параметров командной строки. Можно использовать параметр
-backend-configпри выполнении командыinit:
Создаём инфраструктуру
В файле main.tf опишем создание виртуальной машины и локальной сети:
- Укажем ОС.
- Укажем пресет.
- Добавим VPC.
- Опишем конфигурацию сервера.
- Добавим идентификатор приватной сети в выходные параметры, чтобы мы могли использовать его в других конфигурациях
Содержимое конфигурации main.tf будет выглядеть так:
Выполним команду terraform validate:
Затем terraform plan:
И terraform apply:
После применения конфигурации в бакете автоматически будет создан файл состояния.
Проверка и использование состояния
В панели управления можно проверить наличие файла состояния в бакете:
Теперь попробуем использовать сохранённое состояние в другой конфигурации.
Добавим новую папку remote-state:
Добавим файл remote-state.tf и заполним его следующим образом:
В этом примере мы используем outputs из предыдущего файла main.tf для получения идентификатора локальной сети, и добавляем в эту сеть новый VPS.
Выполним команды:
terraform initterraform validateterraform planterraform apply
Будет создан второй сервер в нужной локальной сети:
Чтобы удалить созданные ресурсы, выполните команду terraform destroy сначала во второй конфигурации, а затем в первой.