簡體   English   中英

Terraform:將包含字符串列表的變量傳遞給 jsonencode 部分

[英]Terraform: Pass a variable containing a list of strings to a jsonencode section

我想設置一個 Terraform 模塊,根據 Terraforms 策略分配示例策略分配給 Azure 資源。

為了分配允許位置策略,我想將允許位置列表作為字符串列表從 variables.tf 文件傳遞​​到 main.tf,在那里執行分配。

主文件

#Allowed Locations Policy Assignment 
resource "azurerm_policy_assignment" "allowedlocations" {
  name                 = "allowed-locations"
  scope                = var.scope_allowedlocations
  policy_definition_id = var.policy_allowedlocations.id 
  description          = "This policy enables you to restrict the locations."
  display_name         = "Allowed Locations"

  parameters = <<PARAMETERS
  {
  "allowedLocations": {
    "value": ${var.listofallowedlocations}
    }
  } 
  PARAMETERS

}

變量.tf

# Scope of the Allowed Locations policy
variable "scope_allowedlocations" {
  description = "The scope of the allowed locations assignment."
  default     = "Subscription"
}

# Scope of the Allowed Locations policy
variable "policy_allowedlocations" {
  description = "The allowed locations policy (created by the policy-define module)."
  default     = "default"
}

# List of the Allowed Locations
variable "listofallowedlocations" {
  type = list(string)
  description = "The allowed locations list."
  default     = [ "West Europe", "North Europe", "East US" ]
}

使用terraform plan執行會導致以下錯誤:

Error: Invalid template interpolation value

  on modules/policy-assign/main.tf line 16, in resource "azurerm_policy_assignment" "allowedlocations":
  12:
  13:
  14:
  15:
  16:     "value": ${var.listofallowedlocations}
  17:
  18:
  19:
    |----------------
    | var.listofallowedlocations is list of string with 3 elements

Cannot include the given value in a string template: string required.

因此,我不知道如何將列表從變量文件准確地傳遞到策略分配資源的 PARAMETERS 部分。 在 Terraforms 策略分配示例中,列表直接在 PARAMETERS 部分中進行了內聯編碼,並且可以正常工作。 但是沒有傳遞變量...:

parameters = <<PARAMETERS
{
  "allowedLocations": {
    "value": [ "West Europe" ]
  }
}
PARAMETERS

將值插入字符串時,該值本身必須可轉換為字符串,否則 Terraform 無法將各個部分連接在一起以生成單個字符串結果。

這里有幾種不同的選擇,具有不同的權衡。


我個人在這里選擇的選項是根本不使用<<PARAMETERS語法,而僅使用jsonencode構建整個值:

parameters = jsonencode({
  allowedLocations = {
    value = var.listofallowedlocations
  }
})

這完全避免了您的配置需要處理任何 JSON 語法問題,因此(主觀上)使意圖更清晰,未來維護更容易。

在結果是單個有效 JSON 值的任何情況下,我總是選擇使用jsonencode而不是模板語言。 為了完整起見,我將包含下面的其他選項,以防將來的讀者嘗試將集合值包含到生成 JSON 的字符串模板中。


第二種選擇是編寫一個表達式來告訴 Terraform 一種將列表值轉換為合適格式的字符串值的方法。 在您的情況下,您需要 JSON,因此再次jsonencode可能是最合適的選擇:

parameters = <<PARAMETERS
{
  "allowedLocations": {
    "value": ${jsonencode(var.listofallowedlocations)}
  }
} 
PARAMETERS

在其他非 JSON 情況下,當結果是一個簡單的字符串列表時, join函數可用於將所有字符串與固定分隔符連接在一起。

任何生成單個字符串的Terraform 函數都是這里的候選函數 “字符串函數”和“編碼函數”下的那些是最有可能的選擇。


最后,對於從集合值到結果字符串的映射是標准函數無法處理的自定義內容的情況,您可以使用模板重復語法:

parameters = <<CONFIG
%{ for port in var.ports ~}
listen 127.0.0.1:${port}
%{ endfor ~}
CONFIG

在這種情況下,Terraform 將為var.ports每個元素評估重復構造的主體,並將所有結果連接在一起以生成結果。 您可以使用這種方法生成各種文本輸出格式,但如果模板變得特別復雜,最好將其分解為單獨的文件並使用templatefile函數對其進行評估。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM