This error occurs when Terraform attempts to delete an Azure Network Security Group (NSG) that is still associated with network interfaces or subnets. The deletion fails because Azure prevents removal of in-use resources, requiring dependent resources to be removed first.
Azure Network Security Groups (NSGs) manage inbound and outbound traffic rules for network interfaces and subnets. When you attempt to delete an NSG using Terraform, Azure checks if the resource is currently in use. If the NSG is still associated with active network interfaces, subnets, or other resources, the Azure API rejects the deletion with the InUseNetworkSecurityGroupCannotBeDeleted error. This is a safety mechanism to prevent accidental removal of security configurations that are actively protecting network resources.
Navigate to the Network Security Group in Azure Portal and verify which network interfaces and subnets are associated with it. Note the resource names and groups.
az network nsg show --name my-nsg --resource-group my-rgIf you have azurerm_subnet_network_security_group_association resources, remove them from your Terraform configuration first:
# Remove or comment out:
resource "azurerm_subnet_network_security_group_association" "example" {
subnet_id = azurerm_subnet.example.id
network_security_group_id = azurerm_network_security_group.example.id
}Then run:
terraform applyRemove or comment out azurerm_network_interface_security_group_association resources:
# Remove or comment out:
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.example.id
network_security_group_id = azurerm_network_security_group.example.id
}Apply the changes:
terraform applyIf using inline NIC references, target the deletion of network interfaces before the NSG:
terraform destroy -target=azurerm_network_interface.example
terraform destroyOr use targeted destruction in your configuration with depends_on:
resource "azurerm_network_security_group" "example" {
# ... config ...
}
resource "azurerm_network_interface" "example" {
# ... config ...
depends_on = [azurerm_network_security_group.example]
}Check that you're not mixing inline security rules with separate azurerm_network_security_rule resources:
# DON'T DO THIS - will cause conflicts:
resource "azurerm_network_security_group" "example" {
security_rule {
name = "AllowHTTP"
# ...
}
}
resource "azurerm_network_security_rule" "example" {
name = "AllowHTTPS"
# ...
}Choose one approach: either define all rules inline OR use separate azurerm_network_security_rule resources, but not both.
With associations removed and dependencies properly ordered, retry the destroy operation:
terraform destroyIf you still encounter the error, refresh the Terraform state:
terraform refresh
terraform destroyAzure resource deletion is asynchronous. Even though Terraform reports a resource as deleted, the Azure backend may still be processing the deletion. If multiple destroy runs are needed, this is expected behavior. For complex environments with many dependent resources, consider using terraform import to synchronize state with actual Azure resources, then carefully destroy with proper depends_on ordering. Resource locks (applied via Azure RBAC or Resource Manager locks) can also cause this error; check the resource's 'Locks' section in Azure Portal. In CI/CD pipelines, add retry logic: terraform destroy may succeed on the second or third attempt as Azure completes asynchronous cleanup operations.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform