Декларирование инфраструктуры — Примеры

Пример 1 — Одна переменная на входе, одно выходное значение

Окружению нужны сеть и одна машина, а регион различается между окружениями. Напишите объявление так, чтобы регион был входом, адрес машины — выходным значением, а машина подключалась к подсети, которая ссылается на сеть. Затем посмотрите, что меняется при изменении значения региона.

resource "network" "main" {
  cidr = "10.0.0.0/16"
}

resource "instance" "app" {
  network = network.main.id
  region  = "eu-west-1"
}

Решение

variable "region" {
  type    = string
  default = "eu-west-1"
}

resource "network" "main" {
  cidr   = "10.0.0.0/16"
  region = var.region
}

resource "subnet" "app" {
  network = network.main.id
}

resource "instance" "app" {
  subnet = subnet.app.id
  region = var.region
}

output "address" {
  value = instance.app.address
}
Plan: 1 to add, 0 to change, 2 to destroy

  - instance.app
  - network.main

регион входит в неизменяемые настройки сети, а инстанс ссылается
на подсеть этой сети, поэтому оба заменяются. Остановитесь здесь.

Переменная — это единственное значение, которое действительно различается между окружениями, а выходное значение — адрес, нужный кому-то после применения, и это удерживает интерфейс в две строки. Ссылка на subnet.app.id вместо скопированного идентификатора означает, что зависимость объявлена, а не подразумевается. План — это контракт: network.main — ресурс, который меняется, а неожиданное удаление — момент остановиться, а не деталь, которую надо одобрить. Ошибка — применить этот план, не прочитав его, потому что значения показались разумными.

Пример 2 — Переименование, которое план считает заменой

Блок ресурса переименовывают, чтобы локальное имя совпадало с сервисом, и больше ничего не меняется. Ниже — план после правки. Скажите, что произойдёт и как переименовать, не пересоздавая машину.

resource "instance" "api" {   # было resource "instance" "app"
  subnet = subnet.app.id
}

Решение

Plan: 1 to add, 0 to change, 1 to destroy

  + instance.api
  - instance.app

$ terraform state mv 'instance.app' 'instance.api'
$ terraform plan
No changes. Infrastructure is up to date.

Адрес ресурса — это его тип и локальное имя, а состояние связывает этот адрес с реальным объектом; новое имя — это новый адрес, поэтому старая машина предлагается к удалению, а свежая — к созданию. Перенос существующей записи на новый адрес сохраняет машину и делает следующий план пустым. Ошибка — одобрить план, потому что настройки выглядят неизменными: как только адрес перестаёт совпадать, настройки уже не важны, и работающая машина заменяется.