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.51k stars 4.6k forks source link

Reading content from files for APIM policies (.xml) results in unnecessary changes detected, due to whitespace. #23388

Open andrewCluey opened 11 months ago

andrewCluey commented 11 months ago

Is there an existing issue for this?

Community Note

Terraform Version

1.5.3

AzureRM Provider Version

3.74.0

Affected Resource(s)/Data Source(s)

azurerm_api_management_api_operation_policy

Terraform Configuration Files

resource "azurerm_api_management_api_operation_policy" "main" {
  operation_id        = var.op_id
  api_management_name = var.api_management_instance_name
  resource_group_name = var.api_management_resource_group_name
  api_name            = azurerm_api_management_api.main.name
  xml_content         = file("${local.apis_path}/policy.xml")
}

Debug Output/Panic Output

# module.api.azurerm_api_management_api_operation_policy.main["api_v1"] will be updated in-place       
  ~ resource "azurerm_api_management_api_operation_policy" "main" {
        id                  = "/subscriptions/ccccc-xxxxxe-xxxxxdccc44/resourceGroups/rg-xxxxx/providers/Microsoft.ApiManagement/service/apim-dev-xxxxxx/apis/api_v1/operations/xxxxxxx"
      ~ xml_content         = <<-EOT
            <policies>
                <inbound>
          -             <base />
          +         <base />
                        <validate-content unspecified-content-type-action="ignore" max-size="102400" size-exceeded-action="ignore">
                                <content type="application/json" validate-as="json" action="ignore" />
          -             </validate-content>
          +             </validate-content>

Expected Behaviour

The .xml files have not changed, so there should be no planned changes.

Actual Behaviour

The policy.xml file have not changed, but seems to be that because Terraform adds whitespace and new line/escape characters to the xml_content in the state file, TF interprets this as a change.

It should be possible to suppress this as the files are effectively 'the same'

I believe this is done for other file types (json) when deploying Azure policy (policy_definition_resource.go).

Steps to Reproduce

deploy an API to APIM and also an API operation policy for the API being deployed.

Use the xml_content argument and read this in from an xml file.

Once deployed, run a plan immediately after, Terraform reports that every line of the operation policy has to be replaced, with exactly the same content (only difference being white space).

Important Factoids

No response

References

No response

sinbai commented 11 months ago

Hi @andrewCluey thanks for opening this issue. Unfortunately, I could not reproduce this issue with the following terraform configuration. Could you reproduce with it?

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "3.74.0"
    }
  }
}
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "acctestRG-example"
  location = "eastus"
}

resource "azurerm_api_management" "test" {
  name                = "acctestAM-0928"
  location            = azurerm_resource_group.test.location
  resource_group_name = azurerm_resource_group.test.name
  publisher_name      = "pub1"
  publisher_email     = "pub1@email.com"
  sku_name            = "Consumption_0"
}

resource "azurerm_api_management_api" "test" {
  name                = "acctestapi-0928"
  resource_group_name = azurerm_resource_group.test.name
  api_management_name = azurerm_api_management.test.name
  display_name        = "Butter Parser"
  path                = "butter-parser"
  protocols           = ["https", "http"]
  revision            = "3"
  description         = "What is my purpose? You parse butter."
  service_url         = "https://example.com/foo/bar"

  subscription_key_parameter_names {
    header = "X-Butter-Robot-API-Key"
    query  = "location"
  }
}

resource "azurerm_api_management_api_operation" "test" {
  operation_id        = "acctest-operation"
  api_name            = azurerm_api_management_api.test.name
  api_management_name = azurerm_api_management.test.name
  resource_group_name = azurerm_resource_group.test.name
  display_name        = "DELETE Resource"
  method              = "DELETE"
  url_template        = "/resource"
}

resource "azurerm_api_management_api_operation_policy" "test" {
  api_name            = azurerm_api_management_api.test.name
  api_management_name = azurerm_api_management.test.name
  resource_group_name = azurerm_resource_group.test.name
  operation_id        = azurerm_api_management_api_operation.test.operation_id

  xml_content = file("api_management_api_operation_policy.xml")
}

Test data: api_management_api_operation_policy.xml

alexwiese commented 10 months ago

I can reproduce this. Looking into this further you can update the APIM policies using the ARM REST APIs using spaces instead of tabs. You can then execute a GET request against the ARM API and it returns tabs rather than spaces. This seems like an issue in APIM/ARM itself, that the resource provider would need to workaround to ignore these whitespace changes.

sudhakarinka commented 6 months ago

we are encountering same issue, our policies are kept in a folder xml_content = templatefile("../apim/policies/xyz.xml", {}) resulting in recurring change detection

alexwiese commented 3 months ago

we are encountering same issue, our policies are kept in a folder xml_content = templatefile("../apim/policies/xyz.xml", {}) resulting in recurring change detection

If you use tabs in that file instead of spaces do you still get the issue?