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.61k stars 4.65k forks source link

azurerm_api_management_api: changing from single version api to api with multiple versions causes "already exists" on first apply #28048

Closed J0F3 closed 10 minutes ago

J0F3 commented 1 day ago

Is there an existing issue for this?

Community Note

Terraform Version

1.9.8

AzureRM Provider Version

4.10.0

Affected Resource(s)/Data Source(s)

azurerm_api_management_api

Terraform Configuration Files

provider "azurerm" {
  resource_provider_registrations = "none"
  features {}
}
locals {
  apim_rg              = "test-rg"
  apim_name            = "test-apim"
  additional_version = false
}

resource "azurerm_api_management_api_version_set" "additional_version" {
  name                = local.apim_name
  api_management_name = local.apim_name
  resource_group_name = local.apim_rg
  display_name        = "replace-api-bug-repro"
  versioning_scheme   = "Header"
  version_header_name = "Version"
}

resource "azurerm_api_management_api" "api" {
  name                = local.additional_version == true ? "replace-api-bug-repro-cloud" : "replace-api-bug-repro"
  resource_group_name = local.apim_rg
  api_management_name = local.apim_name
  revision            = "1"
  display_name        = "replace-api-bug-repro - ${local.additional_version ? "multi version" : "single version"}"
  path                = "test/api"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/openapi.yaml")
  }

  version_set_id = local.additional_version ? azurerm_api_management_api_version_set.additional_version.id : null
  version        = local.additional_version ? "cloud" : null
}

resource "azurerm_api_management_api" "additional_api" {

  count = local.additional_version ? 1 : 0

  name                = "replace-api-bug-repro"
  resource_group_name = local.apim_rg
  api_management_name = local.apim_name
  revision            = "1"
  display_name        = "replace-api-bug-repro - ${local.additional_version ? "multi version" : "single version"}"
  path                = "test/api"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/openapi.yaml")
  }

  version_set_id = azurerm_api_management_api_version_set.additional_version.id
  version        = null
}

Debug Output/Panic Output

https://gist.github.com/J0F3/5ec2d9c1d4425b871271b56a89a55ab5

Expected Behaviour

azurerm_api_management_api should be replaced as shown in terraform plan without any error.

Actual Behaviour

The first time running terraform apply always fails with 'A resource with the ID ... already exist...'. The second time running terraform apply works then and completes the needed changes. But in a CI/CD pipeline this always leads to a broken pipeline and needs retries.

The reason for that is similar to the reason of https://github.com/hashicorp/terraform-provider-azurerm/issues/23322 where azurerm does not follow correctly the polling URL of the Azure API where a long running operation should be tracked. Instead azurerm zu goes ahead and tries to create the api again (with the new setting) but then it finds the previous API for which the delete operation has not finished yet.

Here is the relevant part of the debug log:

2024-11-18T09:51:59.628+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Served request: @caller=github.com/hashicorp/terraform-plugin-go@v0.25.0/tfprotov5/tf5server/server.go:843 @module=sdk.proto tf_req_id=10b890ba-1803-1b60-2e7b-9bb8f0bad169 tf_rpc=PlanResourceChange tf_proto_version=5.7 tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_resource_type=azurerm_api_management_api timestamp="2024-11-18T09:51:59.628+0100"
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] AzureRM Request: 
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: DELETE /subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1?api-version=2022-08-01 HTTP/1.1
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Host: management.azure.com
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: User-Agent: HashiCorp/go-azure-sdk (Go-http-Client/1.1 api/2022-08-01) HashiCorp Terraform/1.9.8 (+https://www.terraform.io) terraform-provider-azurerm/4.10.0+4.0-beta pid-222c6c49-1b0a-5959-a213-6608f9eb8820
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Accept: application/json; charset=utf-8; IEEE754Compatible=false
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Content-Type: application/json; charset=utf-8
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Odata-Maxversion: 4.0
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Odata-Version: 4.0
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Correlation-Request-Id: ff94c19d-7d43-0e61-a788-3af6c634d376
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Accept-Encoding: gzip
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5
2024-11-18T09:51:59.628+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] DELETE https://management.azure.com/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1?api-version=2022-08-01
2024-11-18T09:51:59.629+0100 [WARN]  Provider "registry.terraform.io/hashicorp/azurerm" produced an invalid plan for azurerm_api_management_api.additional_api[0], but we are tolerating it because it is using the legacy plugin SDK.
    The following problems may be the cause of any confusing errors from downstream operations:
      - .subscription_required: planned value cty.True for a non-computed attribute
      - .subscription_key_parameter_names: attribute representing nested block must not be unknown itself; set nested attribute values to unknown instead
