Why Terraform tries to delete subnet from function app if it exists in state, code and resource?

63 Views Asked by At

When i run terraform plan or apply i always see, that my subnet will be deleted.

So, in resource i see that its connected to vnet and subnet: enter image description here

i have TF code representation of that connection:

resource "azurerm_app_service_virtual_network_swift_connection" "func_app_vnet_swift_connection" {
  app_service_id = azurerm_windows_function_app.func_app.id
  subnet_id      = data.azurerm_subnet.subnet.id

  depends_on = [ 
    azurerm_windows_function_app.func_app
  ]
}

In State i can see that block representation with the same subnet_id like from terraform plan command:

{
      "mode": "managed",
      "type": "azurerm_app_service_virtual_network_swift_connection",
      "name": "func_app_vnet_swift_connection",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [

enter image description here

What is wrong with my code that it ALWAYS try to delete swift_connection block from resource? I need to do workaround (add and delete) an run apply twice to overcome that issue but it alwasy go back to me again

2

There are 2 best solutions below

0
Technowise On

Update the azurerm_windows_function_app.func_app resource to have virtual_network_subnet_id argument included, which should refer to the subnet id (ie data.azurerm_subnet.subnet.id). This should resolve the issue. If it still does not work, please share the code block of azurerm_windows_function_app.func_app

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_function_app#virtual_network_subnet_id

0
Vinay B On

I tried to address the issue Why Terraform tries to delete subnet from function app if it exists in state, code and resource which can also be overcome by using ignore changes.

From the query you mentioned that the command terraform plan is always indicating that the azurerm_app_service_virtual_network_swift_connection resource will be deleted whenever you run terraform plan or terraform apply.

This can happen if there are discrepancies between your Terraform configuration and the actual state of the Azure resources as Technowise mentioned I agreed with it. As info provided was also limited in query this also might be the issue which causing the modification or recreating the resource after every plan or apply.

Even after the checking mentioned pointers & if the issue still persists and to counter that you can use ignore changes life cycle module.

I tried a demo configuration to justify my explanation.

My terraform configuration:

provider "azurerm" {
  features {}
}

data "azurerm_resource_group" "example" {
  name     = "rg-name"
}

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

  lifecycle {
    ignore_changes = [
      // attributes of the virtual network that should not cause other resources to be recreated
    ]
  }
}

resource "azurerm_subnet" "example" {
  name                 = "bolliv-subnet"
  resource_group_name  = data.azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]

    delegation {
    name = "delegation"
    service_delegation {
      name    = "Microsoft.Web/serverFarms"
      actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
    }
  }
}

resource "azurerm_storage_account" "example" {
  name                     = "wfunctionappvk"
  resource_group_name      = data.azurerm_resource_group.example.name
  location                 = data.azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_service_plan" "example" {
  name                = "bolliv-asp"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
  os_type             = "Windows"
  sku_name            = "B1"
}

resource "azurerm_windows_function_app" "example" {
  name                = "bolliv-functionapp"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
  service_plan_id = azurerm_service_plan.example.id
  storage_account_name       = azurerm_storage_account.example.name
  storage_account_access_key = azurerm_storage_account.example.primary_access_key

  site_config {
    // Your specific function app settings
  }
}

resource "azurerm_app_service_virtual_network_swift_connection" "example" {
  app_service_id = azurerm_windows_function_app.example.id
  subnet_id      = azurerm_subnet.example.id

  depends_on = [
    azurerm_windows_function_app.example,
    azurerm_subnet.example
  ]

}

deployment succeeded:

enter image description here

enter image description here

enter image description here

Now if my make any changes in the subnet configuration and try using life cycle module it will restrict changes and doesn't make any changes in configuration or state.

  lifecycle {
    ignore_changes = [
      subnet_id, // Only ignore if changes to subnet_id should not force new resource
    ]
  }

note : You can also specify any resource or module along with subnet to restrict the recreation and modification of any resource that doesn't requires changes by using this.

enter image description here