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.58k stars 4.62k forks source link

Current revision is not identified with its revision ID #12766

Closed Berbe closed 7 months ago

Berbe commented 3 years ago

Community Note

Terraform (and AzureRM Provider) Version

Terraform v1.0.3
on linux_amd64
+ provider registry.terraform.io/hashicorp/azurerm v2.69.0
+ provider registry.terraform.io/hashicorp/template v2.2.0

Affected Resource(s)

Terraform Configuration Files

resource "azurerm_api_management_api" "example" {
  name                = "example"
  resource_group_name = azurerm_resource_group.example.name
  api_management_name = azurerm_api_management.example.name
  revision            = "1"
  display_name        = "example"
  path                = "example"
  service_url         = "https://example.org"
  protocols           = [
    "https",
  ]

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

Debug Output

Debug output ```bash GET /subscriptions/***/resourceGroups/example/providers/Microsoft.ApiManagement/service/example/apis/example;rev=1?api-version=2020-12-01&asyncId=***&asyncCode=201 HTTP/1.1^M Host: management.azure.com^M User-Agent: Go/go1.16.6 (amd64-linux) go-autorest/v14.2.1 Azure-SDK-For-Go/v55.6.0 apimanagement/2020-12-01 HashiCorp Terraform/1.0.3 (+https://www.terraform.io) Terraform Plugin SDK/2.7.0 terraform-provider-azurerm/2.69.0 pid-***^M X-Ms-Correlation-Request-Id: ***^M Accept-Encoding: gzip: timestamp=*** *** [DEBUG] provider.terraform-provider-azurerm_v2.69.0_x5: AzureRM Response for https://management.azure.com/subscriptions/***/resourceGroups/example/providers/Microsoft.ApiManagement/service/example/apis/example;rev=1?api-version=2020-12-01&asyncId=***&asyncCode=201: HTTP/2.0 201 Created^M Content-Length: 1458^M Cache-Control: no-cache^M Content-Type: application/json; charset=utf-8^M Date: ***^M Etag: "***"^M Expires: -1^M Pragma: no-cache^M Server: Microsoft-HTTPAPI/2.0^M Strict-Transport-Security: max-age=31536000; includeSubDomains^M X-Content-Type-Options: nosniff^M X-Ms-Correlation-Request-Id: ***^M X-Ms-Ratelimit-Remaining-Subscription-Reads: ***^M X-Ms-Request-Id: ***^M X-Ms-Routing-Request-Id: ***^M ^M {^M "id": "/subscriptions/***/resourceGroups/example/providers/Microsoft.ApiManagement/service/example/apis/***",^M "type": "Microsoft.ApiManagement/service/apis",^M "name": "***",^M "properties": {^M "displayName": "example",^M "apiRevision": "1",^M "description": "",^M "subscriptionRequired": true,^M "serviceUrl": null,^M "path": "example",^M "protocols": [^M "https"^M ],^M "authenticationSettings": {^M "oAuth2": null,^M "openid": null^M },^M "subscriptionKeyParameterNames": {^M "header": "Ocp-Apim-Subscription-Key",^M "query": "subscription-key"^M },^M "isCurrent": true,^M "apiVersion": ""^M }^M }: timestamp=*** ```

Note the request made by Terraform specified the revision ID, but the idΒ field on the answer returned by the REST API does not contain it anymore, because revision 1 is current in the demo setup. It would have been there at the end of the idΒ string otherwise.

Expected Behaviour

azurerm_api_management_api objects shall be tied with an object ID containing the revision ID at all times, to ensure that the correct object is referenced even when the current revision changes.

Actual Behaviour

Revision ID is only returned by the Azure API Management REST API when the requested API revision is not current. When Terraform tracks such an object (for instance the first time it creates an API), it will attempt to improperly overwrite the current revision of the same API everytime it has been changed:

Actual behaviour ```bash Note: Objects have changed outside of Terraform Terraform detected the following changes made outside of Terraform since the last "terraform apply": # azurerm_api_management_api.example has been changed ~ resource "azurerm_api_management_api" "example" { id = "/subscriptions/***/resourceGroups/example/providers/Microsoft.ApiManagement/service/example/apis/example" name = "example" ~ revision = "1" -> "2" + revision_description = "example" # (10 unchanged attributes hidden) # (2 unchanged blocks hidden) } Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes. ───────────────────────────────────────────────────────────────────────────────────────────── Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # azurerm_api_management_api.example must be replaced -/+ resource "azurerm_api_management_api" "example" { ~ id = "/subscriptions/***/resourceGroups/example/providers/Microsoft.ApiManagement/service/example/apis/example" -> (known after apply) ~ is_current = true -> (known after apply) ~ is_online = false -> (known after apply) name = "example" ~ revision = "2" -> "1" # forces replacement - revision_description = "example" -> null + version = (known after apply) + version_set_id = (known after apply) # (8 unchanged attributes hidden) ~ subscription_key_parameter_names { ~ header = "Ocp-Apim-Subscription-Key" -> (known after apply) ~ query = "subscription-key" -> (known after apply) } # (1 unchanged block hidden) } Plan: 1 to add, 0 to change, 1 to destroy. ```

Steps to Reproduce

  1. terraform apply
  2. Create another revision 2 through the REST API and make it current (be it manually crafting REST API requests or using Terraform, Azure Portal, Azure CLI, etc.: it doesn't matter)
  3. terraform plan

Important Factoids

It is an upstream issue coming from the answers of the REST API. The Azure Go SDK documents this behaviour.

If you change the current active revision, any request on example;rev=<current revision> will return an API object ID not containing said ID, and the previously current API (not being so anymore) will start returning a example;rev=<revision> suffix in its ID.

However, awaiting for an upstream fix (if ever), Terraform could patch the REST API answer before using it, ensuring a ;rev=<revision> suffix always exists in the tracked objects state.

Another side-effect of this is the deletion of the whole API in case an azurerm_api_management_api object tracking a resource ID without such a ;rev=<revision> suffix is deleted.

References

rcskosir commented 7 months ago

Thanks for opening this issue. This was a problem in the 2.x version of the provider which is no longer actively maintained. If this is still an issue with the 3.x version of the provider please do let us know by opening a new issue, thanks!

github-actions[bot] commented 6 months ago

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.