Terraform-provider-aws: data.aws_ecs_task_definition: échec de l'obtention de la définition de la tâche

Créé le 28 juil. 2017  ·  25Commentaires  ·  Source: hashicorp/terraform-provider-aws

Version Terraform

0.9.11.

  • aws_ecs_task_definition

Fichiers de configuration 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}")}"
...
}

Comportement prévisible

si la ressource n'existe pas, créez une nouvelle définition de aws_ecs_task_definition sinon utilisez la dernière version de aws_ecs_task_definition

ce code fonctionne bien dans Terraform v0.9.2

Comportement réel

: Échec de l'obtention de la définition de la tâche ClientException: impossible de décrire la définition de la tâche.
code d'état: 400, ID de la demande: "mon-service"

Étapes à suivre pour reproduire

  1. terraform apply
bug servicecs

Commentaire le plus utile

J'ai pu contourner ce problème en ajoutant un "depend_on" à la source de données:

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

J'espère que cela aide.

Tous les 25 commentaires

également reproduit dans terraform 1.0

Je rencontre également le même problème! Ce qui est curieux, c'est que lors de la tentative de recherche en utilisant un état vanille (complètement vide), le plan et l'application fonctionnent comme prévu. Ce n'est que lorsque j'ai un fichier d'état existant que cela ne fonctionne pas.

Encore plus curieux, les ressources n'existent de toute façon pas dans le fichier d'état, et pourtant cela échoue? 🤔

Plonger dans le débogage ... J'ai remarqué que func dataSourceAwsEcsTaskDefinitionRead n'est pas appelé dans un projet vanilla, mais dans un projet existant. Cela semble être un modèle de terraforme. J'ai pu reproduire cela en créant d'abord une ressource simple (un groupe de sécurité), puis en essayant d'effectuer une recherche. Le plan a échoué lorsqu'une ressource était déjà présente dans un fichier d'état (le groupe de sécurité dans ce cas). J'ai vérifié mon hypothèse en créant également une source de données différente qui recherchait un groupe de sécurité inexistant. Le plan pour cela a également échoué.

Si les arguments d'une instance de données ne contiennent aucune référence à des valeurs calculées, telles que des attributs de ressources qui n'ont pas encore été créés, alors l'instance de données sera lue et son état mis à jour pendant la phase "d'actualisation" de Terraform, qui par défaut s'exécute avant créer un plan. Cela garantit que les données récupérées sont disponibles pour une utilisation lors de la planification et le diff affichera les valeurs réelles obtenues.

Les arguments d'instance de données peuvent faire référence à des valeurs calculées, auquel cas les attributs de l'instance elle-même ne peuvent pas être résolus tant que tous ses arguments ne sont pas définis. Dans ce cas, l'actualisation de l'instance de données sera différée jusqu'à la phase «appliquer», et toutes les interpolations des attributs d'instance de données s'afficheront comme «calculées» dans le plan car les valeurs ne sont pas encore connues.

C'est doublement intéressant pour moi. Sur la base des documents ci-dessus , la configuration d'OP ne devrait pas échouer car data.aws_ecs_task_definition.my-service dépend de aws_ecs_task_definition.my-service.family , mais elle échoue dans la phase de plan * (mon problème aussi). Peut-être s'agit-il d'un bogue au niveau terraform et non au niveau du fournisseur?

  • Edit: a déclaré à tort qu'il a échoué dans la phase d'application au lieu de la phase de plan.

@radeksimko pourrions-nous avoir vos yeux là-dessus? Je ne veux pas spammer le dépôt principal s'il ne s'agit pas d'un problème de terraform.

Je vois également ce problème.

En fait, je n'ai pas besoin de données et de ressources pour la même chose dans le même fichier. J'ai commenté les données et maintenant elles semblent mieux fonctionner.

J'ai pu contourner ce problème en ajoutant un "depend_on" à la source de données:

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

J'espère que cela aide.

Ce n'est pas vraiment un bug, la solution de @parruda est correcte. Le resource aws_ecs_service et le data aws_ecs_task_definition s'attendent tous deux à ce que les resource aws_ecs_task_definition associés soient déjà créés.

@KIVagant qui a du sens, car je rencontrais également le même problème.

Bien que je dirais que les documents Terraform pour cela montrent que l'objet data et resource utilisés ensemble devraient être mis à jour pour refléter cela. dans l'état actuel des choses, les documents impliquent que si la ressource n'existe pas, rien ne devrait échouer.

Sinon, les solutions @parruda ont du sens pour moi

