Terraform 茶包「value of count cannot be computed」解法

2018-08-05 Terraform

回鍋沒多久就踩到 Terraform 雷到不行的茶包,最近在設計 terraform-aws-web 這個模組的 aws_security_group_rule 時候有參考官方 terraform-aws-security-group 的寫法,在 count 的地方利用 length 去算 variable input 進來有幾個 list 進而產生多個 rule。

 

module 像是這樣判斷:

resource "aws_security_group_rule" "ingress_with_source_security_group_id" {
  count = "${length(var.web_ingress_source_security_group_id)}"

  ...
}

 

然後使用模組的時候可以這樣丟進來:

web_ingress_source_security_group_id = [
  {
    rule                     = "http-80-tcp"
    source_security_group_id = "${var.alb_sg_id}"
  },
  {
    rule                     = "https-443-tcp"
    source_security_group_id = "${var.alb_sg_id}"
  }
]

 

這樣看起來是可以彈性的建立 resource 沒錯 … 但好景不常,小弟習慣把自己建起來的整包 terraform destroy 後再 apply … 來驗證拿到另一個環境真的能動,結果 destroy 後就壞了

aws_security_group_rule.ingress_with_source_security_group_id: value of ‘count’ cannot be computed

 

count 的值不能被計算 ?

 

這個錯誤訊息很不合理,因為在 apply 的時候可以使用 length 計算出 count 的數量,但反覆驗證後發現只有在 destroy 才發生 count 無法計算的錯誤?

 

這個問題其實在「terraform modules value of count cannot be computed#12570」討論的沸沸揚揚,從 2017/03 就出現的問題留到現在 …

 

其原因是 count 只能計算已知的數值,對於不存在的數值會有問題 … 所以 destroy 就壞了

The current constraint is that count may only use values that can be known at plan time.

 

然後官方建議是不要使用有任何 dependency 的 variable,或者是用 -target 例外處理這個 resource

 

文中還有人提到用 locals 來處理 length 計算後再丟到 count,不過不曉得為什麼我用起來不能動 …

 

所以我參考 terraform-aws-security-group 的作法,額外加一個 static variable 給 count (單純覺得用 -target 會忘記),所以 module 會變這樣:

variable "web_number_of_ingress_source_security_group_id" {
  description = "The Security Group ingress number other security group source id of Web."
  default     = "0"
}

resource "aws_security_group_rule" "ingress_with_source_security_group_id" {
  count = "${var.web_number_of_ingress_source_security_group_id}"

  ...
}

 

使用 module 會麻煩一點 …

web_ingress_source_security_group_id = [
  {
    rule                     = "http-80-tcp"
    source_security_group_id = "${var.alb_sg_id}"
  },
  {
    rule                     = "https-443-tcp"
    source_security_group_id = "${var.alb_sg_id}"
  }
]

web_number_of_ingress_source_security_group_id = 2

 

如果 destroy 就會用 module 預設的 0,解法有好幾種,但都不是很好用,只能等官方解。

 

給 Mr. 沙先生一點建議

彙整

分類

展開全部 | 收合全部

License

訂閱 Mr. 沙先生 的文章

輸入你的 email 用於訂閱