Terraform

GCP Terraform:無法在雲路由器上設置要通過 BGP 通告的子網

  • June 9, 2021

我正在嘗試創建一個雲路由器,其中發布了兩個網路範圍,但是我從 terraform 中得到了一些非常模糊的錯誤,我無法完全確定出了什麼問題。

resource "google_compute_router" "router1" {
 name     = "${var.alias}-prod1-ha-vpn-cloud-router-1"
 project  = var.project_name
 network  = var.network1
 region   = var.region1
 bgp {
   asn = var.asn
   advertise_mode = "CUSTOM"
   dynamic "advertised_ip_ranges" {
     for_each = var.advertised_ip_ranges_prod1
     content {
       range = advertised_ip_ranges_prod1.value["cidr"]
       description = advertised_ip_ranges_prod1.value["desc"]
     }
   }
 }
}

以及實際的模組程式碼:

module "vpn-ha-gateway" {
 source          = "-----"
 project_name    = var.project_name
 customer        = var.customer
 alias           = var.alias
 region1         = var.region1
 count           = (var.vpn_type == "ha-vpn" ? 1 : 0)   ## Build if vpn_type is ha-vpn
 network1        = module.prod1-vpc.self_link
 customer_redundancy = var.customer_redundancy
 customer_ha_vpn_peers = var.customer_ha_vpn_peers
 shared_secret   = var.shared_secret
 asn             = var.asn
 cust_asn        = var.cust_asn
 advertised_ip_ranges_prod1      = var.advertised_ip_ranges_prod1
}

我們將 advertised_ip_ranges_prod1 定義為地圖,因為我們不知道每個模組會有多少:

variable "advertised_ip_ranges_prod1" {
 type = list(map(string))
 description = "advertised by BGP on prod1"
 default = [
   {
       cidr = "1.2.3.4/28" ## Prod1 advertised range
       desc = "secondary range advertised via BGP"
   },
   {
       cidr = "5.6.7.8/28" # Test advertised range
       desc = "Test range advertised via BGP"
   },
 ]
}

雖然我有其他以相同方式建構的模組(使用 for_each)正常工作,但這個模組不斷拋出這些模糊的錯誤:

Error: Reference to undeclared resource

 on .terraform\modules\vpn-ha\main.tf line 36, in resource "google_compute_router" "router1":
 36:         range = advertised_ip_ranges_prod1.value["cidr"]

A managed resource "advertised_ip_ranges_prod1" "value" has not been declared
in module.vpn-ha-gateway.


Error: Reference to undeclared resource

 on .terraform\modules\vpn-ha-gateway\main.tf line 37, in resource "google_compute_router" "router1":
 37:         description = advertised_ip_ranges_prod1.value["desc"]

A managed resource "advertised_ip_ranges_prod1" "value" has not been declared
in module.vpn-ha-gateway.```

所以問題(我認為)在於如何從for_each“塊”中引用動態元素的目前迭代。通常,用於引用for_each塊中目前迭代器值的“變數”的名稱實際上就是動態標籤本身的名稱。結果,我認為您需要替換它:

resource "google_compute_router" "router1" {
 name     = "${var.alias}-prod1-ha-vpn-cloud-router-1"
 project  = var.project_name
 network  = var.network1
 region   = var.region1
 bgp {
   asn = var.asn
   advertise_mode = "CUSTOM"
   dynamic "advertised_ip_ranges" {
     for_each = var.advertised_ip_ranges_prod1
     content {
       range = advertised_ip_ranges_prod1.value["cidr"]
       description = advertised_ip_ranges_prod1.value["desc"]
     }
   }
 }
}

有了這個:

resource "google_compute_router" "router1" {
 name     = "${var.alias}-prod1-ha-vpn-cloud-router-1"
 project  = var.project_name
 network  = var.network1
 region   = var.region1
 bgp {
   asn = var.asn
   advertise_mode = "CUSTOM"
   dynamic "advertised_ip_ranges" {
     for_each = var.advertised_ip_ranges_prod1
     content {
       range = advertised_ip_ranges.value["cidr"]
       description = advertised_ip_ranges.value["desc"]
     }
   }
 }
}

例如s/advertised_ip_ranges_prod1/advertised_ip_ranges/

作為參考,請參閱他們有關此的文件中的第一個範例,如下所示:

resource "aws_elastic_beanstalk_environment" "tfenvtest" {
 name                = "tf-test-name"
 application         = "${aws_elastic_beanstalk_application.tftest.name}"
 solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6"

 dynamic "setting" {
   for_each = var.settings
   content {
     namespace = setting.value["namespace"]
     name = setting.value["name"]
     value = setting.value["value"]
   }
 }
}

請注意,它們使用setting.value,即使變數的名稱是settings。您基本上遇到了完全相同的,相當混亂的差異。

引用自:https://serverfault.com/questions/1066194