2024-11-18T09:51:59.629+0100 [TRACE] checkPlannedChange: Verifying that actual change (action Create) matches planned change (action Create)
2024-11-18T09:51:59.629+0100 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/azurerm" is in the global cache
2024-11-18T09:51:59.629+0100 [INFO]  Starting apply for azurerm_api_management_api.additional_api[0]
2024-11-18T09:51:59.629+0100 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/azurerm" is in the global cache
2024-11-18T09:51:59.629+0100 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/azurerm" is in the global cache
2024-11-18T09:51:59.629+0100 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/azurerm" is in the global cache
2024-11-18T09:51:59.629+0100 [DEBUG] azurerm_api_management_api.additional_api[0]: applying the planned Create change
2024-11-18T09:51:59.629+0100 [TRACE] GRPCProvider: ApplyResourceChange
2024-11-18T09:51:59.629+0100 [TRACE] GRPCProvider: GetProviderSchema
2024-11-18T09:51:59.629+0100 [TRACE] GRPCProvider: returning cached schema: EXTRA_VALUE_AT_END=registry.terraform.io/hashicorp/azurerm
2024-11-18T09:51:59.630+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Received request: tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_resource_type=azurerm_api_management_api @caller=github.com/hashicorp/terraform-plugin-go@v0.25.0/tfprotov5/tf5server/server.go:852 @module=sdk.proto tf_proto_version=5.7 tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 tf_rpc=ApplyResourceChange timestamp="2024-11-18T09:51:59.630+0100"
2024-11-18T09:51:59.630+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Sending request downstream: tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 tf_resource_type=azurerm_api_management_api @module=sdk.proto tf_proto_version=5.7 tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-go@v0.25.0/tfprotov5/internal/tf5serverlogging/downstream_request.go:22 timestamp="2024-11-18T09:51:59.630+0100"
2024-11-18T09:51:59.630+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: calling downstream server: tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-mux@v0.17.0/internal/logging/mux.go:19 @module=sdk.mux tf_mux_provider="*schema.GRPCProviderServer" timestamp="2024-11-18T09:51:59.630+0100"
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] setting computed for "subscription_key_parameter_names" from ComputedKeys
2024-11-18T09:51:59.630+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Calling downstream: tf_mux_provider="*schema.GRPCProviderServer" tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 tf_resource_type=azurerm_api_management_api tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.35.0/helper/schema/resource.go:936 tf_provider_addr=registry.terraform.io/hashicorp/azurerm @module=sdk.helper_schema timestamp="2024-11-18T09:51:59.630+0100"
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] AzureRM Request: 
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: GET /subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1?api-version=2022-08-01 HTTP/1.1
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Host: management.azure.com
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: User-Agent: HashiCorp/go-azure-sdk (Go-http-Client/1.1 api/2022-08-01) HashiCorp Terraform/1.9.8 (+https://www.terraform.io) terraform-provider-azurerm/4.10.0+4.0-beta pid-222c6c49-1b0a-5959-a213-6608f9eb8820
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Content-Type: application/json; charset=utf-8
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Correlation-Request-Id: ff94c19d-7d43-0e61-a788-3af6c634d376
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Accept-Encoding: gzip
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5
2024-11-18T09:51:59.630+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] GET https://management.azure.com/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1?api-version=2022-08-01
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: [DEBUG] AzureRM Response for https://management.azure.com/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1?api-version=2022-08-01: 
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: HTTP/2.0 200 OK
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Content-Length: 990
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Cache-Control: no-cache
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Content-Type: application/json; charset=utf-8
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Date: Mon, 18 Nov 2024 08:51:59 GMT
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Etag: "AAAAAAAIMQ0="
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Expires: -1
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Pragma: no-cache
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: Strict-Transport-Security: max-age=31536000; includeSubDomains
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Cache: CONFIG_NOCACHE
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Content-Type-Options: nosniff
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Correlation-Request-Id: ff94c19d-7d43-0e61-a788-3af6c634d376
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Ratelimit-Remaining-Subscription-Global-Reads: 3749
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Ratelimit-Remaining-Subscription-Reads: 249
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Request-Id: ff94c19d-7d43-0e61-a788-3af6c634d376
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Ms-Routing-Request-Id: FRANCESOUTH:20241118T085200Z:851343d2-eac4-45da-bf20-34ee4eb9479b
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: X-Msedge-Ref: Ref A: EA52F9B8237D4C308323AA0C86F878C7 Ref B: MRS211050618051 Ref C: 2024-11-18T08:51:59Z
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: {
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:   "id": "/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:   "type": "Microsoft.ApiManagement/service/apis",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:   "name": "replace-api-bug-repro",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:   "properties": {
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "displayName": "replace-api-bug-repro - single version",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "apiRevision": "1",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "description": "",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "subscriptionRequired": true,
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "serviceUrl": "",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "backendId": null,
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "path": "test/api",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "protocols": [
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "https"
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     ],
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "authenticationSettings": {
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "oAuth2": null,
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "openid": null,
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "oAuth2AuthenticationSettings": [],
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "openidAuthenticationSettings": []
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     },
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "subscriptionKeyParameterNames": {
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "header": "Ocp-Apim-Subscription-Key",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:       "query": "subscription-key"
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     },
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "isCurrent": true,
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "apiRevisionDescription": "",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "apiVersionDescription": "",
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:     "provisioningState": "Succeeded"
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5:   }
2024-11-18T09:52:00.285+0100 [DEBUG] provider.terraform-provider-azurerm_v4.10.0_x5: }
2024-11-18T09:52:00.286+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Called downstream: tf_mux_provider="*schema.GRPCProviderServer" @module=sdk.helper_schema tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 tf_resource_type=azurerm_api_management_api tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.35.0/helper/schema/resource.go:938 timestamp="2024-11-18T09:52:00.285+0100"
2024-11-18T09:52:00.286+0100 [TRACE] provider.terraform-provider-azurerm_v4.10.0_x5: Received downstream response: @module=sdk.proto tf_proto_version=5.7 tf_req_duration_ms=655 tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-go@v0.25.0/tfprotov5/internal/tf5serverlogging/downstream_request.go:42 diagnostic_error_count=1 diagnostic_warning_count=0 tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_resource_type=azurerm_api_management_api timestamp="2024-11-18T09:52:00.286+0100"
2024-11-18T09:52:00.286+0100 [ERROR] provider.terraform-provider-azurerm_v4.10.0_x5: Response contains error diagnostic: tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-go@v0.25.0/tfprotov5/internal/diag/diagnostics.go:58 diagnostic_detail="" diagnostic_severity=ERROR tf_proto_version=5.7 tf_req_id=1881541e-3b52-c29f-cc60-14aad08b5f60 @module=sdk.proto diagnostic_summary="A resource with the ID \"/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1\" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for \"azurerm_api_management_api\" for more information." tf_provider_addr=registry.terraform.io/hashicorp/azurerm tf_resource_type=azurerm_api_management_api timestamp="2024-11-18T09:52:00.286+0100"

