The issue is related to the workload_profile and infrastructure_resource_group_name. I'll try to list the history of the related PRs to get the full picture of the story.
Before going through the history, a little bit of the API behavior needs to clarify. The ACE has two versions of environments:
- Consumption only environment (i.e. v1): This is now deprecated and in a deprecating process. Whilst for some reason, some regions still default to this version if
workloadProfilesis not specified. - Workload environment (i.e. v2): This is the recommended version and is enabled for most regions. The API accepts
workloadProfilesunset (though users can set it explicitly), and will return a Consumption profile by default.
See: https://learn.microsoft.com/en-us/azure/container-apps/environment-type-consumption-only
Link: hashicorp/terraform-provider-azurerm#23478.
This PR initially introduces the workload_profile with a special handling to skip the Consumption type during flatten. This is probably to keep the existing config (without workload_profile set) continue working, however, this apparently will break if the user explicitly set the workload_profile, which causes a plan diff.
Link: hashicorp/terraform-provider-azurerm#24361
This PR initially introduces the infrastructure_resource_group_name, which is set as O+C, mainly because if infrastructure_subnet_id is specified, this attribute will be populated with a resource group name that is managed by the service team. Otherwise, it is explicitly set by the user, the workload_profile must be also set with a type other than Consumption.
Link: hashicorp/terraform-provider-azurerm#25285
This seems to solve an early issue in a defaults to v1 ACE region, where to create a workload profile env, a user has to specify the workloadProfiles explicitly. This makes users who omit the workloadProfiles at the creation will create a v1 ACE and fail to update it later:
but when I add new workload profile to the existing Consumption only environment I see the below error:
│ Managed Environment Name: "testenv1"): performing CreateOrUpdate: unexpected status 400 with error: EnvironmentNotCreatedWithWorkloadProfile: To add a new workload profile, environment should be created with a Workload Profile
The PR fixes this by always ensuring to set the workloadProfiles (defaults to one Consumption profile type).
For the changes made by this PR, there are some confusions about the introduction to the conditional force new logic: it seems to set the workload_profile as force new when either adding a profile to an empty profile list, or removing all profiles from a non-empty profile list. It will probably fail nowadays in v2 regions.
Link: hashicorp/terraform-provider-azurerm#26365
This PR removes the O+C trait on infrastructure_resource_group_name, instead it introduces an buggy customize diff logic which will always return true, i.e. diff suppressed (since there is a condition of newValue == oldValue, which will always be false).
Link: hashicorp/terraform-provider-azurerm#27007
This PR fixes the buggy customize diff logic introduced by #26365 above, with a reverse logic:
if profiles := d.Get("workload_profile").(*pluginsdk.Set).List(); len(profiles) > 0 && newValue == "" {
for _, profile := range profiles {
if profile.(map[string]interface{})["workload_profile_type"].(string) != string(helpers.WorkloadProfileSkuConsumption) {
return true
}
}
}
return falseThe logic here assumes that workload_profile's precense indicate whether this is a consumption only ACE or not, which is wrong (even if the provider intentionally to not set the Consumption profile into state, it can still be a v2 ACE). As long as this is a v2 ACE, user can either set the infra RG name explicitly, or leave it unset to allow the service team to choose a name for them, which is a valid O+C scenario.
Link: hashicorp/terraform-provider-azurerm#30139
Adding a DiffSupressFunc on a Set seems to be buggy: hashicorp/terraform-plugin-sdk#477.
Back to the issue itself: Assuming changing the infrastructure_resource_group_name back to O+C should resolve the issue. However, when I run acctest against:
resource "azurerm_container_app_environment" "test" {
name = "acctest-CAEnv%[2]d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
infrastructure_subnet_id = azurerm_subnet.control.id
zone_redundancy_enabled = true
tags = {
Foo = "Bar"
secret = "sauce"
}
}It failed with:
testcase.go:192: Step 1/3 error: After applying this test step, the refresh plan was not empty.
stdout
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# azurerm_container_app_environment.test will be updated in-place
~ resource "azurerm_container_app_environment" "test" {
id = "/subscriptions/xxxx/resourceGroups/acctestRG-CAE-260310165449410028/providers/Microsoft.App/managedEnvironments/acctest-CAEnv260310165449410028"
name = "acctest-CAEnv260310165449410028"
tags = {
"Foo" = "Bar"
"secret" = "sauce"
}
# (17 unchanged attributes hidden)
- workload_profile {
- maximum_count = 0 -> null
- minimum_count = 0 -> null
- name = "Consumption" -> null
- workload_profile_type = "Consumption" -> null
}
}
Plan: 0 to add, 1 to change, 0 to destroy.
This indicates the DiffSuppress of workload_profile doesn't work as expected somehow. Also it's unclear why the user's plan diff doesn't show the workload_profile change.
This is actually caused by hashicorp/terraform-provider-azurerm#30139. I've observed that with the above config applied. If I run terraform plan and break point at the DiffSuppressFunc, the old value and new value are the same after refresh, which is the read value, though the old value shall be empty since there is no workload_profile defined in the state (i.e. null).