Terraform с динамическим списком c будет воссоздавать ресурсы при изменении индекса - PullRequest
0 голосов
/ 07 февраля 2020

При использовании динамического списка c, если запись добавляется или удаляется, каждая запись, следующая за измененным индексом, будет обновляться.
Как сделать так, чтобы terraform вставил только новую запись?

Пример

У меня есть список

  • 10
  • 20
  • 30

(применяется терраформ)

Теперь измените мой список, добавив 15

  • 10
  • 15
  • 20
  • 30

(применяется терраформ) Terraform собирается заменить 20 -> 15, 30 -> 20 и создать 30

Простое решение

Одно из решений объявление всех элементов по отдельности (без использования списка)

Комплексное решение

Перед применением я мог напрямую изменить файл состояния для изменения индексов. Это кажется опасным.

Больше контекста

У меня есть файл данных json с сотнями записей DNS. Я загружаю это в список, используя data.external

data "external" "read_dns_entries" {
   program = [ "${path.module}/terraform_script_dns_entries_from_file" ]
}

locals {
  file_dns_records_without_aliases = jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias)
}

resource "aws_route53_record" "record" {
  count = length(local.file_dns_records_without_aliases)

  zone_id         = local.file_dns_records_without_aliases[count.index].ZoneID
  name            = local.file_dns_records_without_aliases[count.index].Name
  type            = local.file_dns_records_without_aliases[count.index].Type
  allow_overwrite = true
  ttl             = local.file_dns_records_without_aliases[count.index].TTL
  records         = local.file_dns_records_without_aliases[count.index].Records

  lifecycle {
    create_before_destroy = true
  }
}

Я использую Terraform v0.12.18

Ссылки

Этот закрытый вопрос говорит об этом. https://github.com/hashicorp/terraform/issues/3449

Он надеялся, что Terraform 0.12 исправит это с помощью for_each
Бесполезны ли "петли" terraform? Или я что-то упустил?

1 Ответ

0 голосов
/ 24 марта 2020

Если вы можете использовать Terraform 0.12.x или новее, рассмотрите вариант выбора

  1. for_each вместо count
  2. карты вместо списка для представления входных данных (поскольку for_each работает на картах)

Карту можно составить из списка с выражением { for item in list: key => value } (см. https://www.terraform.io/docs/configuration/expressions.html#for -выражения ). В отличие от count, который отслеживает ресурсы по позиции, for_each отслеживает представление ресурса в состоянии по id (ключ карты). Поскольку позиции постоянно меняются / меняются по мере того, как новые ресурсы вставляются или удаляются, полагаться на эту довольно хрупкую структуру не приходится. Вот почему можно было бы заметить, что многие операции уничтожения / создания выполняются на плане после случайного перемещения, вставки или удаления в списке ресурсов;).

Для записи приведен фрагмент кода настройки очистки:

data "external" "read_dns_entries" {
  program = ["${path.module}/terraform_script_dns_entries_from_file"]
}

locals {
  #file_dns_records_without_aliases = jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias)
  file_dns_records_without_aliases = {
    for entry in jsondecode(data.external.read_dns_entries.result.EntriesWithoutAlias) :
    entry.Name => entry
  }
}

resource "aws_route53_record" "record" {
  # count = length(local.file_dns_records_without_aliases)
  for_each = local.file_dns_records_without_aliases

  zone_id         = each.value.ZoneID
  name            = each.value.Name
  type            = each.value.Type
  allow_overwrite = true
  ttl             = each.value.TTL
  records         = each.value.Records

  lifecycle {
    create_before_destroy = true
  }
}

PS: Похоже, что data.external не совсем идиоматически используется здесь, и аргументация с использованием file("${path.module}/terraform_script_dns_entries_from_file") была бы более понятной, поскольку целью является просто чтение содержимого файла.

...