发布于 2026-01-06 0 阅读
0

Terraform - 复杂变量类型

Terraform - 复杂变量类型

Terraform 变量

创建 Terraform 配置时,必须配置和声明输入变量。输入变量作为 Terraform 模块和资源的参数,允许在不更改模块自身源代码的情况下自定义模块的各个方面,并允许在不同的配置之间共享模块。

Terraform 语言使用以下几种类型作为其值:

  • string:表示某些文本的 Unicode 字符序列,例如“hello”。
  • number:数值。数字类型可以表示整数(例如 15)和分数(例如 6.283185)。
  • bool:布尔值,取值为真或假。布尔值可用于条件逻辑。
  • list(或tuple):一系列值,例如["one", "two"]。列表或元组中的元素由从零开始的连续整数标识。
  • map(或object):一组由命名标签标识的值,例如{name = "Mabel", age = 52}

字符串、数字和布尔值有时被称为基本类型。列表/元组和映射/对象有时被称为复杂类型、结构类型或集合类型。

使用原始变量类型

在以下示例中,我们创建一个基本的 Azure 资源组,并使用原始类型为每个资源参数声明一个单独的变量:

#main.tf
resource "azurerm_resource_group" "demo_rg" {
  count    = var.create_rg ? 1 : 0
  name     = var.name
  location = var.location
}
Enter fullscreen mode Exit fullscreen mode

每个变量都是单独声明的:

#variables.tf
variable "create_rg" {
    type = bool
    default = false
}

variable "name" {
    type = string
    default = "Default-RG-Name"
}

variable "location" {
    type = string
    default = "uksouth"
}
Enter fullscreen mode Exit fullscreen mode

从上面的例子中可以看出,每个资源参数都是使用原始变量类型声明的。

使用复杂变量类型

在以下示例中,我们将创建一个 Azure 资源组和两个存储帐户,但与使用基本类型单独声明每个变量不同,我们将使用复杂类型的集合。我们将使用名为 `ResourceGroup` 的单个复杂变量创建资源组,并使用名为 `StorageAccount` 的单个复杂变量对象列表创建存储帐户rg_configstorage_config

从以下变量声明中可以看出,我们仅使用对象(资源组配置)和列表对象(存储帐户配置列表)的复杂变量类型来声明每个资源的值:

#// code/variables.tf#L1-L20
#Resource Group Config - Object
variable "rg_config" {
  type = object({
    create_rg = bool
    name      = string
    location  = string
  })
}

#Storage Account Config - List of Objects (Each object represents a storage config)
variable "storage_config" {
  type = list(object({
    name                      = string
    account_kind              = string
    account_tier              = string
    account_replication_type  = string
    access_tier               = string
    enable_https_traffic_only = bool
    min_tls_version           = string
    is_hns_enabled            = bool
  }))
}
Enter fullscreen mode Exit fullscreen mode

注意:因为我们使用的是变量对象,所以我们可以直接引用并查找传入的相关对象的每个键,以获取相应的配置值,例如var.config.key

使用 COUNT 的示例

#// code/resources.tf#L6-L32
resource "azurerm_resource_group" "demo_rg" {
  count    = var.rg_config.create_rg ? 1 : 0
  name     = var.rg_config.name
  location = var.rg_config.location
  tags     = { Purpose = "Demo-RG", Automation = "true" }
}

## COUNT Example ##
resource "azurerm_storage_account" "sas" {
  count = length(var.storage_config)

  #Implicit dependency from previous resource
  resource_group_name = azurerm_resource_group.demo_rg[0].name
  location            = azurerm_resource_group.demo_rg[0].location

  #values from variable storage_config objects
  name                      = var.storage_config[count.index].name
  account_kind              = var.storage_config[count.index].account_kind
  account_tier              = var.storage_config[count.index].account_tier
  account_replication_type  = var.storage_config[count.index].account_replication_type
  access_tier               = var.storage_config[count.index].access_tier
  enable_https_traffic_only = var.storage_config[count.index].enable_https_traffic_only
  min_tls_version           = var.storage_config[count.index].min_tls_version
  is_hns_enabled            = var.storage_config[count.index].is_hns_enabled

  #Apply tags
  tags = { Purpose = "Demo-sa-${count.index + 1}", Automation = "true" }
}
Enter fullscreen mode Exit fullscreen mode

使用 FOR_EACH 的示例

resource "azurerm_resource_group" "demo_rg" {
  count    = var.rg_config.create_rg ? 1 : 0
  name     = var.rg_config.name
  location = var.rg_config.location
  tags     = { Purpose = "Demo-RG", Automation = "true" }
}

## FOR_EACH Example ##
resource "azurerm_storage_account" "sas" {
  for_each = { for each in var.storage_config : each.name => each )

  #Implicit dependency from previous resource
  resource_group_name = azurerm_resource_group.demo_rg[0].name
  location            = azurerm_resource_group.demo_rg[0].location

  #values from variable storage_config objects
  name                      = each.value.name
  account_kind              = each.value.account_kind
  account_tier              = each.value.account_tier
  account_replication_type  = each.value.account_replication_type
  access_tier               = each.value.access_tier
  enable_https_traffic_only = each.value.enable_https_traffic_only
  min_tls_version           = each.value.min_tls_version
  is_hns_enabled            = each.value.is_hns_enabled

  #Apply tags
  tags = { Purpose = "Demo-sa-${count.index + 1}", Automation = "true" }
}
Enter fullscreen mode Exit fullscreen mode

由于我们现在使用对象列表作为存储帐户的变量,因此我们可以将要创建的每个存储帐户配置为TFVARS文件中自身块内的一个对象,因此我们可以简单地向TFVARS中添加其他对象块来构建one存储many帐户,每个帐户都有不同的配置:

#// code/common.auto.tfvars.tf#L1-L30
#Resource Group Config - Object Values
rg_config = {
  create_rg = true
  name      = "Demo-Terraform-RG"
  location  = "uksouth"
}

#Storage Account Configs - List of Objects Values
storage_config = [
  #Storage Account 1 (Object1): StorageV2
  {
    name                      = "pwd9000v2sa001"
    account_kind              = "StorageV2"
    account_tier              = "Standard"
    account_replication_type  = "LRS"
    min_tls_version           = "TLS1_2"
    enable_https_traffic_only = true
    access_tier               = "Cool"
    is_hns_enabled            = false
  },
  #Storage Account 2 (object2): Azure Data Lake Storage V2 (ADLS2)
  {
    name                      = "pwd9000adls2sa001"
    account_kind              = "BlockBlobStorage"
    account_tier              = "Premium"
    account_replication_type  = "ZRS"
    min_tls_version           = "TLS1_2"
    enable_https_traffic_only = false
    access_tier               = "Hot"
    is_hns_enabled            = true
  }
]
Enter fullscreen mode Exit fullscreen mode

从最后一个例子中可以看出,使用复杂的变量类型并使我们的配置更加面向对象,可以为 Terraform 部署提供更大的灵活性和粒度。

希望您喜欢这篇文章,并从中有所收获。您也可以在我的GitHub页面上找到本文中使用的代码示例。❤️

作者

请点赞、分享并关注我的社交媒体账号:🐙 GitHub | 🐧 X | 👾 LinkedIn

文章来源:https://dev.to/pwd9000/terraform-complex-variable-types-173e