Here it is clearly visible that the DELETE Call was made to the Azure API and then immediately after that the certation starts which find then API which is going to be deleted. It can identified by the "displayName" of the API which contains still "single version" which is the API which must be deleted. I added the string to the "displayName" by intent so that it can be tracked which version of the api is the one which actually triggers the conflict.

As you can see in the documentation of the Azure API the DELETE resource normally response with "202" and URLs where the actual progress can be tracked: https://learn.microsoft.com/en-us/rest/api/apimanagement/apis/delete?view=rest-apimanagement-2024-05-01&tabs=HTTP#apimanagementdeleteapi But this response seems to be ignored by azurem. So, it similar to what happens in https://github.com/hashicorp/terraform-provider-azurerm/issues/23322 for which PR with a fix is still pending: https://github.com/hashicorp/go-azure-sdk/pull/1090. So maybe this would also be fixed when the PR is merged. But I am not sure. @wuxu92 Can please confirm/verify that?

Steps to Reproduce

  1. Apply the above configuration with local.additional_version=false

  2. Change local.additional_version=false to local.additional_version=true. Plan show now that the api must be replaced which makes sense:

    # azurerm_api_management_api.api must be replaced
    -/+ resource "azurerm_api_management_api" "api" {
      ~ api_type              = "http" -> (known after apply)
      ~ display_name          = "replace-api-bug-repro - single version" -> "replace-api-bug-repro - multi version"
      ~ id                    = "/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1" -> (known after apply)
      ~ is_current            = true -> (known after apply)
      ~ is_online             = false -> (known after apply)
      ~ name                  = "replace-api-bug-repro" -> "replace-api-bug-repro-cloud" # forces replacement
      + service_url           = (known after apply)
      + version               = "cloud"
      + version_set_id        = "/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apiVersionSets/test-apim"
        # (10 unchanged attributes hidden)
    
      ~ subscription_key_parameter_names (known after apply)
      - subscription_key_parameter_names {
          - header = "Ocp-Apim-Subscription-Key" -> null
          - query  = "subscription-key" -> null
        }
    
        # (1 unchanged block hidden)
    }
  3. Now when applying the changes (terraform apply) then it would fail with:

    ╷
    │ Error: A resource with the ID "/subscriptions/[sub-id]/resourceGroups/test-rg/providers/Microsoft.ApiManagement/service/test-apim/apis/replace-api-bug-repro;rev=1" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_api_management_api" for more information.
    │
    │   with azurerm_api_management_api.additional_api[0],
    │   on main.tf line 44, in resource "azurerm_api_management_api" "additional_api":
    │   44: resource "azurerm_api_management_api" "additional_api" {
    │
    ╵
  4. The second time when terraform apply is run the apply succeeds then.

Important Factoids

No response

References

I think this is also related to https://github.com/hashicorp/go-azure-sdk/pull/1090

wuxu92 commented 1 day ago

Thank you @J0F3 for reporting this APIM issue. It seems different from the creation provisioning poller issue since the delete doesn't appear to be a long-running operation at first glance. However, I'm not certain yet and will investigate further when I have the chance.

J0F3 commented 1 day ago

Thank you @wuxu92 . What I can say form my troubleshooting steps is that the API definitely returns 202 with the location header which contents the url with the asyncId and asyncCode query parameters. So, this seems to be the same principle as for the Create/Update on the polling from https://github.com/hashicorp/go-azure-sdk/pull/1090 should work. But maybe the resource itself needs some update, so it recognizes the delete also as a long running operation where the polling is needed.

What I also noticed is that it really takes some time (approx. 1sec in my case but is probably depending on the size/complexity of th api) until the api really gone on the APIM. That's also what actually causes the issue (because the GET request come to early).

May this help to further investigations.

J0F3 commented 1 day ago

Thank you @wuxu92 . What I can say form my troubleshooting steps is that the API definitely returns 202 with the location header which contents the url with the asyncId and asyncCode query parameters. So, this seems to be the same principle as for the Create/Update on the polling from hashicorp/go-azure-sdk#1090 should work. But maybe the resource itself needs some update, so it recognizes the delete also as a long running operation where the polling is needed.

What I also noticed is that it really takes some time (approx. 1sec in my case but is probably depending on the size/complexity of th api) until the api really gone on the APIM. That's also what actually causes the issue (because the GET request come to early).

May this help to further investigations.

Well with that said I cannot reproduce 202 answers with the api version "2022-08-01" anymore 😵. I get always just a 200. But when I use the api version "2024-06-01-preview" for example I get the 202 responses from the API. So, it seems tobe api version related.

wuxu92 commented 1 day ago

@J0F3 Yes, the latest stable version 2024-05-01 added the 202 response: https://github.com/Azure/azure-rest-api-specs/blob/b9e65c8997ce097af3f773a48d2ea2e0535f3cca/specification/apimanagement/resource-manager/Microsoft.ApiManagement/stable/2024-05-01/apimapis.json#L458. This issue can be resolved once AzureRM upgrades its SDK: https://github.com/hashicorp/go-azure-sdk/blob/25c3e8aca56e73ede8722b5183526a9e1ef1addf/resource-manager/apimanagement/2024-05-01/api/method_delete.go#L91. However, as you mentioned in your investigation, the asyncId parameter is also required, so the go-azure-sdk#1090 may still be a dependency.

J0F3 commented 1 day ago

Yes, but something seems to be strange with the api version 2024-05-01 also. It is the latest stable version which is listed in the documentation. But I cannot use this version in actual calls. The latest version wich worked for me is "2024-06-01-preview". When using "2024-05-01" I get "API version query parameter is not specified or was specified incorrectly. Supported versions: 2014-02-14-preview,2014-02-14,2015-09-15,2016-07-07,2016-10-10,2017-03-01,2018-01-01,2018-06-01-preview,2019-01-01,2019-12-01-preview,2019-12-01,2020-06-01-preview,2020-12-01,2021-01-01-preview,2021-04-01-preview,2021-08-01,2021-12-01-preview,2022-04-01-preview,2022-08-01,2022-09-01-preview,2023-03-01-preview,2023-05-01-preview,2023-09-01-preview,2024-06-01-preview"

wuxu92 commented 1 day ago

This is a known issue with the API version. The service team provided "an estimated completion of the fix in the second week of January." We need a custom poller in the provider before the service team fixes it.

J0F3 commented 23 hours ago

Ah ok, good to know. Thx!

wuxu92 commented 4 hours ago

@J0F3 I tested this configuration on my machine and found that the issue is not caused by an API problem, but by the overlapping order of API deletion and additional_api creation.

When we change local.additional_version from false to true, azurerm_api_management_api.api will be replaced, meaning it will be destroyed and then created. At the same time, azurerm_api_management_api.additional_api[0] will also be created. Since there is no dependency between api and additional_api, their destruction and creation processes run in parallel. When calling for the creation of additional_api, the destruction of api might not have started yet or could still be ongoing, causing an error to occur.

image

J0F3 commented 1 hour ago

@wuxu92 Thank you.
Yes, you are right. I was looking at the debug log, again and I saw too that the recreation of azurerm_api_management_api.api and the creation of azurerm_api_management_api.additional_api[0] overlaps. It is not very good visible in the log but the destroy action gets actually finished after the "already exists" error happend.

So, this basically means that it cannot be fixed in the provider itself, right? Instead, it must be ensured by an explicit depends_on in the configuration that the recreation and creation of the additional api version do run in sequence.

Or do you have any other suggestion for fixing the error?

Thx!

wuxu92 commented 1 hour ago

@J0F3 Yes, the only thing I can think of is to add the depends_on meta argument to sequence the resources. However, I encountered issue of #23322 after adding depends_on, but we can track this in that issue.

J0F3 commented 10 minutes ago

I tested it quickly by adding depends_on = [ azurerm_api_management_api.api ] to the "additional_api" resource and that seems to fix it and the apply runs through without any error. So, the full config would look now like this:


provider "azurerm" {
  resource_provider_registrations = "none"
  features {}
}
locals {
  apim_rg              = "test-rg"
  apim_name            = "test-apim"
  additional_version = false
}

resource "azurerm_api_management_api_version_set" "additional_version" {
  name                = local.apim_name
  api_management_name = local.apim_name
  resource_group_name = local.apim_rg
  display_name        = "replace-api-bug-repro"
  versioning_scheme   = "Header"
  version_header_name = "Version"
}

resource "azurerm_api_management_api" "api" {
  name                = local.additional_version == true ? "replace-api-bug-repro-cloud" : "replace-api-bug-repro"
  resource_group_name = local.apim_rg
  api_management_name = local.apim_name
  revision            = "1"
  display_name        = "replace-api-bug-repro - ${local.additional_version ? "multi version" : "single version"}"
  path                = "test/api"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/openapi.yaml")
  }

  version_set_id = local.additional_version ? azurerm_api_management_api_version_set.additional_version.id : null
  version        = local.additional_version ? "cloud" : null
}

resource "azurerm_api_management_api" "additional_api" {

  count = local.additional_version ? 1 : 0

  name                = "replace-api-bug-repro"
  resource_group_name = local.apim_rg
  api_management_name = local.apim_name
  revision            = "1"
  display_name        = "replace-api-bug-repro - ${local.additional_version ? "multi version" : "single version"}"
  path                = "test/api"
  protocols           = ["https"]

  import {
    content_format = "openapi"
    content_value  = file("${path.module}/openapi.yaml")
  }

  version_set_id = azurerm_api_management_api_version_set.additional_version.id
  version        = null

  depends_on = [ azurerm_api_management_api.api ]
}

In this particular test case, the error form https://github.com/hashicorp/terraform-provider-azurerm/issues/23322 did not occurred for me. But I am very aware of this issue. We have these errors almost on daily basis somewhere. 🙈 However, as this issue here can be fixed with the depends_on and is not really an issue of the provider I am going to close this issue.

@wuxu92 Thank you very much for looking into it and for giving the hint where the cause actually is!