Oui, j'aurais probablement dû essayer le correctif avant de répondre, cela fonctionne mais cela provoque une détection continue des changements.
Quel n'est pas le résultat attendu / souhaité

Le correctif de depends_on explicite déclenche une mise à jour de mes définitions de tâches à chaque exécution de tf. Existe-t-il une meilleure pratique pour éviter cela? J'utilise Terraform v0.11.5
et provider.aws v1.10.0.

@dendrochronology , j'utilise quelque chose comme ceci:

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 ahhh, je vais jouer avec le hook de cycle ignore_changes vie

Ah, bien, je vais jouer avec ça aussi. Cela signifierait-il que j'aurais besoin de taint manuellement lorsque je modifie le fichier de modèle de définition de tâche?

Cela dépend de vos objectifs. Dans notre cas, le modèle contient un emplacement vide pour les secrets qui se remplissent après la première installation par Terraform et nous ne voulons pas lui permettre de modifier les définitions de tâches existantes. Et nous les contrôlons manuellement après la première installation.

@dendrochronology désolé pour le manque de réponse. En fait, je n'ai jamais remarqué le problème car nous voulons mettre à jour la définition de la tâche à chaque exécution. J'espère que vous avez trouvé une solution.

Cela semble toujours être un problème, si vous utilisez simplement ce qui se trouve sur la documentation, vous obtiendrez ceci:

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'

Les seules choses qui ont changé sont que cela se trouve à l'intérieur d'un module et que le nom est frontshop. Cela pourrait-il être lié au module?
J'ai essayé aussi avec depend_on et cela ne fonctionnera pas. Je pense appliquer une première version pour créer la ressource, puis utiliser les données avec max pour obtenir la dernière révision.

En fait, ce que j'ai dit est un mensonge, il semble qu'il y ait un problème lorsque vous avez un JSON invalide pour les définitions de conteneurs et que le mien n'utilise pas la syntaxe heredoc mais un fichier json avec un modèle et cela devrait être un tableau de conteneurs et j'ai un seul objet principal.
Ici où je l'ai découvert https://github.com/terraform-providers/terraform-provider-aws/issues/2026

gentil @jaysonsantos. Dans mon cas, l'erreur est survenue à cause d'une erreur de syntaxe json

Avec une mise à niveau du fournisseur vers 1.59 et terraform 11.11, je vois toujours cette erreur.

Si terraform destroy se termine sans erreur, cela fonctionne correctement sans depend_on.

Cependant, si terraform destroy échoue sur autre chose, par exemple:

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

Sans rapport avec le service ecs. Quelque chose que l'exécution de terraform détruit une deuxième fois résoudrait autrement. Au deuxième passage, le

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

l'erreur refait surface et le fichier d'état est corrompu.

Cette question n'est pas très claire pour moi. On dirait que certaines personnes affirment que nous ne devrions PAS utiliser un depend_on dans la source de données pour la définition de la tâche mais que lors de la première exécution, cela échoue toujours car la ressource n'existe pas.

FYI pour tous les autres trébuchant sur le problème: @skorfmann illustré dans ce MR https://github.com/terraform-providers/terraform-provider-aws/pull/10247 une meilleure solution de contournement en utilisant aws_ecs_task_definition.self.revision et explique pourquoi le discuté depends_on approche

Cela permet de contourner le problème de ne pas avoir de définition de tâche lorsque les ressources sont initialement déployées. L'exemple de documentation de la référence directe à "task_family" ne fonctionne pas et se termine avec une erreur lors de son application initiale. Voir aussi ce numéro # 1274

La raison en est que les sources de données ne gèrent pas correctement les données manquantes. Malheureusement, cela ne sera pas résolu, comme indiqué ici: hashicorp / terraform # 16380 (commentaire). L'une des solutions de contournement suggérées est d'ajouter un explicatif depends_on . Cependant, cela provoque un changement potentiel dans la sortie du plan terraform, même si cela ne changera pas réellement. De plus, il est découragé par la documentation Terraform elle-même.

Ce fil mentionne quelques autres solutions de contournement, mais aucune d'entre elles ne semble convenir hashicorp / terraform # 16380

aws_ecs_task_definition.self.revision ne peut être référencé qu'une fois la ressource créée (contrairement à la famille, qui est déjà présente dans le code). Apparemment, cela permet à Terraform de résoudre correctement les dépendances et fait en sorte que la source de données se comporte comme prévu.

Cette page vous a été utile?
0 / 5 - 0 notes