hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.6k stars 4.64k forks source link

azurerm_resource_group_template_deployment - terraform is unable to destroy any resource created with the deployment #21378

Open rdsserrao opened 1 year ago

rdsserrao commented 1 year ago

Is there an existing issue for this?

Community Note

Terraform Version

1.2.5

AzureRM Provider Version

3.50.0

Affected Resource(s)/Data Source(s)

azurerm_resource_group_template_deployment

Terraform Configuration Files

main.tf

data "azurerm_resource_group" "rg" {
  name = var.rg_name
}

data "azurerm_key_vault" "kv" {
  name                = var.kv_name
  resource_group_name = var.kv_rg_name
}

data "azurerm_key_vault_secret" "kv_secret_username" {
  name         = var.kv_secret_admin_username
  key_vault_id = data.azurerm_key_vault.kv.id
}

data "azurerm_key_vault_secret" "kv_secret_password" {
  name         = var.kv_secret_admin_password
  key_vault_id = data.azurerm_key_vault.kv.id
}

resource "azurerm_resource_group_template_deployment" "deployment" {
  for_each            = var.deployment
  name                = each.key
  resource_group_name = data.azurerm_resource_group.rg.name
  deployment_mode     = "Incremental"
#   file("${path.module}/<file-name>.json")
  template_content = file("./FWTemplate.json")

  # these key-value pairs are passed into the ARM Template's 'parameters' block
  parameters_content = jsonencode({
# Para passar variáveis TF no ARM é preciso usar "{value =...}"
    vmName                   = { value = each.value.vmName }
    tags                     = { value = each.value.tags }
    storageAccountName       = { value = each.value.storageAccountName }
    storageAccountExistingRG = { value = each.value.storageAccountExistingRG }
    # zones                    = { value = each.value.zones }
    fwAvSet           = { value = each.value.fwAvSet }
    vmSize            = { value = each.value.vmSize }
    imageVersion      = { value = each.value.imageVersion }
    imageSku          = { value = each.value.imageSku }
    bootstrapFirewall = { value = each.value.bootstrapFirewall }
    # O ARM template não aceita parâmetros a NULL, colocar ""
    BootstrapStorageAccount          = { value = lookup(each.value, "BootstrapStorageAccount", "") }
    StorageAccountAccessKey          = { value = lookup(each.value, "StorageAccountAccessKey", "") }
    StorageAccountFileShare          = { value = lookup(each.value, "StorageAccountFileShare", "") }
    StorageAccountFileShareDirectory = { value = lookup(each.value, "StorageAccountFileShareDirectory", "") }
    virtualNetworkName               = { value = each.value.virtualNetworkName }
    virtualNetworkAddressPrefix      = { value = each.value.virtualNetworkAddressPrefix }
    virtualNetworkExistingRGName     = { value = each.value.virtualNetworkExistingRGName }
    subnet0Name                      = { value = each.value.subnet0Name }
    subnet1Name                      = { value = each.value.subnet1Name }
    subnet2Name                      = { value = each.value.subnet2Name }
    subnet0Prefix                    = { value = each.value.subnet0Prefix }
    subnet1Prefix                    = { value = each.value.subnet1Prefix }
    subnet2Prefix                    = { value = each.value.subnet2Prefix }
    subnet0StartAddress              = { value = each.value.subnet0StartAddress }
    subnet1StartAddress              = { value = each.value.subnet1StartAddress }
    subnet2StartAddress              = { value = each.value.subnet2StartAddress }
    adminUsername                    = { value = data.azurerm_key_vault_secret.kv_secret_username.value }
    adminPassword                    = { value = data.azurerm_key_vault_secret.kv_secret_password.value }
    publicIPAddressName              = { value = each.value.publicIPAddressName }
    publicIPType                     = { value = each.value.publicIPType }
    nsgName                          = { value = each.value.nsgName }
    customData                       = { value = each.value.customData }
  })
}

