【问题标题】:Omit some variables when provisioning more than one resource of a module在配置一个模块的多个资源时省略一些变量
【发布时间】:2022-03-03 07:19:22
【问题描述】:

我创建了一个用于在 Terraform 中创建子网的模块:

# modules/azure/subnet.main.tf

resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = var.virtual_network_name
  address_prefixes     = var.subnet_address_prefixes
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies

  delegation {
    name = var.subnet_delegation_name

    service_delegation {
      name    = var.subnet_service_delegation_name
    }
  }
}

然后我在另一个文件中引用它来创建 2 个子网:

# ../../../modules/azure/subnet/main.tf

locals {
  subnet_suffix = "dev-subnet"
  subnet_delegation_name = {
    public_1 = "app-service-delegation"
  }
  subnet_service_delegation_name = {
    public_1 = "Microsoft.Web/serverFarms"
  }
}

module "subnet_public_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-public-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.dev_resource_group.name
  virtual_network_name                           = data.azurerm_virtual_network.dev_virtual_network.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.public_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.public_1
  subnet_delegation_name                         = local.subnet_delegation_name.public_1
  subnet_service_delegation_name                 = local.subnet_service_delegation_name.public_1
  tag_environment                                = var.tag_environment
}

module "subnet_private_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-private-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.dev_resource_group.name
  virtual_network_name                           = data.azurerm_virtual_network.dev_virtual_network.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.private_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.private_1
  tag_environment                                = var.tag_environment
}

但是我不希望 subnet_private_1 模块具有 subnet_delegation_namesubnet_service_delegation_name 变量。所以我在模块块中省略了它们,但是当我运行terraform plan 时出现错误:

│ Error: Missing required argument
│ 
│   with module.subnet_private_1.azurerm_subnet.subnet,
│   on ../../../modules/azure/subnet/main.tf line 9, in resource "azurerm_subnet" "subnet":
│    9:     name = var.subnet_delegation_name
│ 
│ The argument "delegation.0.name" is required, but no definition was found.
╵
╷
│ Error: Missing required argument
│ 
│   with module.subnet_private_1.azurerm_subnet.subnet,
│   on ../../../modules/azure/subnet/main.tf line 12, in resource "azurerm_subnet" "subnet":
│   12:       name    = var.subnet_service_delegation_name
│ 
│ The argument "delegation.0.service_delegation.0.name" is required, but no definition was found.

我也尝试添加变量并将它们设置为null,但仍然无法正常工作:

# ../../../modules/azure/subnet/main.tf

locals {
  subnet_suffix = "dev-subnet"
}

module "subnet_public_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-public-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.dev_resource_group.name
  virtual_network_name                           = data.azurerm_virtual_network.dev_virtual_network.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.public_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.public_1
  subnet_delegation_name                         = local.subnet_delegation_name.public_1
  subnet_service_delegation_name                 = local.subnet_service_delegation_name.public_1
  tag_environment                                = var.tag_environment
}

module "subnet_private_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-private-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.dev_resource_group.name
  virtual_network_name                           = data.azurerm_virtual_network.dev_virtual_network.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.private_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.private_1
  subnet_delegation_name                         = var.subnet_delegation_name.private_1
  subnet_service_delegation_name                 = var.subnet_service_delegation_name.private_1
  tag_environment                                = var.tag_environment
}

这是我的 variables.tf 文件:

variable "subnet_name" {
  type        = string
  description = "The name of the subnet"
  default     = "mysubnet"
}

variable "resource_group_name" {
  type        = string
  description = "The name which should be used for this Resource Group."
  default     = "MyDevRG"
}

variable "virtual_network_name" {
  type        = string
  description = "The name of the virtual network"
  default     = "my-dev-vnet"
}

variable "subnet_address_prefixes" {
  type        = map(list(string))
  description = "The address prefixes to use for the subnet."
  default = {
    public_1  = ["10.1.1.0/24"],
    private_1 = ["10.1.2.0/24"]
  }
}

variable "enforce_private_link_endpoint_network_policies" {
  type        = map(bool)
  description = "Enable or Disable network policies for the private link endpoint on the subnet. Setting this to true will Disable the policy and setting this to false will Enable the policy. Default value is false"
  default = {
    public_1  = false,
    private_1 = true
  }
}

variable "subnet_delegation_name" {
  type        = map(string)
  description = "A name for this delegation"
  default = {
    public_1  = "app-service-delegation",
    private_1 = null
  }
}

