Terraform-provider-aws: data.aws_ecs_task_definition: Не удалось получить определение задачи

Созданный на 28 июл. 2017  ·  25Комментарии  ·  Источник: hashicorp/terraform-provider-aws

Версия Terraform

0.9.11.

  • aws_ecs_task_definition

Файлы конфигурации Terraform

data "aws_ecs_task_definition" "my-service" {
  task_definition = "${aws_ecs_task_definition.my-service.family}"
}

resource "aws_ecs_task_definition" "my-service" {
  family                = "${var.environment_name}-${var.service_name}-${var.instance_name}"
  network_mode          = "bridge"
  container_definitions = "${data.template_file.my-service.rendered}"
}

resource "aws_ecs_service" "my-service" {
 ...
  #Track the latest ACTIVE revision
  task_definition = "${aws_ecs_task_definition.my-services.family}:${max("${aws_ecs_task_definition.my-service.revision}", "${data.aws_ecs_task_definition.my-service.revision}")}"
...
}

Ожидаемое поведение

если ресурс не существует, создайте новый aws_ecs_task_definition, иначе используйте последнюю версию aws_ecs_task_definition

этот код отлично работает в Terraform v0.9.2

Фактическое поведение

: Не удалось получить определение задачи. ClientException: невозможно описать определение задачи.
код состояния: 400, идентификатор запроса: "my-service"

Действия по воспроизведению

  1. terraform apply
bug servicecs

Самый полезный комментарий

Мне удалось обойти эту проблему, добавив к источнику данных «depends_on»:

resource "aws_ecs_task_definition" "task" {
...
}
data "aws_ecs_task_definition" "task" {
  depends_on = [ "aws_ecs_task_definition.task" ]
  ...
}

Надеюсь, поможет.

Все 25 Комментарий

также воспроизводится в terraform 1.0

У меня такая же проблема! Что любопытно, при попытке поиска с использованием ванильного состояния (полностью пустого) план и применение работают должным образом. Только когда у меня есть существующий файл состояния, он не работает.

Что еще более любопытно, ресурсов в файле состояния все равно не существует, и все же он не работает? 🤔

Погружаясь в отладку ... Я заметил, что func dataSourceAwsEcsTaskDefinitionRead не вызывается в обычном проекте, а вызывается в существующем. Это похоже на узор терраформирования. Я смог воспроизвести это, создав сначала простой ресурс (группу безопасности), а затем попытавшись выполнить поиск. План не удался, когда ресурс уже присутствовал в файле состояния (в данном случае группа безопасности). Я проверил свою гипотезу, также создав другой источник данных, который искал несуществующую группу безопасности. План на это тоже не удался.

Если аргументы экземпляра данных не содержат ссылок на вычисленные значения, такие как атрибуты ресурсов, которые еще не были созданы, то экземпляр данных будет прочитан и его состояние будет обновлено во время фазы «обновления» Terraform, которая по умолчанию выполняется до создание плана. Это гарантирует, что полученные данные будут доступны для использования во время планирования, а разница покажет реальные полученные значения.

Аргументы экземпляра данных могут относиться к вычисленным значениям, и в этом случае атрибуты самого экземпляра не могут быть разрешены, пока не будут определены все его аргументы. В этом случае обновление экземпляра данных будет отложено до фазы «применения», и все интерполяции атрибутов экземпляра данных будут отображаться в плане как «вычисленные», поскольку значения еще не известны.

Мне это интересно вдвойне. Основываясь на приведенных выше документах , конфигурация OP не должна давать сбой, потому что data.aws_ecs_task_definition.my-service зависит от aws_ecs_task_definition.my-service.family , но не работает на этапе плана * (моя проблема тоже). Возможно, это ошибка на уровне терраформ, а не на уровне провайдера?

  • Изменить: неправильно сказано, что это не удалось на этапе применения, а не на этапе планирования.

@radeksimko, мы могли бы

Я тоже вижу эту проблему.

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

Мне удалось обойти эту проблему, добавив к источнику данных «depends_on»:

resource "aws_ecs_task_definition" "task" {
...
}
data "aws_ecs_task_definition" "task" {
  depends_on = [ "aws_ecs_task_definition.task" ]
  ...
}

Надеюсь, поможет.

На самом деле это не ошибка, решение от @parruda правильное. Оба resource aws_ecs_service и data aws_ecs_task_definition ожидают, что связанные resource aws_ecs_task_definition уже должны быть созданы.

@KIVagant, это имеет смысл, так как я тоже столкнулся с той же проблемой.

Хотя я бы сказал, что документы Terraform для этого показывают, что data объект и resource используются вместе, должны быть обновлены, чтобы отразить это. в его нынешнем виде документ подразумевает, что если ресурс не существует, ничего не должно произойти.

В противном случае решения @parruda имеют для меня смысл

Я, вероятно, должен был попробовать исправление, прежде чем отвечать, оно работает, но вызывает постоянное обнаружение изменений.
Что не является ожидаемым / желаемым результатом

Исправление @parruda сработало для меня, но теперь явный depends_on запускает обновление моих определений задач при каждом запуске tf. Есть ли лучший способ предотвратить это? Я использую Terraform v0.11.5
и provider.aws v1.10.0.

@dendrochronology , я использую что-то вроде этого:

