Azure / terraform-provider-azapi

Terraform provider for Azure Resource Manager Rest API
https://registry.terraform.io/providers/Azure/azapi/latest
Mozilla Public License 2.0
193 stars 51 forks source link

data azapi_resource handling RESPONSE 404: 404 Not Found #131

Open mpjtaylor opened 2 years ago

mpjtaylor commented 2 years ago

Trying to reference a resource that may or may not exist, expect null

looked at response_export_values but this doesn't seem to help

ms-henglu commented 2 years ago

Hi @mpjtaylor ,

Thank you for opening this issue.

I think this behavior is by design, using data source to read a not existed resource, it should throw error.

mpjtaylor commented 2 years ago

Ok so Im trying to configure a VM that may or may not have a capacity reservation and therefore want to avoid this error

data "azurerm_resource_group" "supportmodule" {
  name = "rg"
}

data "azapi_resource" "virtualmachine_rehosted_capacity_group" {
  name      = "res"
  parent_id = data.azurerm_resource_group.supportmodule.id
  type      = "Microsoft.Compute/capacityReservationGroups@2021-11-01"
}

data "azapi_resource" "virtualmachine_rehosted_capacity" {
  name      = "Standard_D2_v2"
  parent_id = data.azapi_resource.virtualmachine_rehosted_capacity_group.id
  type      = "Microsoft.Compute/capacityReservationGroups/capacityReservations@2021-11-01"
}

resource "azapi_resource" "virtualmachine_rehosted" {
  count = var.migration ? 1 : 0
  type  = "Microsoft.Compute/virtualMachines@2021-11-01"

  name      = local.vm_name
  location  = data.azurerm_resource_group.virtualmachine.location
  parent_id = data.azurerm_resource_group.virtualmachine.id
  body = jsonencode({
    identity = {
      type = "SystemAssigned"
    }
    properties = {
      hardwareProfile = {
        vmSize = var.vm_size
      }
      networkProfile = {
        networkInterfaces = [{
          id = azurerm_network_interface.virtualmachine.id
        }]
      }
      storageProfile = {
        osDisk = {
          createOption = "Attach"
          managedDisk = {
            storageAccountType = var.vm_storage_account_type
            id                 = azurerm_managed_disk.os_disk[0].id
          }
          osType = var.os_type
          name   = azurerm_managed_disk.os_disk[0].name
        }
      }
      capacityReservation = {
        capacityReservationGroup = {
          id = data.azapi_resource.virtualmachine_rehosted_capacity.name == null ? null : data.azapi_resource.virtualmachine_rehosted_capacity_group.id
        }
      }
      licenseType = local.license_type
    }
    zones = ["${local.primary_zone}"]
  })
  schema_validation_enabled = false
  tags                      = merge(local.tags, local.vmtags, local.provisioningtags)
  lifecycle {
    ignore_changes = [
      tags["local-vmstatus"],
      tags["local-vmprovisioning"],
      tags["local-vmpuppetstatus"],
      tags["local-vmprovisioning"],
      tags["local-vmprovisioningid"],
      tags["local-vmfqdn"]
    ]
  }
  depends_on = [data.azurerm_resource_group.virtualmachine, azurerm_managed_disk.os_disk, data.azapi_resource.virtualmachine_rehosted_capacity_group]
}

How best to handle this?

ms-henglu commented 2 years ago

Maybe use a variable to indicate whether there're available capacity reservations?

mpjtaylor commented 2 years ago

yes this is an option, but i assumed as azurerm handles data resources not found azapi maybe able to :)

LaurentLesle commented 2 years ago

+1 on the not found by default. However I can see a use case where you want to fail if the object does not exists. Maybe adding an attribute to the data azapi_resource to say fails_if_not_exist

use case: certificate or secret from kv must exist in some cases.