Terraform-provider-aws: data.aws_ecs_task_definition: Falha ao obter definição de tarefa

Criado em 28 jul. 2017  ·  25Comentários  ·  Fonte: hashicorp/terraform-provider-aws

Versão Terraform

0.9.11.

  • aws_ecs_task_definition

Arquivos de configuração do 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}")}"
...
}

Comportamento esperado

se o recurso não existir, crie um novo aws_ecs_task_definition senão use a última versão do aws_ecs_task_definition

este código funciona bem no Terraform v0.9.2

Comportamento Real

: Falha ao obter a definição da tarefa ClientException: Incapaz de descrever a definição da tarefa.
código de status: 400, id de solicitação: "my-service"

Passos para reproduzir

  1. terraform apply
bug servicecs

Comentários muito úteis

Consegui contornar esse problema adicionando um "depends_on" à fonte de dados:

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

Espero que ajude.

Todos 25 comentários

também reproduzido em terraform 1.0

Também estou tendo o mesmo problema! O curioso é que ao tentar a pesquisa usando um estado vanilla (completamente vazio), o planejamento e a aplicação funcionam conforme o esperado. É apenas quando eu tenho um arquivo de estado existente que ele não funciona.

Ainda mais curioso, os recursos não existem no arquivo de estado de qualquer maneira, e ainda assim ele falha? 🤔

Mergulhando na depuração ... Notei que func dataSourceAwsEcsTaskDefinitionRead não é chamado em um projeto vanilla, mas sim em um existente. Este parece ser um padrão de terreno. Consegui reproduzir isso criando primeiro um recurso simples (um grupo de segurança) e, em seguida, tentando realizar uma pesquisa. O plano falhou quando um recurso já estava presente em um arquivo de estado (o grupo de segurança neste caso). Eu verifiquei minha hipótese criando também uma fonte de dados diferente que pesquisou um grupo de segurança inexistente. O plano para isso também falhou.

Se os argumentos de uma instância de dados não contiverem referências a valores computados, como atributos de recursos que ainda não foram criados, a instância de dados será lida e seu estado atualizado durante a fase de "atualização" do Terraform, que por padrão é executada antes de criando um plano. Isso garante que os dados recuperados estejam disponíveis para uso durante o planejamento e o diff mostrará os valores reais obtidos.

Os argumentos da instância de dados podem se referir a valores computados, caso em que os atributos da própria instância não podem ser resolvidos até que todos os seus argumentos sejam definidos. Nesse caso, a atualização da instância de dados será adiada até a fase de "aplicação" e todas as interpolações dos atributos da instância de dados serão mostradas como "computadas" no plano, uma vez que os valores ainda não são conhecidos.

Isso é duplamente interessante para mim. Com base nos documentos acima , a configuração do OP não deveria estar falhando porque data.aws_ecs_task_definition.my-service depende de aws_ecs_task_definition.my-service.family , mas está falhando na fase do plano * (meu problema também). Talvez seja um bug de nível de terraform e não um nível de provedor?

  • Editar: disse incorretamente que falhou na fase de aplicação em vez da fase de plano.

@radeksimko podemos colocar seus olhos nisso? Não quero enviar spam para o repositório principal se não for um problema de terraform.

Também estou vendo esse problema.

Na verdade, não preciso de dados e recursos para a mesma coisa no mesmo arquivo. Comentei os dados e agora parece estar funcionando melhor.

Consegui contornar esse problema adicionando um "depends_on" à fonte de dados:

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

Espero que ajude.

Não é realmente um bug, a solução do @parruda está correta. O resource aws_ecs_service e o data aws_ecs_task_definition esperam que o resource aws_ecs_task_definition já tenha sido criado.

@KIVagant isso faz sentido, pois eu também estava enfrentando o mesmo problema.

Embora eu diria que os documentos do Terraform para isso mostram o objeto data e resource sendo usados ​​juntos devem ser atualizados para refletir isso. da forma como está agora, os documentos implicam que, se o recurso não existir, nada deve falhar.

Caso contrário, as soluções

Sim, eu provavelmente deveria ter tentado a correção antes de responder, ela funciona, mas faz com que a detecção de mudança contínua ocorra.
Qual não é o resultado esperado / desejado

