从类型为`map(object)`的子网中获取子网ID。

huangapple go评论72阅读模式
英文:

get the subnetid from subnets of type map(object)

问题

我需要从azurerm_subnet数据资源中提取subnetid,因为subnet在azurerm_virtual_network的dynamic block中使用,其类型为map(object)。

请帮助解决问题,因为我想在azurerm_virtual_network中声明subnet作为动态块,并从数据资源中获取subnet id。以下是我的terraform.tfvars:

subnets = {
  subnet1 = {
    name           = "subnet1"
    address_prefix = "10.0.0.0/24"
  }
  subnet2 = {
    name           = "subnet2"
    address_prefix = "10.0.1.0/24"
  }
  subnet3 = {
    name           = "subnet3"
    address_prefix = "10.0.2.0/24"
  }
}

从中提取第二个subnetid以将其附加到存储帐户中。

resource "azurerm_storage_account" "example" {
  count                    = length(var.subnets)
  name                     = "storageaccountname"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  network_rules {
    default_action             = "Deny"
    virtual_network_subnet_ids = ["${data.azurerm_subnet.subnetid.id}"]
  }
}

希望有人可以帮助解决这个问题,因为我想在azurerm_virtual_network中声明subnet作为动态块,并从数据资源中获取subnet id。

英文:

I need to fetch the subnetid from azurerm_subnet data resource as subnet is used in dynamic block of azurerm_virtual_network as map(object) type

resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  dynamic "subnet" {
    for_each = var.subnets
    content {
      name           = subnet.value.name
      address_prefix = subnet.value.address_prefix
      security_group = azurerm_network_security_group.example[subnet.key].id
    }
  }
}

Fetch the second subnetid to attach it to storage account

resource "azurerm_storage_account" "example" {
  count                    = length(var.subnets)
  name                     = "storageaccountname"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  network_rules {
    default_action             = "Deny"
    virtual_network_subnet_ids = ["${data.azurerm_subnet.subnetid.id}"]
  }
}

Please can any one help to solve as i want to declare subnet in azurerm_virtual_network as dynamic block and get the subnet if from the data resource and please find my terraform.tfvars as below

subnets = {
  subnet1 = {
    name           = "subnet1"
    address_prefix = "10.0.0.0/24"
  }
  subnet2 = {
    name           = "subnet2"
    address_prefix = "10.0.1.0/24"
  }
  subnet3 = {
    name           = "subnet3"
    address_prefix = "10.0.2.0/24"
  }
}

答案1

得分: 0

重要提示

在您的问题中,resource "azurerm_storage_account" "example" {} 中的 count = length(var.subnets) 仍然存在,从逻辑上来说是不正确的,正如我在评论中所指出的。

答案

根据您的评论,我假设您想在 resource "azurerm_storage_account" "example" {}network_rules 中使用 subnet2id。在您当前的方法中,创建虚拟网络资源中的子网,您必须使用 splat 表达式locals 来将 set 对象制作成映射,然后可以在需要的地方直接引用。

即使使用 localssplat 表达式 进行引用,仍然需要使用子网的名称,因为 Terraform 无法在没有数据的情况下知道您想要什么。

resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  dynamic "subnet" {
    for_each = var.subnets

    content {
      name           = subnet.value.name
      address_prefix = subnet.value.address_prefix
      # security_group = azurerm_network_security_group.example[subnet.key].id ## 我已经忽略它,因为没有共享相关代码###
    }
  }
}

locals {
  subnets = { for subnet in azurerm_virtual_network.example.subnet : subnet.name => subnet }
}

resource "azurerm_storage_account" "example" {
  #count                    = length(var.subnets) ## 我也删除了它,因为与当前代码在逻辑上不正确##
  name                     = "storageaccountname"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  network_rules {
    default_action             = "Deny"
    virtual_network_subnet_ids = [local.subnets.subnet2.id]
  }

当在根模块中引用一个资源/模块的属性到另一个资源/模块时,您不需要使用数据源。

然而,我建议使用 azurerm_subnet 资源,以便更容易引用,而不是在虚拟网络资源本身创建子网,因为您可能需要在子网中使用 Microsoft.Storage service_endpoints 来使用 network_rules 来处理存储帐户。

英文:

IMPORTANT

count = length(var.subnets) in resource "azurerm_storage_account" "example" {} is still there in your question which is logically incorrect as I have stated in the comments.

Answer

With your comments, I am assuming that you want to use id of subnet2 in network_rules of resource "azurerm_storage_account" "example" {}. With your current approach where creating subnets within the virtual network resource you have to use splat expressions and locals to make a map out of the set object and then can directly refer wherever is required.

> While doing referencing even with locals and splat expressions it is still required to use the name of the subnet as it is not possible for terraform to know what you want without any data.

resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  dynamic "subnet" {
    for_each = var.subnets

    content {
      name           = subnet.value.name
      address_prefix = subnet.value.address_prefix
      # security_group = azurerm_network_security_group.example[subnet.key].id ## I have ignored it as no relevant code is shared### 
    }
  }
}

locals {
  subnets = { for subnet in azurerm_virtual_network.example.subnet : subnet.name => subnet }
}

resource "azurerm_storage_account" "example" {
  #count                    = length(var.subnets) ## Removed it too as logically incorrect with the current code ##
  name                     = "storageaccountname"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"

  network_rules {
    default_action             = "Deny"
    virtual_network_subnet_ids = [local.subnets.subnet2.id]
  }

You do not need a data source when referencing the attributes from one resource/module to another resource/module in the root module.

However, I suggest using azurerm_subnet resource for easier reference in spite of creating subnets in the virtual network resource itself because your might need Microsoft.Storage service_endpoints in your subnets for working with storage account with network_rules.

huangapple
  • 本文由 发表于 2023年2月18日 20:19:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493295.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定