data "aws_ecs_task_definition" "blabla" {
  task_definition = "${aws_ecs_task_definition.blabla.family}"
  depends_on = [ "aws_ecs_task_definition.blabla" ]
}


resource "aws_ecs_task_definition" "..." {
  family                = "..."
  task_role_arn         = "${aws_iam_role.blabla.arn}"

  container_definitions = "${data.template_file.task_definition.rendered}"

  depends_on = [
    "data.template_file.task_definition",
  ]

  lifecycle {
    ignore_changes = [
      "container_definitions" # if template file changed, do nothing, believe that human's changes are source of truth
    ]
  }
}


resource "aws_ecs_service" "blabla" {
  name            = "blabla"
  cluster         = "${aws_ecs_cluster.cluster_name.id}"
  task_definition = "${aws_ecs_task_definition.blabla.family}:${max("${aws_ecs_task_definition.blabla.revision}", "${data.aws_ecs_task_definition.blabla.revision}")}"
  desired_count   = 1
  iam_role        = "${aws_iam_role.ecs_service.name}"

// Not compatible with placement_constraints:distinctInstance, commented
//  placement_strategy {
//    type  = "binpack"
//    field = "cpu"
//  }

  placement_constraints {
    type  = "distinctInstance"
  }

  load_balancer {
    elb_name       = "${aws_elb.blabla.name}"
    container_name = "internal"
    container_port = "${var.blabla_port}"
  }

  depends_on = [
    "aws_iam_role.ecs_service",
    "aws_elb.blabla",
    "aws_iam_role.blabla",
    "aws_ecs_task_definition.blabla"
  ]

  lifecycle {
    ignore_changes = ["task_definition"] # the same here, do nothing if it was already installed
  }
}

@KIVagant аааа , я собираюсь поиграть с крючком жизненного цикла ignore_changes !

Ах, хорошо, я тоже поиграю с этим. Означает ли это, что мне нужно вручную taint , когда я внесу изменения в файл шаблона определения задачи?

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

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

Это все еще кажется проблемой, если вы просто используете то, что указано в документации, вы получите следующее:

Error: Error running plan: 1 error(s) occurred:

* module.frontshop_staging.data.aws_ecs_task_definition.frontshop: 1 error(s) occurred:

* module.frontshop_staging.data.aws_ecs_task_definition.frontshop: Resource 'aws_ecs_task_definition.frontshop' not found for variable 'aws_ecs_task_definition.frontshop.family'

Единственное, что изменилось, это то, что он находится внутри модуля и называется frontshop. Может быть, это связано с модулем?
Я также пробовал с зависимым_on, и это не сработает. Я подумываю применить первую версию для создания ресурса, а затем использовать данные с max, чтобы получить последнюю версию.

На самом деле, то, что я сказал, является ложью, похоже, есть проблема, когда у вас есть недопустимый JSON для определений контейнеров, а мой не использует синтаксис heredoc, а json-файл с шаблоном, и это должен быть массив контейнеров, и у меня только один главный объект.
Вот где я об этом узнал https://github.com/terraform-providers/terraform-provider-aws/issues/2026

хороший @jaysonsantos. В моем случае ошибка возникла из-за ошибки синтаксиса json

После обновления провайдера до 1.59 и terraform 11.11 я все еще вижу эту ошибку.

Если уничтожение terraform завершается без ошибок, он отлично работает и без зависимости.

Однако, если terraform destroy не работает, например, на другом:

 Error removing user, role, or group list from IAM Policy Detach bootstrap-iam-group-attach1:
– NoSuchEntity

Не имеет отношения к службе ecs. То, что запускает терраформ, уничтожает второй раз, иначе разрешится. На втором проходе

Failed getting task definition ClientException: Unable to describe task definition.

ошибка появляется снова, и файл состояния поврежден.

Мне этот вопрос не очень понятен. Похоже, некоторые люди утверждают, что мы НЕ должны использовать зависимый_on в источнике данных для определения задачи, но при первом запуске он всегда терпит неудачу, потому что ресурс не существует.

К вашему сведению для всех, кто споткнулся о проблеме: @skorfmann, проиллюстрированный в этом MR https://github.com/terraform-providers/terraform-provider-aws/pull/10247, лучший обходной путь с использованием aws_ecs_task_definition.self.revision и объясняет, почему обсуждаемый подход depends_on - это не то, что вам нужно!

Это позволяет решить проблему отсутствия определения задачи при первоначальном развертывании ресурсов. Пример документации с прямой ссылкой на "task_family" не работает и завершается с ошибкой при первоначальном применении. См. Также этот выпуск №1274.

Причина в том, что источники данных плохо обрабатывают отсутствующие данные. К сожалению, это не будет рассматриваться, как указано здесь: hashicorp / terraform # 16380 (комментарий). Один из предлагаемых обходных путей - добавить явный depends_on . Однако это приводит к потенциальному изменению вывода плана терраформирования, хотя на самом деле это не изменится. Кроме того, сама документация Terraform обескураживает.

В этой ветке упоминается несколько других обходных путей, но ни один из них не кажется подходящим hashicorp / terraform # 16380

aws_ecs_task_definition.self.revision можно ссылаться только после создания ресурса (в отличие от семейства, которое уже присутствует в коде). По-видимому, это позволяет Terraform правильно разрешать зависимости и заставляет источник данных вести себя так, как ожидалось.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги