Search code examples
azureterraformvirtual-machinedatabricksterraform-provider-azure

Terraform avoid deletion of additional subnet resources


I have 2 terraform scripts. One of them creates an Azure VM with a network and 1 subnet. The second TF script creates databricks and 2 additional subnets in the Azure VM network to connect both Databricks and VM.

The problem is that after the first apply everything works well. But after the second the terraform is want to delete 2 additional subnets.

My question is how to prevent the deletion of 2 additional subnets?

VM part of the creation network and one subnet:

resource "azurerm_virtual_network" "neo4j_virt_network" {
  name                = "neo4j-virtnetwork-${var.env}-${var.location}-001"
  address_space       = ["10.0.0.0/16"]
  location            = var.location
  resource_group_name = var.resource_group

  subnet {
    name           = "neo4j-virtnetwork-subnet-${var.env}-${var.location}-001"
    address_prefix = "10.0.1.0/24"
    security_group = azurerm_network_security_group.neo4j_sg.id
  }

  tags = local.tags
}

Databricks part of creating 2 additional subnets:

resource "azurerm_subnet" "private" {
  name = "databricks-dev-northeurope-001-private"
  resource_group_name  = var.resource_group
  virtual_network_name = azurerm_virtual_network.neo4j_virt_network.name
  address_prefixes     = ["10.0.3.0/24"]

  delegation {
    name = "databricks-delegation"

    service_delegation {
      name = "Microsoft.Databricks/workspaces"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
        "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
        "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action",
      ]
    }
  }
}

resource "azurerm_network_security_group" "private" {
  name = "databricks-dev-northeurope-001-private-sg"
  resource_group_name = var.resource_group
  location            = var.location
}

resource "azurerm_subnet_network_security_group_association" "private" {
  subnet_id                 = azurerm_subnet.private.id
  network_security_group_id = azurerm_network_security_group.private.id
}

resource "azurerm_subnet" "public" {
  name = "databricks-dev-northeurope-001-public"
  resource_group_name  = var.resource_group
  virtual_network_name = azurerm_virtual_network.neo4j_virt_network.name
  address_prefixes     = ["10.0.5.0/24"]

  delegation {
    name = "databricks-delegation"

    service_delegation {
      name = "Microsoft.Databricks/workspaces"
      actions = [
        "Microsoft.Network/virtualNetworks/subnets/join/action",
        "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action",
        "Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action",
      ]
    }
  }
}

resource "azurerm_network_security_group" "public" {
  name = "databricks-dev-northeurope-001-public-sg"
  resource_group_name = var.resource_group
  location            = var.location
}

resource "azurerm_subnet_network_security_group_association" "public" {
  subnet_id                 = azurerm_subnet.public.id
  network_security_group_id = azurerm_network_security_group.public.id
}

resource "azurerm_databricks_workspace" "databricks" {
  name                 = "databricks-${var.env}-${var.location}-001"
  resource_group_name  = var.resource_group
  location             = var.location
  sku                  = "standard"

  managed_resource_group_name = "${var.company_name}-rg-databricks-workspace-${var.env}-${var.location}-001"

  custom_parameters {
    machine_learning_workspace_id                        = azurerm_machine_learning_workspace.ml_workspace.id
    storage_account_name                                 = "databrick${var.env}${random_string.db_code.result}"
    virtual_network_id                                   = azurerm_virtual_network.neo4j_virt_network.id
    public_subnet_name                                   = azurerm_subnet.public.name
    public_subnet_network_security_group_association_id  = azurerm_subnet_network_security_group_association.public.id
    private_subnet_name                                  = azurerm_subnet.private.name
    private_subnet_network_security_group_association_id = azurerm_subnet_network_security_group_association.private.id
  }

  depends_on = [
    azurerm_subnet_network_security_group_association.public,
    azurerm_subnet_network_security_group_association.private,
  ]

  tags = local.tags
}

Message from debug about that quantity of subnets changed in network object:

2022-11-10T09:28:12.050+0200 [WARN]  Provider "registry.terraform.io/hashicorp/azurerm" produced an unexpected new value for module.dev.azurerm_virtual_network.neo4j_virt_network during refresh.
      - .subnet: actual set element cty.ObjectVal(map[string]cty.Value{"address_prefix":cty.StringVal("10.0.3.0/24"), "id":cty.StringVal("[...]"), "name":cty.StringVal("databricks-dev-northeurope-001-private"), "security_group":cty.StringVal("[...]")}) does not correlate with any element in plan
      - .subnet: actual set element cty.ObjectVal(map[string]cty.Value{"address_prefix":cty.StringVal("10.0.5.0/24"), "id":cty.StringVal("[...]"), "name":cty.StringVal("databricks-dev-northeurope-001-public"), "security_group":cty.StringVal("[...]")}) does not correlate with any element in plan
      - .subnet: length changed from 1 to 3

Solution

  • Don't use subnet { ... } block in vnet definition, instead create the subnet as a separate resource.

    resource "azurerm_virtual_network" "neo4j_virt_network" {
      name                = "neo4j-virtnetwork-${var.env}-${var.location}-001"
      address_space       = ["10.0.0.0/16"]
      location            = var.location
      resource_group_name = var.resource_group
      tags = local.tags
    }
    
    resource "azurerm_subnet" "neo4j_virt_subnet" {
      name                 = "neo4j-virtnetwork-subnet-${var.env}-${var.location}-001"
      resource_group_name  = var.resource_group
      virtual_network_name = azurerm_virtual_network.neo4j_virt_network.name
      address_prefixes     = ["10.0.1.0/24"]
    }
    
    resource "azurerm_subnet_network_security_group_association" "neo4j_virt_nsg_assoc" {
      subnet_id                 = azurerm_subnet.neo4j_virt_subnet.id
      network_security_group_id = azurerm_network_security_group.neo4j_sg.id
    }