How to add subnet delegation block for azurerm_subnet in terraform?

269 views Asked by At

I'm trying to add subnet delegation for an existing subnet using Terraform. I don't have a list of subnets, so don't really need to iterate. But it should depend on enable_delegation's boolean value. If enable_delegation is set to true, terraform plan should prompt for subnet_delegation's name and actions individually as two inputs. If enable_delegation is set to false, it should skip and continue with the plan.

main.tf:

resource "azurerm_subnet" "subnet" {
  name                 = local.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = var.virtual_network_name
  address_prefixes     = [local.subnet_address_prefixes]

  dynamic "subnet_delegation" {
    for_each = var.enable_delegation ? [1] : []
    content {
      name    = var.subnet_delegation.name
      actions = var.subnet_delegation.actions
    }
  }
  private_endpoint_network_policies_enabled     = var.private_endpoint_network_policies_enabled
  private_link_service_network_policies_enabled = var.private_link_service_network_policies_enabled
}

variables.tf:

variable "subnet_delegation" {
  type        = object({
    name  = string
    actions = list(string)
    })
  default     = {
    "name"  = "Microsoft.ContainerInstance/containerGroups"
    "actions" = ["Microsoft.Network/virtualNetworks/subnets/join/action",
        "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
        "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"]
  }
}

variable "enable_delegation" {
  type = bool
}

The other approach I tried is :

  dynamic "delegation" {
    for_each = var.subnet_delegations != null ? true : false
    content {
      name = each.value["name"]
      service_delegation {
        name    = each.value["name"]
        actions = each.value["actions"]
      }
    }
  }

Error:

│ Error: Unsupported block type │ │ on main.tf line 15, in resource "azurerm_subnet" "subnet": │ 15: dynamic "subnet_delegation" { │ │ Blocks of type "subnet_delegation" are not expected here.

This didn't work either.

Any leads on this are appreciated. Thank you for your help.

2

There are 2 answers

0
Vinay B On

I tried to add a subnet delegation block for azurerm_subnet using Terraform and I was able to provision the requirement successfully.

The error you're encountering is likely due to an incorrect usage of the dynamic block or a misconfiguration in the resource schema.

The azurerm_subnet resource does not recognize a block called subnet_delegation. This could be due to an incorrect name or a misunderstanding of how the resource is structured in the AzureRM Terraform provider.

Using the dynamic block with a conditional expression for enable_delegation is appropriate. When enable_delegation is true, the delegation block is included; otherwise, it's omitted.

My Terraform configuration:

main.tf:

provider "azurerm" {
    features {}
}

resource "azurerm_resource_group" "example" {
  name     = var.resource_group_name
  location = "East US"
}

resource "azurerm_virtual_network" "example" {
  name                = var.virtual_network_name
  address_space       = ["10.0.0.0/16"]
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
}

resource "azurerm_subnet" "subnet" {
  name                 = var.subnet_name
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = var.subnet_address_prefixes

  dynamic "delegation" {
    for_each = var.enable_delegation ? [var.subnet_delegation] : []
    content {
      name    = delegation.value.name
      service_delegation {
        name    = delegation.value.name
        actions = delegation.value.actions
      }
    }
  }
}

variable.tf:

variable "resource_group_name" {
  type = string
}

variable "virtual_network_name" {
  type = string
}

variable "subnet_name" {
  type = string
}

variable "subnet_address_prefixes" {
  type = list(string)
}

variable "enable_delegation" {
  type    = bool
  default = false
}

variable "subnet_delegation" {
  type = object({
    name    = string
    actions = list(string)
  })
  default = {
    name    = "Microsoft.ContainerInstance/containerGroups"
    actions = [
      "Microsoft.Network/virtualNetworks/subnets/join/action",
      "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
      "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"
    ]
  }
}

terraform.tfvars:

resource_group_name     = "demorg-vk"
virtual_network_name    = "vkVNet"
subnet_name             = "vkSubnet"
subnet_address_prefixes = ["10.0.1.0/24"]

enable_delegation       = true

subnet_delegation = {
  name    = "Microsoft.ContainerInstance/containerGroups"
  actions = [
    "Microsoft.Network/virtualNetworks/subnets/join/action",
    "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
    "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action"
  ]
}

Output:

enter image description here

enter image description here

0
Ritik Gupta On
dynamic "subnet_delegation" {
  for_each = var.enable_delegation ? [1] : []
  content {
    name    = var.subnet_delegation.name
    actions = var.subnet_delegation.actions
  }
}

It should be "delegation" instead of subnet_delegation. Please refer to the documentation. (Screenshot attached)

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet