代码之家  ›  专栏  ›  技术社区  ›  Scott

Terraform Azure包含带有子网部署的NSG

  •  0
  • Scott  · 技术社区  · 5 月前

    我在Azure上遇到了一些困难,试图通过Terraform创建具有条件NSG关联的子网。

    我有一个带有一些子网的单个vnet,其中一些子网应该连接/分配nsgs,而另一些则不应该。

    模块代码如下:

    (注意:在这里,我试图包含一个引用,即如果调用模块提供了子网,则NSG应与子网相关联):

    子网模块

    subnets.tf

    resource "azurerm_subnet" "subnet" {
      resource_group_name               = var.resource_group_name
      virtual_network_name              = var.virtual_network_name
      name                              = var.name
      address_prefixes                  = var.address_prefixes
      private_endpoint_network_policies = var.private_endpoint_network_policies
    
      dynamic "delegation" {
        for_each = var.delegation
        content {
          name = delegation.value["delegation_name"]
          service_delegation {
            name    = delegation.value["service_delegation_name"]
            actions = delegation.value["service_delegation_actions"]
          }
        }
      }
    }
    
    # If the subnet has a NSG specified associate it
    resource "azurerm_subnet_network_security_group_association" "subnet_nsg_link" {
      count                     = var.network_security_group == null ? 0 : 1
      subnet_id                 = azurerm_subnet.subnet.id
      network_security_group_id = var.network_security_group
    }
    

    子网的变量:

    variables.tf

    variable "name" {
      type        = string
      description = "Name for subnet resource"
    }
    
    variable "resource_group_name" {
      type        = string
      description = "Resource group the subnet resource to fall under"
    }
    
    variable "virtual_network_name" {
      type        = string
      description = "Name of the virtual network this subnet will be connected with"
    }
    
    variable "address_prefixes" {
      type        = list(string)
      description = "List of ip address"
    }
    
    variable "private_endpoint_network_policies" {
      type        = string
      description = "Setting for network policy to be allowed for security group"
      default     = null
    }
    
    variable "network_security_group" {
      type        = string
      description = "Network security group id to connect with"
      default     = null
    }
    
    variable "delegation" {
      type = list(object({
        delegation_name            = string,
        service_delegation_name    = string,
        service_delegation_actions = list(string)
      }))
      description = "(Optional) The delegations for the subnet."
      default     = []
    }
    

    NSG模块:

    nsg.tf

    resource "azurerm_network_security_group" "this" {
      name                = var.name
      location            = var.location
      resource_group_name = var.resource_group_name
    
      security_rule {
        name                       = "test123"
        priority                   = 100
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "*"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
      }
    }
    

    nsg的变量:

    variables.tf

    variable "name" {
      type        = string
      description = "Name for the network security group"
    }
    
    variable "location" {
      type        = string
      description = "Azure region that the network security group resource will be created under"
    }
    
    variable "resource_group_name" {
      type        = string
      description = "Resource group the network security group will be created under"
    }
    

    我正在尝试调用该模块:

    main.tf

    # Resource group
    resource "azurerm_resource_group" "network" {
      name     = "rg-temp"
      location = "uksouth"
    }
    
    # Default NSG (empty)
    module "default" {
      source = "./modules/azure-network-security-group"
    
      name                = "nsg-default"
      location            = azurerm_resource_group.network.location
      resource_group_name = azurerm_resource_group.network.name
    }
    
    # VNETs
    # Internal vnet
    resource "azurerm_virtual_network" "vnet" {
      name                = "my-uksouth-int-vn01"
      location            = azurerm_resource_group.network.location
      resource_group_name = azurerm_resource_group.network.name
      address_space       = "10.10.10.0/24"
    
    }
    
    module "firewall_subnet" {
      source = "./modules/azure-subnet"
    
      resource_group_name  = azurerm_resource_group.network.name
      virtual_network_name = azurerm_virtual_network.vnet
      name                 = "AzureFirewallSubnet"
      address_prefixes     = "10.10.10.0/27"
    }
    
    module "vpn_subnet" {
      source = "./modules/azure-subnet"
    
      resource_group_name    = azurerm_resource_group.network.name
      virtual_network_name   = azurerm_virtual_network.vnet
      name                   = "vpnout"
      address_prefixes       = "10.10.10.32/27"
      network_security_group = module.default.id
    }
    

    前两个Azure特定子网不应有任何与之关联的NSG,但x2 VPN子网应该有。

    我希望逻辑 azurerm_subnet_network_security_group_association 子网模块中的“如果子网'network_security_group'为空,则跳过此位,否则将关联NSG ID”?

    但是当我运行代码时,我得到了这个错误:

    ╷
    │ Error: Invalid count argument
    │
    │   on modules/azure-subnet/main.tf line 22, in resource "azurerm_subnet_network_security_group_association" "sublink":
    │   22:   count                     = var.network_security_group == null ? 0 : 1
    │
    │ The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use
    │ the -target argument to first apply only the resources that the count depends on.
    ╵
    

    这似乎不是语法问题,而是排序条件问题?我不太确定该怎么办?

    有人有什么想法吗?

    谢谢。

    1 回复  |  直到 5 月前
        1
  •  1
  •   Rui Jarimba    5 月前

    “计数”值取决于在应用之前无法确定的资源属性,因此Terraform无法预测将创建多少实例。

    信息似乎很明确-您无法设置 count 具有动态值,例如由Terraform管理的另一个资源的资源id。

    考虑添加一个新的布尔变量来管理子网和NSG之间的关联:

    # other variables here
    
    # new variable
    variable "associate_network_security_group" {
      type        = bool
      description = "Associate subnet to a NSG?"
      default     = true
    }
    
    # existing variable
    variable "network_security_group" {
      type        = string
      description = "Network security group id to connect with"
      default     = null
    }
    

    使用变量:

    module "firewall_subnet" {
      source = "./modules/azure-subnet"
    
      resource_group_name  = azurerm_resource_group.network.name
      virtual_network_name = azurerm_virtual_network.vnet
      name                 = "AzureFirewallSubnet"
      address_prefixes     = "10.10.10.0/27"
    
      // use new variable here
      associate_network_security_group = false 
    }
    
    module "vpn_subnet" {
      source = "./modules/azure-subnet"
    
      resource_group_name    = azurerm_resource_group.network.name
      virtual_network_name   = azurerm_virtual_network.vnet
      name                   = "vpnout"
      address_prefixes       = "10.10.10.32/27"
    
      network_security_group = module.default.id
      // No need to set associate_network_security_group (true be default)
    }
    

    子网-NSG关联:

    resource "azurerm_subnet_network_security_group_association" "subnet_nsg_link" {
      count = var.associate_network_security_group ? 0 : 1
    
      subnet_id                 = azurerm_subnet.subnet.id
      network_security_group_id = var.network_security_group
    }
    
    推荐文章