Terraform, кажется, не подхватывает ручные изменения - PullRequest
3 голосов
/ 12 апреля 2020

У меня очень расстраивающая проблема с Terraform, я внес некоторые изменения в свой скрипт terraform, который потерпел неудачу, когда я применил план. Я прошел через кучу махинаций и, вероятно, усугубил ситуацию, поскольку в итоге я вручную удалил кучу AWS ресурсов, пытаясь решить эту проблему. Так что теперь я не могу использовать Terraform вообще (refre sh, plan, destroy), все получают ту же ошибку.

Ситуация

У меня есть список служб Fargate и набор карт, которые соотносят различные функции служб Fargate, такие как «Целевая группа» для балансировщика нагрузки ( предоставленный код ниже). Похоже, проблема в том, что Terraform не обнаруживает, что эти ресурсы были удалены вручную, или каким-то образом запутывается, потому что их не существует. В этот момент, если я запускаю refre sh, планирую или уничтожаю , я получаю сообщение об ошибке, указывающее, что указанный c список пуст, даже если он не является (или не должен быть). При неудачном запуске я добавил новую службу в список ниже вместе с новым URL-адресом (см. Код ниже)

Цель

На этом этапе я согласился бы уничтожить всю среду (это мое среда разработки), однако; в идеале я хочу, чтобы система работала так, чтобы Terraform обнаруживал изменения и работал правильно.

Сценарий Terraform действителен

Я вернул свои скрипты Terraform обратно к последней известной исправной версии. Я запустил хорошую версию для нашей промежуточной среды, и она отлично работает.

Информация о конфигурации

MacOS Mojave 10.14.6 (18G103)

Terraform v0.12.24.

  • Provider. Archive v1. v2.1.2

Файл состояния Terraform хранится в корзине S3, и был вызван terraform init --reconfigure.

Что я сделал

I Первоначально получала похожую ошибку, но она находилась в другом месте, после многих часов поиска в Google и попыток (что я не записывал) я решил вручную удалить ресурсы AWS, связанные с кодом проблематичного c ( ALB, целевые группы, группы безопасности)

Пример скрипта Terraform

К сожалению, я не могу опубликовать реальный скрипт, так как он является приватным, но я опубликовал то, что я считаю соответствующими частями, но отредактировал некоторую информацию. Причина, по которой я упоминаю это, заключается в том, что любая ошибка типа синтаксиса, которую вы можете увидеть, будет вызвана этим редактированием, как я уже говорил выше, сценарий отлично работает при запуске в нашей промежуточной среде.

globalvars.tf

В каталоге root. В случае неудачного запуска Terraform я добавил новое имя в список service_names (edd = "edd") (я добавил в качестве первого элемента). В service_name_map_2_url я добавил новую запись (edd = "edd") как последнюю запись. Я не уверен, что проблема в том, что я добавил эти элементы в другом «порядке», хотя на самом деле это не так, поскольку я получаю доступ к карте по имени, а не по индексу

variable "service_names" {
  type = list(string)
  description = "This is a list/array of the images/services for the cluster"
  default = [
    "alert",
    "alert-config"
  ]
}

variable service_name_map_2_url {
  type = map(string)
  description = "This map contains the base URL used for the service"
  default = {
    alert = "alert"
    alert-config = "alert-config"
  }
}

alb .tf

In modules/alb. В этом модуле мы создаем ALB, а затем целевую группу для каждого сервиса, который выглядит следующим образом. Элементы из globalvars.tf передаются в этот скрипт

locals {
  numberOfServices = length(var.service_names)
}

resource "aws_alb" "orchestration_alb" {
  name = "orchestration-alb"
  subnets = var.public_subnet_ids
  security_groups = [var.alb_sg_id]

  tags = {
    environment = var.environment
    group       = var.tag_group_name
    app         = var.tag_app_name
    contact     = var.tag_contact_email
  }
}

resource "aws_alb_target_group" "orchestration_tg" {
  count = local.numberOfServices
  name = "${var.service_names[count.index]}-tg"
  port = 80
  protocol = "HTTP"
  vpc_id = var.vpc_id
  target_type = "ip"
  deregistration_delay = 60
  tags = {
    environment = var.environment
    group       = var.tag_group_name
    app         = var.tag_app_name
    contact     = var.tag_contact_email
  }
  health_check {

        path = "/${var.service_name_map_2_url[var.service_names[count.index]]}/health"
        port = var.app_port
        protocol = "HTTP"
        healthy_threshold = 2
        unhealthy_threshold = 5
        interval = 30
        timeout = 5
        matcher = "200-308"
    }
}

output.tf

Это вывод alb.tf, выводятся другие вещи, но это тот, который имеет значение для этой проблемы

output "target_group_arn_suffix" {
  value = aws_alb_target_group.orchestration_tg.*.arn_suffix
}

cloudwatch.tf

In modules/cloudwatch. Я пытаюсь создать панель управления

data "template_file" "Dashboard" {
  template = file("${path.module}/dashboard.json.template")
  vars = {
  ...
   alert-tg = var.target_group_arn_suffix[0]
   alert-config-tg = var.target_group_arn_suffix[1]
   edd-cluster-name = var.ecs_cluster_name
   alb-arn-suffix = var.alb-arn-suffix
  }
}

Ошибка

Когда я запускаю terraform refresh (или планирую или уничтожаю), я получаю следующую ошибку (я получаю ту же ошибку для alert-config, что и хорошо)

Error: Invalid index

  on modules/cloudwatch/cloudwatch.tf line 146, in data "template_file" "Dashboard":
 146:     alert-tg = var.target_group_arn_suffix[0]
    |----------------
    | var.target_group_arn_suffix is empty list of string

The given key does not identify an element in this collection value.

AWS Среда

Я вручную удалил ALB. Dashboard и все Target Groups. Я ожидал (и это работало в прошлом), что Terraform обнаружит это и соответствующим образом обновит свой файл состояния, чтобы при запуске plan он знал, что должен создать ALB и целевые группы.

Спасибо

1 Ответ

1 голос
/ 14 апреля 2020

Терраформ доверяет своему состоянию как единственному источнику истины. Использование Terraform при наличии ручного изменения возможно, но проблематично c.

Если вы удаляете инфраструктуру вручную, вам нужно запустить terraform state rm [resource path] на удаленном вручную ресурсе.

Gruntwork имеет то, что они называют Золотое правило Terraform :

Основная ветвь живого репозитория должна представлять собой представление 1: 1 того, что фактически развернуто в рабочей среде. .

...