A correção de @parruda funcionou para mim, mas agora o depends_on explícito aciona uma atualização para minhas definições de tarefa a cada tf executado. Existe uma prática recomendada para evitar isso? Estou usando o Terraform v0.11.5
e provider.aws v1.10.0.

@dendrochronology , eu uso algo assim:

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, vou brincar com o gancho de ciclo de vida ignore_changes !

Ah, legal, vou brincar com isso também. Isso significa que eu precisaria taint manualmente ao fazer alterações no arquivo de modelo de definição de tarefa?

Depende de seus objetivos. No nosso caso, o modelo contém um espaço vazio para segredos que são preenchidos após a primeira instalação do Terraform e não queremos permitir que ele altere as definições de tarefas existentes. E nós os controlamos manualmente após a primeira instalação.

@dendrochronology desculpe pela falta de resposta. Na verdade, nunca percebi o problema porque queremos atualizar a definição da tarefa em cada execução. Espero que você tenha encontrado uma solução.

Isso ainda parece ser um problema, se você apenas usar o que está nos documentos, você obterá isto:

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'

A única coisa que mudou é que ele está dentro de um módulo e o nome é frontshop. Pode estar relacionado ao módulo?
Tentei também com o depends_on e não funcionou. Estou pensando em aplicar uma primeira versão para criar o recurso e, em seguida, usar os dados com o máximo para obter a revisão mais recente.

Na verdade, o que eu disse é mentira, parece que há um problema quando você tem um JSON inválido para definições de contêiner e o meu não está usando a sintaxe heredoc, mas um arquivo json com um modelo e deve ser uma matriz de contêineres apenas um objeto principal.
Aqui, onde eu descobri https://github.com/terraform-providers/terraform-provider-aws/issues/2026

legal @jaysonsantos. No meu caso, o erro surgiu devido a um erro de sintaxe json

Com a atualização do provedor para 1.59 e o terraform 11.11, ainda estou vendo este erro.

Se terraform destroy for concluído sem erros, ele funcionará bem sem um depends_on.

No entanto, se terraform destroy falhar em outra coisa, por exemplo:

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

Não relacionado ao serviço ECS. Algo que o terreno em execução destrua uma segunda vez resolveria. Na segunda passagem o

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

o erro reaparece e o arquivo de estado está corrompido.

Esse problema não está muito claro para mim. Parece que algumas pessoas afirmam que NÃO devemos usar um depends_on na fonte de dados para a definição da tarefa, mas na primeira execução ele sempre falha porque o recurso não existe.

Para sua informação, para todos os outros que estão tropeçando no problema: @skorfmann ilustrado neste MR https://github.com/terraform-providers/terraform-provider-aws/pull/10247 uma solução alternativa melhor usando aws_ecs_task_definition.self.revision e explica por que o discutido depends_on abordagem não é o que você quer!

Isso é uma solução para o problema de não haver uma definição de tarefa quando os recursos são implementados inicialmente. O exemplo de documentação de referência direta a "task_family" não funciona e sai com um erro ao aplicá-lo inicialmente. Veja também esta edição # 1274

O motivo é que as fontes de dados não lidam com os dados ausentes normalmente. Infelizmente, isso não será abordado, conforme declarado aqui: hashicorp / terraform # 16380 (comentário). Uma das soluções alternativas sugeridas é adicionar um depends_on explícito. No entanto, isso causa uma mudança potencial na saída do plano de terreno, embora não vá realmente mudar. Além disso, é desencorajado pela própria documentação do Terraform.

Este tópico menciona algumas outras soluções alternativas, mas nenhuma delas parece ser adequada hashicorp / terraform # 16380

aws_ecs_task_definition.self.revision só pode ser referenciado, uma vez que o recurso é criado (ao contrário da família, que já está presente no código). Aparentemente, isso permite que o Terraform resolva corretamente as dependências e faz com que a fonte de dados se comporte conforme o esperado.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

jch254 picture jch254  ·  37Comentários

darrenhaken picture darrenhaken  ·  36Comentários

takeda-joao picture takeda-joao  ·  39Comentários

hashibot picture hashibot  ·  50Comentários

jsi-p picture jsi-p  ·  33Comentários