Декларирование инфраструктуры
Что это такое
Конфигурация Terraform — это набор файлов, объявляющих ресурсы, значения, которые им нужны, и значения, которые стоит сделать доступными. Ресурс — это реальная вещь у провайдера: сеть, машина, база данных, — описанная своими настройками. Переменные параметризуют конфигурацию, чтобы одно определение могло описывать несколько окружений, а выходные значения открывают то, что нужно другой конфигурации или человеку.
Почему это важно
Консоль делает любое изменение лёгким и ни одно из них — записанным. Объявление превращает изменение в diff: вы видите, что будет создано, изменено или удалено, до того как это случится, и это единственный момент, когда опасное изменение дёшево поймать. Поскольку конфигурация живёт в системе контроля версий, история окружения просматриваема, а пересборка после аварии — это применение тех же файлов, а не попытка вспомнить последовательность кликов.
Ключевые идеи
Ресурс — это объект с жизненным циклом
Объявление ресурса задаёт ему тип, локальное имя и настройки. Terraform создаёт его, записывает в состояние, а позже изменяет или удаляет по мере изменения объявления. Локальное имя — это то, как другие части конфигурации ссылаются на ресурс, поэтому переименование блока ресурса не косметика: для инструмента это может выглядеть как новый ресурс и старый, подлежащий удалению.
resource "network" "main" { ... }
resource "subnet" "app" { network = network.main.id }
План — это контракт, и его нужно читать
План перечисляет каждое действие и помечает разрушительные. Его чтение и есть весь механизм безопасности: неожиданное удаление — это момент остановиться, а не деталь, которую надо одобрить. В конвейере план стоит прикладывать к изменению для просмотра, потому что человек, который его одобряет, — последняя точка перед тем, как ресурс исчезнет.
Переменные параметризуют, выходные значения открывают
Переменные — это входы, которые различаются между окружениями; им задают значения по умолчанию и типы, чтобы конфигурацией можно было пользоваться, не читая её целиком. Выходные значения — это то, что стоит напечатать после применения, например эндпоинт или идентификатор. Небольшой интерфейс — несколько осмысленных переменных вместо десятков — это то, что делает модуль переиспользуемым, а не просто параметризованным.
Модуль упаковывает приём, и ему нужна версия
Модуль — это каталог конфигурации, который вызывают откуда-то ещё; так распространяют стандартный приём для сети или сервиса. Как только у модуля появляются потребители, его изменение меняет всех их, поэтому модуль стоит версионировать, а его интерфейс считать публичным. Модуль, оборачивающий один ресурс, добавляет косвенность и больше ничего.
Провайдеры — это граница с реальным миром
Каждый провайдер поставляет типы ресурсов и вызовы API за ними, а версии провайдера меняют поведение. Фиксация версии провайдера и осознанное обновление — вот что не даёт несвязанному изменению поменять то, как создаётся каждый ресурс.
Применение, упавшее на середине, оставляет реальные ресурсы
В отличие от программы, применение — не транзакция. Часть ресурсов существует, часть — нет, и состояние может потребовать приведения в порядок, прежде чем можно будет продолжить. Ответ — внимательно прочитать состояние и план и осознанно вернуть объявление и реальность в соответствие, а не запускать заново в надежде.
Практика
Соберите небольшое окружение из объявления
Объявите сеть и один инстанс с переменной для региона и выходным значением для адреса. Примените, затем измените регион и прочитайте план, прежде чем решать, применять ли.
Готово, когда: вы можете объяснить, что именно уничтожит изменение и почему, и остановились до его применения.
Выделяйте модуль только там, где есть повтор
Напишите второе окружение, использующее то же объявление с другими значениями, и определите, оправдан ли уже переиспользуемый модуль.
Готово, когда: вы можете назвать хотя бы двух реальных потребителей до создания модуля — или оставляете дублирование на месте.
Частые ошибки
- Применение без чтения плана — разрушительное изменение проходит незамеченным; исправить: читайте каждый план и прикладывайте его к ревью.
- Переименование блока ресурса — оно трактуется как замена, ресурс уничтожается и создаётся заново; исправить: при переименовании используйте команду переноса в состоянии.
- Незафиксированные версии провайдеров — несвязанное применение меняет то, как строятся ресурсы; исправить: фиксируйте версию и обновляйте осознанно.
- Создание модуля для одного применения — косвенность без переиспользования; исправить: выделяйте модуль, когда появился второй потребитель.
- Убеждение, что применение атомарно — частичный провал оставляет реальные ресурсы; исправить: осознанно согласуйте состояние и объявление.
Что читать дальше
- Terraform (06-cloud-devops/07-terraform) — инструмент, для которого написано это объявление.
- Состояние и планирование (06-cloud-devops/07-terraform/02-state-and-planning) — что делает план надёжным и файл, который при неаккуратном обращении приносит больше всего ущерба.