I've created a terraform script with an azurerm_linux_function_app with vnet integration (using azurerm_app_service_virtual_network_swift_connection). If I run the Terraform script everything works as expected, but if I run Terraform again it proposes to update the function app in-place by removing the virtual_network_subnet_id, which then breaks the vnet integration. If I run terraform again it proposes to create azurerm_app_service_virtual_network_swift_connection again and everything works and this loop continues.
resource "azurerm_subnet" "this" {
name = "name"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.5.128/26"]
service_endpoints = ["Microsoft.AzureCosmosDB"]
delegation {
name = "name-delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
}
resource "azurerm_linux_function_app" "this" {
name = "name"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
storage_account_name = azurerm_storage_account.this.name
storage_account_access_key = azurerm_storage_account.this.primary_access_key
service_plan_id = azurerm_service_plan.this.id
https_only = true
site_config {
vnet_route_all_enabled = true
cors {
allowed_origins = ["https://portal.azure.com"]
}
application_stack {
node_version = "18"
}
}
app_settings = {
}
depends_on = [azurerm_cosmosdb_account.db]
}
resource "azurerm_app_service_virtual_network_swift_connection" "this" {
app_service_id = azurerm_linux_function_app.this.id
subnet_id = azurerm_subnet.this.id
}
Glad the problem was solved As a workaround instead of removing swift connection
You can make use of lifecycle block as mentioned in this SO thread in your terraform code to avoid your swift connection from updating again, Refer below:-
My Terraform code:-
I have referred the below terraform code from this Official Terraform document and modified the code by adding Depends on and lifecycle block.
# We strongly recommend using the required_providers block to set the
# Azure Provider source and version being used
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.58.0"
}
}
}
# Configure the Microsoft Azure Provider
provider "azurerm" {
subscription_id = "subid"
tenant_id = "tenantid"
client_id = "clientid"
client_secret = "clientsecret"
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "West Europe"
}
resource "azurerm_virtual_network" "example" {
name = "example-virtual-network"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_subnet" "example" {
name = "example-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
delegation {
name = "example-delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
depends_on = [ azurerm_virtual_network.example ]
}
resource "azurerm_app_service_plan" "example" {
name = "example-app-service-plan"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
depends_on = [ azurerm_resource_group.example ]
sku {
tier = "Standard"
size = "S1"
}
}
resource "azurerm_storage_account" "example" {
name = "siliconstrg54332"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_function_app" "example" {
name = "siliconfunc-0987"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
depends_on = [azurerm_app_service_plan.example]
}
resource "azurerm_app_service_virtual_network_swift_connection" "this" {
app_service_id = azurerm_function_app.example.id
subnet_id = azurerm_subnet.example.id
depends_on = [azurerm_subnet.example, azurerm_function_app.example]
lifecycle {
ignore_changes = [
subnet_id,
]
}
}
lifecycle block:-
resource "azurerm_app_service_virtual_network_swift_connection" "this" {
app_service_id = azurerm_function_app.example.id
subnet_id = azurerm_subnet.example.id
depends_on = [azurerm_subnet.example, azurerm_function_app.example]
lifecycle {
ignore_changes = [
subnet_id,
]
}
}
Output:-
When I ran the Plan again it did not ask me to update Swift connection or Function app except for asking me to add the tag as cost center refer below:-
You can add the tags by adding this
tags = { costCenter = "My Cost Center" }
in your resource block after tadding this in my resource block when I ran the plan I got the desired state refer below:-
Complete code with tag referred from this Official Terraform Document modified with Depends on and lifecycle block.
# We strongly recommend using the required_providers block to set the
# Azure Provider source and version being used
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.58.0"
}
}
}
# Configure the Microsoft Azure Provider
provider "azurerm" {
subscription_id = "subid"
tenant_id = "tenantid"
client_id = "clientid"
client_secret = "clientsecret"
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "West Europe"
}
resource "azurerm_virtual_network" "example" {
name = "example-virtual-network"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
tags = {
costCenter = "My Cost Center"
}
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_subnet" "example" {
name = "example-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
delegation {
name = "example-delegation"
service_delegation {
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
}
depends_on = [ azurerm_virtual_network.example ]
}
resource "azurerm_app_service_plan" "example" {
name = "example-app-service-plan"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
depends_on = [ azurerm_resource_group.example ]
sku {
tier = "Standard"
size = "S1"
}
tags = {
costCenter = "My Cost Center"
}
}
resource "azurerm_storage_account" "example" {
name = "siliconstrg54332"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
costCenter = "My Cost Center"
}
depends_on = [ azurerm_resource_group.example ]
}
resource "azurerm_function_app" "example" {
name = "siliconfunc-0987"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
app_service_plan_id = azurerm_app_service_plan.example.id
storage_account_name = azurerm_storage_account.example.name
storage_account_access_key = azurerm_storage_account.example.primary_access_key
tags = {
costCenter = "My Cost Center"
}
depends_on = [azurerm_app_service_plan.example]
}
resource "azurerm_app_service_virtual_network_swift_connection" "this" {
app_service_id = azurerm_function_app.example.id
subnet_id = azurerm_subnet.example.id
depends_on = [azurerm_subnet.example, azurerm_function_app.example]
lifecycle {
ignore_changes = [
subnet_id,
]
}
}