variable "subnet_service_delegation_name" {
  type        = map(string)
  description = "The name of service to delegate to."
  default = {
    public_1  = "Microsoft.Web/serverFarms",
    private_1 = null
  }
}

variable "tag_environment" {
  type        = string
  description = "A mapping of tags which should be assigned to the resource."
  default     = "dev"
}

我收到了这个错误:

╷
│ Error: Missing required argument
│ 
│   with module.subnet_private_1.azurerm_subnet.subnet,
│   on ../../../modules/azure/subnet/main.tf line 9, in resource "azurerm_subnet" "subnet":
│    9:     name = var.subnet_delegation_name
│ 
│ The argument "delegation.0.name" is required, but no definition was found.
╵
╷
│ Error: Missing required argument
│ 
│   with module.subnet_private_1.azurerm_subnet.subnet,
│   on ../../../modules/azure/subnet/main.tf line 12, in resource "azurerm_subnet" "subnet":
│   12:       name    = var.subnet_service_delegation_name
│ 
│ The argument "delegation.0.service_delegation.0.name" is required, but no definition was found.

这里还有一个正在进行的对话 - null value is not treated per docs when passed to modules #24142 关于为什么 null 不能按照文档工作。

【问题讨论】:

  • “将它们设置为 null 但它仍然无法正常工作” - 你能说明你是如何做到的以及为什么它没有工作吗?
  • 能否请您分享您的变量文件?
  • 我已将 null 部分添加到问题@Marcin。您现在可以查看。
  • 我还添加了变量文件@AndriyBilous
  • 错误是关于subnet_delegation_namesubnet_service_delegation_name变量,但没有显示它们的定义。

标签: azure terraform


【解决方案1】:

在您的subnet 模块中,您有delegation 设置块不是可选的,这就是为什么在subnet_private_1subnet_public_1 中调用subnet 模块时必须指定subnet_delegation_namesubnet_service_delegation_name 变量的原因.

要使delegation 设置块可选,您应该使用Terraform dynamic Blocks

这是一个例子:

subnet 带有动态块的模块:

# modules/azure/subnet.main.tf

resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = var.virtual_network_name
  address_prefixes     = var.subnet_address_prefixes
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies

  dynamic "delegation" {
    for_each = var.delegation_settings
    content {
      name = delegation.value["subnet_delegation_name"]
      service_delegation {
      name = delegation.value["subnet_service_delegation_name"]
      }
    }
  }
}

subnet模块变量.tf:

variable "delegation_settings" {
    type = list(map(string))
    default = []
}

main.tf 示例:

terraform {
  required_version = "~> 1.0.8"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "2.81.0"
    }
  }
}

provider "azurerm" {
  features {}
}

data "azurerm_resource_group" "main" {
  name = var.resource_group_name
}

data "azurerm_virtual_network" "main" {
  name                = var.virtual_network_name
  resource_group_name = data.azurerm_resource_group.main.name
}

locals {
  subnet_suffix = "dev-subnet"
  
  delegation_settings = [{
    subnet_delegation_name         = "app-service-delegation"
    subnet_service_delegation_name = "Microsoft.Web/serverFarms"
  }]

}

module "subnet_public_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-public-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.main.name
  virtual_network_name                           = data.azurerm_virtual_network.main.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.public_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.public_1
  delegation_settings = [
    {
      subnet_delegation_name         = local.delegation_settings[0].subnet_delegation_name
      subnet_service_delegation_name = local.delegation_settings[0].subnet_service_delegation_name
    }
  ]
  tag_environment = var.tag_environment
}

module "subnet_private_1" {
  source = "../../../modules/azure/subnet"

  subnet_name                                    = "${var.subnet_name}-private-1-${local.subnet_suffix}"
  resource_group_name                            = data.azurerm_resource_group.main.name
  virtual_network_name                           = data.azurerm_virtual_network.main.name
  subnet_address_prefixes                        = var.subnet_address_prefixes.private_1
  enforce_private_link_endpoint_network_policies = var.enforce_private_link_endpoint_network_policies.private_1
  tag_environment                                = var.tag_environment
}

注意:我没有将 subnet_delegation_namesubnet_service_delegation_name 变量添加到 variables.tf example 文件中,因此 Terraform 不会抱怨在subnet_private_1 模块块。我只在我的variables.tf module 文件中添加了它们。

【讨论】:

  • 非常感谢这对我有用。欣赏它。请允许我修改您的答案以添加更多上下文。
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 2021-11-10
  • 2019-05-26
  • 1970-01-01
  • 2021-12-09
  • 2012-08-09
  • 2020-09-25
相关资源
最近更新 更多