--------------------------------------------------------------------------------------------------------
FWTemplate.json

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmName": {
            "type": "string",
            "metadata": {
                "description": "Name of VM-Series FW in the Azure portal"
            },
            "defaultValue": ""
        },
        "tags": {
            "type": "object",
            "metadata": {
                "description": "Resource Tags"
            },
            "defaultValue": {}
        },
        "storageAccountName": {
            "type": "string",
            "metadata": {
                "description": "Name of the EXISTING storage account used to store the VM's disks"
            },
            "defaultValue": ""
        },
        "storageAccountExistingRG": {
            "type": "string",
            "metadata": {
                "description": "Storage Account's Resource Group."
            },
            "defaultValue": ""
        },
        "fwAvSet": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Availability Set name for Firewalls"
            },
            "defaultValue": ""
        },
        "vmSize": {
            "type": "string",
            "allowedValues": [
                "Standard_D3",
                "Standard_D4",
                "Standard_D3_v2",
                "Standard_D4_v2",
                "Standard_A4",
                "Standard_DS3_v2",
                "Standard_DS4_v2"
            ],
            "metadata": {
                "description": "Azure VM size for VM-Series"
            },
            "defaultValue": ""
        },
        "publicIPType": {
            "type": "string",
            "allowedValues": [
                "standard",
                "basic"
            ],
            "metadata": {
                "description": "Use Standard if this VM will be in the backend pool of a Standard SKU Load Balancer"
            },
            "defaultValue": "standard"
        },
        "imageVersion": {
            "type": "string",
            "allowedValues": [
                "9.1.10",
                "9.1.13",
                "10.1.0",
                "10.1.5",
                "latest"
            ],
            "metadata": {
                "description": "PAN OS Version"
            },
            "defaultValue": "10.1.5"
        },
        "imageSku": {
            "type": "string",
            "allowedValues": [
                "byol",
                "bundle1",
                "bundle2"
            ],
            "metadata": {
                "description": "Firewall License Model"
            },
            "defaultValue": "byol"
        },
        "bootstrapFirewall": {
            "type": "string",
            "allowedValues": [
                "no",
                "yes"
            ],
            "metadata": {
                "description": "Do you want to bootstrap the firewall?"
            },
            "defaultValue": "no"
        },
        "BootstrapStorageAccount": {
            "type": "string",
            "metadata": {
                "description": "Storage account hosting the bootstrap files"
            },
            "defaultValue": ""
        },
        "StorageAccountAccessKey": {
            "type": "string",
            "metadata": {
                "description": "Authentication key to access the storage account"
            },
            "defaultValue": ""
        },
        "StorageAccountFileShare": {
            "type": "string",
            "metadata": {
                "description": "The file share in the storage account where the bootstrap files are located"
            },
            "defaultValue": ""
        },
        "StorageAccountFileShareDirectory": {
            "type": "string",
            "metadata": {
                "description": "The subdirectory hosting the bootstrap files. Only required if hosting multiple bootstrap directories on the same share"
            },
            "defaultValue": ""
        },
        "virtualNetworkName": {
            "type": "string",
            "metadata": {
                "description": "Name of the EXISTING Virtual Network (VNET)"
            },
            "defaultValue": ""
        },
        "virtualNetworkAddressPrefix": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Virtual network address CIDR"
            },
            "defaultValue": ""
        },
        "virtualNetworkExistingRGName": {
            "type": "string",
            "metadata": {
                "description": "Name of resource group of EXISTING VNET"
            },
            "defaultValue": ""
        },
        "subnet0Name": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Subnet for Management"
            },
            "defaultValue": ""
        },
        "subnet1Name": {
            "type": "string",
            "metadata": {
                "description": "Public EXISTING Subnet"
            },
            "defaultValue": ""
        },
        "subnet2Name": {
            "type": "string",
            "metadata": {
                "description": "Private EXISTING Subnet"
            },
            "defaultValue": ""
        },
        "subnet0Prefix": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Management subnet CIDR"
            },
            "defaultValue": ""
        },
        "subnet1Prefix": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Public subnet CIDR"
            },
            "defaultValue": ""
        },
        "subnet2Prefix": {
            "type": "string",
            "metadata": {
                "description": "EXISTING Private subnet CIDR"
            },
            "defaultValue": ""
        },
        "subnet0StartAddress": {
            "type": "string",
            "metadata": {
                "description": "Management subnet static address"
            },
            "defaultValue": ""
        },
        "subnet1StartAddress": {
            "type": "string",
            "metadata": {
                "description": "Public subnet static address"
            },
            "defaultValue": ""
        },
        "subnet2StartAddress": {
            "type": "string",
            "metadata": {
                "description": "Private subnet static address"
            },
            "defaultValue": ""
        },
        "adminUsername": {
            "type": "string",
            "metadata": {
                "description": "Username of the administrator account of VM-Series"
            },
            "defaultValue": ""
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Password of the administrator account of VM-Series"
            },
            "defaultValue": ""
        },
        "publicIPAddressName": {
            "type": "string",
            "metadata": {
                "description": "Name of FW1 MGMT Public Address"
            },
            "defaultValue": ""
        },
        "nsgName": {
            "type": "string",
            "metadata": {
                "description": "Name of existing Network Security Group for MGMT FW interface"
            },
            "defaultValue": ""
        },
        "customData": {
            "type": "string",
            "metadata": {
                "description": "Azure Custom Data - separate entries with a semicolon"
            },
            "defaultValue": ""
        }
    },
    "variables": {},
    "resources": [
        {
            "apiVersion": "2022-07-01",
            "type": "Microsoft.Network/publicIPAddresses",
            "name": "[parameters('publicIPAddressName')]",
            "location": "[resourceGroup().location]",
            "tags": "[parameters('tags')]",
            "sku": {
                "name": "[parameters('publicIPType')]"
            },
            "properties": {
                "publicIPAllocationMethod": "Static",
                "dnsSettings": {
                    "domainNameLabel": "[parameters('publicIPAddressName')]"
                }
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2022-07-01",
            "name": "[concat(parameters('vmName'), '-eth0')]",
            "location": "[resourceGroup().location]",
            "tags": "[parameters('tags')]",
            "dependsOn": [
                "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig-mgmt",
                        "properties": {
                            "privateIPAllocationMethod": "Static",
                            "privateIPAddress": "[parameters('subnet0StartAddress')]",
                            "publicIPAddress": {
                                "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIPAddressName'))]"
                            },
                            "subnet": {
                                "id": "[resourceId(parameters('virtualNetworkExistingRGName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet0Name'))]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2022-07-01",
            "name": "[concat(parameters('vmName'), '-eth1')]",
            "location": "[resourceGroup().location]",
            "tags": "[parameters('tags')]",
            "properties": {
                "enableIPForwarding": true,
                "ipConfigurations": [
                    {
                        "name": "ipconfig-untrust",
                        "properties": {
                            "privateIPAllocationMethod": "Static",
                            "privateIPAddress": "[parameters('subnet1StartAddress')]",
                            "subnet": {
                                "id": "[resourceId(parameters('virtualNetworkExistingRGName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet1Name'))]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2022-07-01",
            "name": "[concat(parameters('vmName'), '-eth2')]",
            "location": "[resourceGroup().location]",
            "tags": "[parameters('tags')]",
            "properties": {
                "enableIPForwarding": true,
                "ipConfigurations": [
                    {
                        "name": "ipconfig-trust",
                        "properties": {
                            "privateIPAllocationMethod": "Static",
                            "privateIPAddress": "[parameters('subnet2StartAddress')]",
                            "subnet": {
                                "id": "[resourceId(parameters('virtualNetworkExistingRGName'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnet2Name'))]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2022-11-01",
            "condition": "[equals(parameters('bootstrapFirewall'),'no')]",
            "name": "[parameters('vmName')]",
            "location": "[resourceGroup().location]",
            "tags": "[parameters('tags')]",
            "dependsOn": [
                "[concat('Microsoft.Network/networkInterfaces/', concat(parameters('vmName'), '-eth0'))]",
                "[concat('Microsoft.Network/networkInterfaces/', concat(parameters('vmName'), '-eth2'))]",
                "[concat('Microsoft.Network/networkInterfaces/', concat(parameters('vmName'), '-eth2'))]"
            ],
            "plan": {
                "name": "[parameters('imageSku')]",
                "product": "vmseries-flex",
                "publisher": "paloaltonetworks"
            },
            "properties": {
                "availabilitySet": {
                    "id": "[resourceId('Microsoft.Compute/availabilitySets', parameters('fwAvSet'))]"
                },
                "hardwareProfile": {
                    "vmSize": "[parameters('vmSize')]"
                },
                "osProfile": {
                    "computerName": "[parameters('vmName')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]",
                    "customData": "[base64(parameters('customData'))]"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "paloaltonetworks",
                        "offer": "vmseries-flex",
                        "sku": "[parameters('imageSku')]",
                        "version": "[parameters('imageVersion')]"
                    },
                    "osDisk": {
                        "name": "osdisk",
                        "vhd": {
                            "uri": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net/vhds/', parameters('vmName'), '-', 'vmseries-flex', '-', parameters('imageSku'), '.vhd')]"
                        },
                        "caching": "ReadWrite",
                        "createOption": "FromImage"
                    }
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'), '-eth0'))]",
                            "properties": {
                                "primary": true
                            }
                        },
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'), '-eth1'))]",
                            "properties": {
                                "primary": false
                            }
                        },
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'), '-eth2'))]",
                            "properties": {
                                "primary": false
                            }
                        }
                    ]
                }
            }
        }
    ]
}

Debug Output/Panic Output

Error: removing items provisioned by this Template Deployment: `properties.OutputResources` was nil - insufficient data to clean up this Template Deployment

Expected Behaviour

Expecting to see TF destroying the resources created by the deployment.

Actual Behaviour

TF says there is insufficient data.

Steps to Reproduce

terraform apply terraform destroy

Important Factoids

No response

References

https://github.com/hashicorp/terraform-provider-azurerm/pull/10565 https://github.com/hashicorp/terraform-provider-azurerm/issues/18243

chrisokonkwo-kr commented 1 year ago

@rdsserrao i experienced the same error from TF as follows:

image

My fix was to go into Azure Portal > MyResourceGroup > Deployments > MyDeployment > Deleted it. After I deleted it, ran TF apply and got a successful deployment