Terraform: Como evitar que a instância do AS2 ec2 seja criada antes que o NAT Gateway seja criado

6

Estou usando dois módulos. Um é um módulo VPC personalizado e o outro é um módulo para abrir uma instância do jenkins ec2.

Você não pode usar depends_on com módulos, mas o módulo Jenkins depende de certas saídas do módulo VPC da mesma forma ...

  jenkins_elb_subnets_ids                 = ["${module.vpc.public_subnets_ids[0]}", "${module.vpc.public_subnets_ids[1]}"]
  jenkins_instance_subnets_ids            = ["${module.vpc.private_subnets_ids[0]}", "${module.vpc.private_subnets_ids[1]}"]
  vpc_id                                  = "${module.vpc.vpc_id}"
  vpc_cidr                                = "${var.vpc_cidr}"

Isso ainda não impede que a instância do jenkins Ec2 seja iniciada antes que os Gateways NAT sejam criados.

�[0m�[1mmodule.jenkins.aws_launch_configuration.jenkins_lc: Creation complete after 5s (ID: devops-jenkins-lc-20180309131935169800000002)�[0m�[0m
�[0m�[1mmodule.jenkins.aws_autoscaling_group.jenkins_asg: Creating...�[0m
  arn:                            "" => "<computed>"
  default_cooldown:               "" => "<computed>"
  desired_capacity:               "" => "1"
  force_delete:                   "" => "false"
  health_check_grace_period:      "" => "300"
  health_check_type:              "" => "EC2"
  launch_configuration:           "" => "devops-jenkins-lc-20180309131935169800000002"
  load_balancers.#:               "" => "1"
  load_balancers.2235174564:      "" => "devops-jenkins-elb"
  max_size:                       "" => "1"
  metrics_granularity:            "" => "1Minute"
  min_size:                       "" => "1"
  name:                           "" => "devops-jenkins-lc-20180309131935169800000002"
  protect_from_scale_in:          "" => "false"
  tags.#:                         "" => "4"
  tags.0.%:                       "" => "3"
  tags.0.key:                     "" => "Name"
  tags.0.propagate_at_launch:     "" => "1"
  tags.0.value:                   "" => "devops-jenkins"
  tags.1.%:                       "" => "3"
  tags.1.key:                     "" => "BackupDisable"
  tags.1.propagate_at_launch:     "" => "1"
  tags.1.value:                   "" => "No"
  tags.2.%:                       "" => "3"
  tags.2.key:                     "" => "Environment"
  tags.2.propagate_at_launch:     "" => "1"
  tags.2.value:                   "" => "dev"
  tags.3.%:                       "" => "3"
  tags.3.key:                     "" => "AppComponent"
  tags.3.propagate_at_launch:     "" => "1"
  tags.3.value:                   "" => "Jenkins-master"
  target_group_arns.#:            "" => "<computed>"
  vpc_zone_identifier.#:          "" => "2"
  vpc_zone_identifier.3355635847: "" => "subnet-4f13e705"
  vpc_zone_identifier.3554579391: "" => "subnet-8e92b2d3"
  wait_for_capacity_timeout:      "" => "0"�[0m
�[0m�[1mmodule.jenkins.aws_autoscaling_group.jenkins_asg: Creation complete after 1s (ID: devops-jenkins-lc-20180309131935169800000002)�[0m�[0m
�[0m�[1mmodule.vpc.aws_vpn_gateway.transit_vgw: Still creating... (10s elapsed)�[0m�[0m
�[0m�[1mmodule.vpc.aws_route53_zone.main: Still creating... (10s elapsed)�[0m�[0m
�[0m�[1mmodule.vpc.aws_nat_gateway.private_nat_gw.1: Still creating... (10s elapsed)�[0m�[0m
�[0m�[1mmodule.vpc.aws_nat_gateway.private_nat_gw.0: Still creating... (10s elapsed)�[0m�[0m

O que resulta na falha do Jenkins em aparecer corretamente.

Cannot find a valid baseurl for repo: amzn-main/latest
Could not retrieve mirrorlist http://repo.us-east-1.amazonaws.com/latest/main/mirror.list error was
12: Timeout on http://repo.us-east-1.amazonaws.com/latest/main/mirror.list: (28, 'Connection timed out after 5001 milliseconds')
Mar 09 13:19:55 cloud-init[2581]: util.py[WARNING]: Failed to install packages: ['git', 'aws-cfn-bootstrap', 'docker', 'jq-libs', 'jq', 'perl-Test-Simple.noarch', 'perl-YAML.noarch', 'gcc', 'amazon-ssm-agent.rpm', 'perl-Switch', 'perl-DateTime', 'perl-Sys-Syslog', 'perl-LWP-Protocol-https', 'perl-Test-Simple.noarch', 'perl-YAML.noarch']

Agora o Terraform tem um módulo VPC "Oficial" da equipe da AWS. Eu olhei para o seu código e não parece fazer nada para mitigar isso? Mas com implantações de 90k e apenas 36 problemas ... não parece que eles tenham um problema. Eu não testei a si mesmo porque usá-lo não é uma opção, mas isso pode significar que o problema está nos meus módulos.

Edit: Isso não funcionou @ sysadmin1138 eu tentei isso ...

resource "aws_autoscaling_group" "jenkins_asg" {
  depends_on                = ["module.vpc.aws_nat_gateway.private_nat_gw.1", "module.vpc.aws_nat_gateway.private_nat_gw.0"]

e recebi este erro

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Error: aws_autoscaling_group.jenkins_asg: resource depends on non-existent module 'vpc.aws_nat_gateway.private_nat_gw.1'



Error: aws_autoscaling_group.jenkins_asg: resource depends on non-existent module 'vpc.aws_nat_gateway.private_nat_gw.0'

Editar2:

Eu tentei adicionar uma saída public_ip do NAT Gatway no módulo VPC como uma entrada para o módulo Jenkins. Esperando que ele aguente o módulo Jenkins até que o NAT Gateway esteja pronto e pronto. Isso não funcionou. O que observei com o Terraform e os módulos é que, a menos que você use a variável em algum lugar, como nos dados de usuário do Jenkins, a variável é completamente ignorada. Não é suficiente tê-lo como uma entrada para o módulo, ele deve ser uma entrada para um recurso nesse módulo. O efeito colateral é que, como um valor computado, ele tentará recriar seu recurso toda vez.

    
por Levi 09.03.2018 / 15:20

2 respostas

2

Obrigado ao jbardin link

Para corrigir isso, você precisa usar uma saída do seu módulo VPC. Você pode usar o aws_nat_gateway attribute public_ip , mas desde que eu criei uma rota depois de aws_nat_gateway , usei essa alternativa. Eu então fiz uma variável fictícia e um recurso simulado no meu módulo Jenkins.

resource "null_resource" "dummy" {
  provisioner "local-exec" {
    command = "echo ${var.dummy}"
  }
}

Certifique-se de atribuir essa variável dummy à saída escolhida. Também precisa ser uma string. dummy = "${join(",", module.vpc.private_nat_gw_routes)}"

Depois disso, usei depends_on = ["null_resource.dummy"] no meu recurso ASG. Isso fez com que o recurso esperasse até que as rotas do NAT Gateway + fossem criadas, mas não tem o desagradável efeito colateral de recriar o recurso toda vez.

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed
    
por 09.03.2018 / 18:22
1

Você pode não conseguir usar depends_on em um módulo, mas tenho certeza de que ainda é possível usá-lo no recurso de NAT real que o módulo cria. Dependendo da sua versão terraform, obtê-la pode ser tão simples quanto usar terraform state list e vasculhar isso, ou pesquisar manualmente seu estado de terraform para ele.

No entanto, parece que o suporte ainda não está disponível a partir da série 11.x . Versões futuras do Terraform podem, desde que um membro da equipe HashiCorp está sugerindo uma maneira de fornecer o que é claramente necessário aqui.

O núcleo do problema é que depends_on é executado em um estágio de compilação antes dos módulos serem expandidos em recursos, o que os torna inelegíveis para segmentação com esse parâmetro.

    
por 09.03.2018 / 16:17

Tags