terraform-provider-azurerm icon indicating copy to clipboard operation
terraform-provider-azurerm copied to clipboard

unexpected status 400 (400 Bad Request) with error: InvalidSubscriptionId

Open enorlando opened this issue 1 year ago • 1 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Community Note

  • Please vote on this issue by adding a :thumbsup: reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment and review the contribution guide to help.

Terraform Version

1.8.3

AzureRM Provider Version

3.103.1

Affected Resource(s)/Data Source(s)

azurerm_virtual_machine

Terraform Configuration Files

resource "azurerm_virtual_machine" "xx" {
  name                             = "xx"
  location                         = var.xx
  resource_group_name              = azurerm_resource_group.xx.name
  network_interface_ids            = [azurerm_network_interface.xx.id, azurerm_network_interface.xx-xx.id]
  primary_network_interface_id     = azurerm_network_interface.xx.id
  vm_size                          = var.xx
  delete_data_disks_on_termination = false
  delete_os_disk_on_termination    = false

  storage_os_disk {
    caching                   = "ReadWrite"
    create_option             = "Attach"
    disk_size_gb              = 500
    vhd_uri                   = "${azurerm_storage_account.xx.primary_blob_endpoint}${azurerm_storage_container.xx.name}/xx.vhd"
    name                      = "xx.vhd"
    os_type                   = "Linux"
    write_accelerator_enabled = false
  }

  boot_diagnostics {
    enabled     = true
    storage_uri = azurerm_storage_account.xx.primary_blob_endpoint
  }

  timeouts {}

  tags = {
    xx         = xx
  }
}

Debug Output/Panic Output

