Terraform: NAT 게이트웨이가 생성되기 전에 ASG ec2 인스턴스가 나타나는 것을 방지하는 방법

Terraform: NAT 게이트웨이가 생성되기 전에 ASG ec2 인스턴스가 나타나는 것을 방지하는 방법

2개의 모듈을 사용하고 있습니다. 하나는 사용자 지정 VPC 모듈이고 다른 하나는 jenkins ec2 인스턴스를 가져오는 모듈입니다.

모듈과 함께 사용할 수는 없지만 depends_onJenkins 모듈은 다음과 같이 VPC 모듈의 특정 출력에 의존합니다.

  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}"

그래도 NAT 게이트웨이가 생성되기 전에 jenkins Ec2 인스턴스가 시작되는 것을 막지는 못합니다.

�[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

그 결과 Jenkins가 제대로 표시되지 않습니다.

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']

이제 Terraform에는 AWS 팀의 "공식" VPC 모듈이 있습니다. 코드를 살펴보았는데 이 문제를 완화하기 위해 아무 것도 하지 않는 것 같습니까? 하지만 배포 횟수가 90,000개이고 문제가 36개뿐이므로... 문제가 있는 것처럼 보이지는 않습니다. 사용하는 것은 옵션이 아니기 때문에 직접 테스트하지는 않았지만 문제가 내 모듈에 있다는 의미일 수도 있습니다.

편집: 작동하지 않았습니다 @sysadmin1138 이것을 시도했습니다...

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"]

그리고 이 오류가 발생했습니다

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'

편집2:

Jenkins 모듈에 대한 입력으로 VPC 모듈의 NAT Gatway에서 public_ip 출력을 추가해 보았습니다. NAT 게이트웨이가 작동되어 준비될 때까지 Jenkins 모듈이 유지되기를 바랍니다. 이것은 작동하지 않았습니다. Terraform과 모듈에서 관찰한 것은 Jenkins 사용자 데이터와 같은 어딘가에서 변수를 사용하지 않는 한 변수가 완전히 무시된다는 것입니다. 모듈에 대한 입력으로 사용하는 것만으로는 충분하지 않으며 해당 모듈의 리소스에 대한 입력이어야 합니다. 부작용은 계산된 값으로 매번 리소스를 다시 생성하려고 시도한다는 것입니다.

답변1

jbardin 덕분에https://github.com/hashicorp/terraform/issues/14056

이 문제를 해결하려면 VPC 모듈의 출력을 사용해야 합니다. aws_nat_gateway속성을 사용할 수 있지만 public_ip이후에 경로가 생성되었기 때문에 aws_nat_gateway대신 해당 속성을 사용했습니다. 그런 다음 Jenkins 모듈에 더미 변수와 더미 리소스를 만들었습니다.

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

dummy선택한 출력에 해당 변수를 할당했는지 확인하세요 . 또한 문자열이어야 합니다.dummy = "${join(",", module.vpc.private_nat_gw_routes)}"

그 후 depends_on = ["null_resource.dummy"]ASG 리소스를 사용했습니다. 이로 인해 해당 리소스는 NAT 게이트웨이 + 경로가 생성될 때까지 기다리게 되었지만 매번 리소스를 다시 생성하는 불쾌한 부작용은 없습니다.

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

답변2

모듈에서는 사용할 수 없을 수도 있지만 depends_on모듈이 생성하는 실제 NAT 게이트웨이 리소스에서는 계속 사용할 수 있다고 확신합니다. Terraform 버전에 따라 이를 얻는 것은 terraform state list이를 사용하고 파헤치거나 Terraform 상태 파일을 직접 검색하는 것만 큼 간단할 수 있습니다 .


그러나 그것은 보인다해당 지원은 아직 11.x 시리즈에는 없습니다.. Terraform의 향후 버전은 HashiCorp 팀 구성원이 여기서 분명히 필요한 것을 제공하는 방법을 제안하고 있기 때문에 그럴 수도 있습니다.

문제의 핵심은 depends_on모듈이 리소스로 확장되기 전 컴파일 단계에서 실행되어 해당 매개변수를 사용하여 타겟팅할 수 없다는 것입니다.

관련 정보