Azure / terraform-provider-azapi

Terraform provider for Azure Resource Manager Rest API
https://registry.terraform.io/providers/Azure/azapi/latest
Mozilla Public License 2.0
192 stars 49 forks source link

Deprecation of ignore_body_changes #583

Open nyanhp opened 2 months ago

nyanhp commented 2 months ago

Hi!

According to the documentation https://github.com/Azure/terraform-provider-azapi/blob/d588fce8e0dcc6f6bfa8755ad89a4282c87b4b01/docs/resources/resource.md?plain=1#L91 ignore_body_changes is deprecated, but what are we supposed to use instead? lifecycle can be used for some, but not all attributes.

image

ms-henglu commented 2 months ago

Hi @nyanhp ,

Thank you for taking time to report this issue!

Please first switch to use the dynamic attribute in body then use the lifecycle.ignore_changes to suppress the diff.

lifecycle can be used for some, but not all attributes.

Would you please share more details about the scenario? Thanks!

gareda commented 2 months ago

Hello, I can add a situation in the lifecycle parameter does not work. If I try to implement a virtual network with subnets where the lifecycle of the subnets I want to ignore, I get the following error:

resource "azapi_resource" "vnet" {
  type      = "Microsoft.Network/virtualNetworks@2024-01-01"
  name      = "test"
  parent_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test"
  location  = "Spain Central"

  body = {
    properties = {
      addressSpace = {
        addressPrefixes = ["10.0.0.0/16"]
      }
      dhcpOptions = {
        dnsServers = ["8.8.8.8", "1.1.1.1"]
      }

      subnets = [
        {
          name = "subnet1"
          properties = {
            addressPrefixes = ["10.0.1.0/24"]
          }
        },
        {
          name = "subnet2"
          properties = {
            addressPrefixes = ["10.0.2.0/24"]
          }
        }
      ]
    }
  }

  lifecycle {
    ignore_changes = [body.properties.subnets]
  }
}
Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Invalid configuration
│ 
│   with azapi_resource.virtual_network,
│   on main.tf line 1, in resource "azapi_resource" "virtual_network":
│    1: resource "azapi_resource" "virtual_network" {
│ 
│ embedded schema validation failed: the argument "body" is invalid:
│ `properties.subnets.0.properties.provisioningState` is not expected here, it's read only
│ `properties.subnets.0.properties.ipamPoolPrefixAllocations` is not expected here. Do you mean `properties.subnets.0.properties.ipAllocations`? 
│ `properties.subnets.0.etag` is not expected here, it's read only
│ `properties.subnets.1.etag` is not expected here, it's read only
│ `properties.subnets.1.properties.provisioningState` is not expected here, it's read only
│ `properties.subnets.1.properties.serviceEndpoints.0.provisioningState` is not expected here, it's read only
│ `properties.subnets.1.properties.ipamPoolPrefixAllocations` is not expected here. Do you mean `properties.subnets.1.properties.ipAllocations`? 
│  You can try to update `azapi` provider to the latest version or disable the validation using the feature flag `schema_validation_enabled = false` within the resource block
ms-henglu commented 2 months ago

Hi @gareda ,

Thanks for the details! Behind the scene, the ignore_changes will add everything from the remote state which includes some read-only fields. It's easy to bypass that, please disable the validation using the feature flag schema_validation_enabled = false within the resource block.

gareda commented 2 months ago

@ms-henglu I understand that I can do a bypass by disabling schema validation, but shouldn't the correct ones be that it is not necessary?

Another example where ignore_body_changes is more interesting than lifecycle is that the former can be dynamic, you can set conditionals using a : x ? y or other systems like for, lifecycle does not allow this at the moment, the values have to be static.

jchancellor-ms commented 1 month ago

Concur with @gareda on the last statement. As we publish modules that are reusable, the ability to dynamically define fields that are ignored is a nice workaround to the lack of support for dynamic configurations in a lifecycle block. Is there any appetite to have support for both types?