Error: retrieving Virtual Machine (Subscription: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx0"
│ Resource Group Name: "xx"
│ Virtual Machine Name: "xx"): unexpected status 400 (400 Bad Request) with error: InvalidSubscriptionId: The provided subscription identifier 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx0' is malformed or invalid.
│ 
│   with azurerm_virtual_machine.xx,
│   on xx.tf line 51, in resource "azurerm_virtual_machine" "xx":
│   51: resource "azurerm_virtual_machine" "xx" {
│ 
╵

Expected Behaviour

After upgrading to the latest azurerm provider, running a terraform plan should come back with no error.

Actual Behaviour

After the plan completes, it errors with unexpected status 400 (400 Bad Request) with error: InvalidSubscriptionId: The provided subscription identifier 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx0' is malformed or invalid. It seems to be adding a 0 to the end of the subscription value causing it to be invalid

Steps to Reproduce

  1. Pin azurerm provider to version = "3.103.1"
  2. Run terraform plan

Dropping the provider back to version 3.101.0 seems to fix the issue. All provider versions after 3.101.0 are problematic

Important Factoids

No response

References

No response

enorlando avatar May 13 '24 23:05 enorlando

Thanks for raising this issue @enorlando.

I recently migrated these legacy compute resources over to using our generated SDK hashicorp/go-azure-sdk. In the process the version also got bumped from 2023-03-01 to 2024-03-01. These changes went into v3.102.0 of the provider so the timing certainly coincides with the behaviour you're seeing, so apologies that this has affected you!

All of the changes made have been standard process and we're not inadvertently concatenating an additional digit at the end of the subscription ID anywhere in the read function. Our understanding is that the older API was taking the first N characters from the subscription ID and parsing it as a UUID which would allow invalid subscription IDs to exist and be used in the API requests. The newer version of the API doesn't appear to be as tolerant anymore.

Would you be able to share the resource ID from the terraform show command as well as the GET request and response for that resource?

stephybun avatar May 14 '24 07:05 stephybun

Thanks for the quick turnaround @stephybun

Output from terraform show:

# azurerm_virtual_machine.xx:
resource "azurerm_virtual_machine" "xx" {
    id                           = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx0/resourceGroups/xxx/providers/Microsoft.Compute/virtualMachines/xx"
    location                     = "xx"
    name                         = "xx"
    network_interface_ids        = [
        "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Network/networkInterfaces/xx",
        "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Network/networkInterfaces/xx-xx",
    ]
    primary_network_interface_id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Network/networkInterfaces/xx"
    resource_group_name          = "xx"
    tags                         = {
        "xx"         = "xx"
        "xx"       = "xx"
        "xx"      = "xx"
        "xx" = "xx"
        "xx"         = "xx"
        "xx"    = "xx"
    }
    vm_size                      = "Standard_D2_v3"
    zones                        = []

    boot_diagnostics {
        enabled     = true
        storage_uri = "https://xx.blob.core.windows.net/"
    }

    storage_os_disk {
        caching                   = "ReadWrite"
        create_option             = "Attach"
        disk_size_gb              = 500
        image_uri                 = null
        managed_disk_id           = null
        managed_disk_type         = null
        name                      = "xx.vhd"
        os_type                   = "Linux"
        vhd_uri                   = "https://xx.blob.core.windows.net/xx/xx.vhd"
        write_accelerator_enabled = false
    }

    timeouts {}
}

Response from GET request:

{
    "name": "xx",
    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Compute/virtualMachines/xx",
    "type": "Microsoft.Compute/virtualMachines",
    "location": "xx",
    "tags": {
        "xx": "xx",
        "xx": "xx",
        "xx": "xx",
        "xx": "xx",
        "xx": "xx",
        "xx": "xx"
    },
    "properties": {
        "hardwareProfile": {
            "vmSize": "Standard_D2_v3"
        },
        "provisioningState": "Succeeded",
        "vmId": "1f224d8b-cd25-4565-8b6b-96fdf0718158",
        "storageProfile": {
            "osDisk": {
                "osType": "Linux",
                "name": "xx.vhd",
                "createOption": "Attach",
                "vhd": {
                    "uri": "https://xx.blob.core.windows.net/xx/xx.vhd"
                },
                "caching": "ReadWrite",
                "writeAcceleratorEnabled": false,
                "deleteOption": "Detach",
                "diskSizeGB": 500
            },
            "dataDisks": []
        },
        "networkProfile": {
            "networkInterfaces": [
                {
                    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Network/networkInterfaces/xx",
                    "properties": {
                        "primary": true
                    }
                },
                {
                    "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xx/providers/Microsoft.Network/networkInterfaces/xx-xx",
                    "properties": {
                        "primary": false
                    }
                }
            ]
        },
        "diagnosticsProfile": {
            "bootDiagnostics": {
                "enabled": true,
                "storageUri": "https://xx.blob.core.windows.net/"
            }
        },
        "timeCreated": "2022-05-05T02:51:27.8409179+00:00"
    }
}

What I see different in the terraform show output is that invalid subscription ID id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx0/resourceGroups/xx/providers/Microsoft.Compute/virtualMachines/xx"

enorlando avatar May 15 '24 02:05 enorlando

Thanks for providing the output @enorlando!

As alluded to earlier, it certainly looks like the API tolerates additional characters in the subscription ID. What's changed here is the SDK that we're using, having migrated away from Azure's SDK which does not parse the subscription ID before sending off the request, to our own generated SDK which does parse the subscription ID to ensure that it's valid.

It looks like what's happened here is the Virtual Machine was imported with an additional digit at the end of the subscription ID back when we were using Azure's SDK which didn't flag it as invalid. Now that we've switched it's highlighting the fact that it actually isn't a valid subscription ID due to the extraneous 0 at the end.

Removing the Virtual Machine from state and re-importing it with the correct ID should resolve this issue for you.

stephybun avatar May 15 '24 05:05 stephybun

Thanks for all the support @stephybun! Removing the VM from state and re-importing it with the correct ID did fix our issue

enorlando avatar May 15 '24 05:05 enorlando

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

github-actions[bot] avatar Jun 15 '24 02:06 github-actions[bot]