hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io
Other
42.92k stars 9.57k forks source link

allow dynamic blocks to automatically match keys #25966

Open dustindortch opened 4 years ago

dustindortch commented 4 years ago

Use-cases

In some cases repetition logic should change between iterations. For instance, if using Private Link on an Azure subnet that is different from the keys that might be more standard:

resource "azurerm_subnet" "dmz" {
    name                 = "dmz"
    resource_group_name  = azurerm_resource_group.my-rg.name
    virtual_network_name = azurerm_virtual_network.my-vnet.name
    address_prefixes     = ["10.0.0.0/27"]
}

resource "azurerm_subnet" "inside" {
    name                 = "inside"
    resource_group_name  = azurerm_resource_group.my-rg.name
    virtual_network_name = azurerm_virtual_network.my-vnet.name
    address_prefixes     = ["10.0.0.32/27"]

    enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_subnet" "bastion" {
    name                 = "AzureBastionSubnet"
    resource_group_name  = azurerm_resource_group.my-rg.name
    virtual_network_name = azurerm_virtual_network.my-vnet.name
    address_prefixes     = ["10.0.0.64/27"]
}

The usage of a for_each loop for a subnet is described here: https://www.hashicorp.com/blog/hashicorp-terraform-0-12-preview-for-and-for-each/

variable "subnets" {
  default = [
    {
      name   = "a"
      number = 1
    },
    {
      name   = "b"
      number = 2
    },
    {
      name   = "c"
      number = 3
    },
  ]
}

locals {
  base_cidr_block = "10.0.0.0/16"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.test.name
  address_space       = [local.base_cidr_block]
  location            = "West US"

  dynamic "subnet" {
    for_each = [for s in subnets: {
      name   = s.name
      prefix = cidrsubnet(local.base_cidr_block, 4, s.number)
    }]

    content {
      name           = subnet.value.name
      address_prefix = subnet.value.prefix
    }
  }
}

We have to describe the placement of everything. However, if we were to use something like the keys in a map matching the properties of the resource, we would not need to worry about anything of. Maybe just:

variable "subnets" {
  default = [
    {
      name           = "dmz"
      address_prefix = ["10.0.0.0/27"]
    },
    {
      name            = "inside"
      address_prefix  = ["10.0.0.32/27"]

      enforce_private_link_endpoint_network_policies = true
    },
    {
      name            = "AzureBastionSubnet"
      address_prefix  = ["10.0.0.64/27"]
    },
  ]
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.test.name
  address_space       = 10.0.0.0/24
  location            = "West US"

  dynamic "subnet" {
    for_each = [for * in subnets]
  }
}

Clearly, we might need logic externally for building out the map more appropriately, but if something in one of the maps in the list, then it could get applied, whereas the absence would be like leaving it absent in a standard fed

jbardin commented 4 years ago

Hi @dustindortch,

Maps and sets are unordered, so the * operator does not apply. There are some additional details and examples in the duplicate #22562

Thanks

dustindortch commented 4 years ago

I am not asking how to use it but requesting a way to do something similar.

From: James Bardin notifications@github.com Sent: Tuesday, September 22, 2020 9:01 AM To: hashicorp/terraform terraform@noreply.github.com Cc: Dustin Dortch me@dustindortch.com; Mention mention@noreply.github.com Subject: Re: [hashicorp/terraform] "Splatting" map to for_each loop (#25966)

Hi @dustindortchhttps://github.com/dustindortch,

Maps and sets are unordered, so the * operator does not apply. There are some additional details and examples in the duplicate #22562https://github.com/hashicorp/terraform/issues/22562

Thanks

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/hashicorp/terraform/issues/25966#issuecomment-696704971, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGC64ZAIGSP35ZTLHVYFT6TSHCNX5ANCNFSM4QIGS3NA.

jbardin commented 4 years ago

Thanks @dustindortch, I changed the title to match what I think you're requesting.