Terraform:如何防止 ASG ec2 實例在建立 NAT 閘道之前出現

Terraform:如何防止 ASG ec2 實例在建立 NAT 閘道之前出現

我正在使用 2 個模組。一個是自訂 VPC 模組,另一個是用於啟動 jenkins ec2 實例的模組。

您不能depends_on與模組一起使用,但 Jenkins 模組確實依賴 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}"

這仍然不會阻止 jenkins Ec2 實例在建立 NAT 網關之前啟動。

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

這導致詹金斯無法正常出現。

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 模組。我查看了它的程式碼,它似乎沒有做任何事情來緩解這個問題?但在 90k 部署和只有 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:

我嘗試新增 VPC 模組中 NAT 網關的 public_ip 輸出作為 Jenkins 模組的輸入。希望它能夠支援 Jenkins 模組,直到 NAT 網關啟動並準備就緒。這不起作用。我在 Terraform 和模組中觀察到的是,除非您在某個地方使用該變量,例如在 Jenkins 用戶資料中,否則該變數將完全忽略。將其作為模組的輸入是不夠的,它必須是該模組中資源的輸入。副作用是,作為計算值,它每次都會嘗試重新建立您的資源。

答案1

感謝傑巴爾丁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在模組擴展為資源之前的編譯階段運行,這使得它們沒有資格使用該參數進行定位。

相關內容