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

Provider ignores APIM error when importing an invalid swagger for the second time #22042

Open ghost opened 1 year ago

ghost commented 1 year ago

Is there an existing issue for this?

Community Note

Terraform Version

1.4.6

AzureRM Provider Version

3.59

Affected Resource(s)/Data Source(s)

azurerm_api_management_api

Terraform Configuration Files

swagger1.json file:

{
  "openapi": "3.0.1",
  "info": {
    "title": "Demo",
    "version": "1.0.0"
  },
  "paths": {
    "/path1": {
      "get": {
        "description": "Description 1",
        "operationId": "operationId1",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/path2": {
      "get": {
        "description": "Description 2",
        "operationId": "operationId2",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}

swagger2 file:

{
  "openapi": "3.0.1",
  "info": {
    "title": "Demo",
    "version": "1.0.0"
  },
  "paths": {
    "/path1": {
      "get": {
        "description": "Description 1",
        "operationId": "operationId2",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/path2": {
      "get": {
        "description": "Description 2",
        "operationId": "operationId3",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}

Manifests:

variable "swagger_file" {
  type        = string
  description = "The swagger file to use to deploy the API."
}

resource "azurerm_api_management_api" "api" {
  name                = "test-apim"
  resource_group_name = "rg"
  api_management_name = "apim-test"
  revision            = "1"
  display_name        = "test"
  path                = "test/test"
  protocols           = ["https"]

  subscription_required = false

  import {
    content_format = "openapi+json"
    content_value  = file(var.swagger_file)
  }
}

Debug Output/Panic Output

Deploy the API with swagger1.json for the first time: OK

Deploy the API with swagger2.json for the first time:

azurerm_api_management_api.api: Modifying... [id=/subscriptions/XXX/resourceGroups/rg/providers/Microsoft.ApiManagement/service/apim-test/apis/test-apim]
azurerm_api_management_api.api: Still modifying... [id=/subscriptions/XXX-...test/apis/test-apim, 10s elapsed]
...
azurerm_api_management_api.api: Still modifying... [id=/subscriptions/XXX-...test/apis/test-apim, 4m0s elapsed]
╷
│ Error: waiting on creating/updating Api: (Name "test-apim" / Service Name "apim-test" / Resource Group "rg"): Future#WaitForCompletion: the number of retries has been exceeded: StatusCode=400 -- Original Error: Code="ValidationError" Message="One or more fields contain incorrect values:" Details=[{"code":"ValidationError","message":"Operation with the same method and URL template already exists: GET, /path1","target":"urlTemplate"},{"code":"ValidationError","message":"Operation with the same method and URL template already exists: GET, /path1","target":"method"}]
│
│   with azurerm_api_management_api.api,
│   on api.tf line 1, in resource "azurerm_api_management_api" "api":
│    1: resource "azurerm_api_management_api" "api" {
│
╵

Deploy the API with swagger2.json for the second time: OK

Expected Behaviour

When applying the manifests with swagger2.json for the second time, I expect to have the same error as when applying for the first time.

Actual Behaviour

Actually, when applying the manifests with swagger2.json for the second time, there is no error.

However, the error is present when using az to deploy the swagger2.json for the second time (as expected):

az apim api import -g "rg" --service-name "apim-test" --path "test/test" --specification-format "OpenApiJson" --api-id "test-api" --specification-path "swagger2.json"

Result:

(ValidationError) One or more fields contain incorrect values:
Code: ValidationError
Message: One or more fields contain incorrect values:
Exception Details:  (ValidationError) Operation with the same method and URL template already exists: GET, /path1
    Code: ValidationError
    Message: Operation with the same method and URL template already exists: GET, /path1
    Target: urlTemplate (ValidationError) Operation with the same method and URL template already exists: GET, /path1
    Code: ValidationError
    Message: Operation with the same method and URL template already exists: GET, /path1
    Target: method

Steps to Reproduce

  1. terraform apply -var swagger_file=swagger1.json # OK
  2. terraform apply -var swagger_file=swagger2.json # Get an error (because we are modifying an existing operationId)
  3. terraform apply -var swagger_file=swagger2.json # OK

Important Factoids

No response

References

No response

J0F3 commented 1 month ago

We have this error very often and I just ran into it today again. So, any plans to fix this at some point?

It seems that the state is erroneously updated despite the Azure APIM API actually returned an error and so the API got actually not updated. This behavior is very very unintuitive because the second time the config just applies with "No changes".

In additional the fact that the actual error mess is just cut off by Terraform makes troubleshooting also unscary difficult. Normally in the error message the reason why the api definition is invalid is shown. But this very relevant part of the error message gets just cut off by terraform/azurerm.

J0F3 commented 1 month ago

@wuxu92 Just saw your PR: https://github.com/hashicorp/go-azure-sdk/pull/1090

Not sure if this would fix also this issue. But I assume not entirely. Because in this case we get the error message but somehow the state is updated despite the error and the interesting part of the error is also chopped in the screenshots of your PR.

So, I assume this issue here need some other/additional fix. Or what do you think?

Thx!