Skip to content

Instantly share code, notes, and snippets.

@magodo
Last active March 11, 2026 10:02
Show Gist options
  • Select an option

  • Save magodo/a7eca6acc2192cb00da9ec959dce2eab to your computer and use it in GitHub Desktop.

Select an option

Save magodo/a7eca6acc2192cb00da9ec959dce2eab to your computer and use it in GitHub Desktop.

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 workloadProfiles is not specified.
  • Workload environment (i.e. v2): This is the recommended version and is enabled for most regions. The API accepts workloadProfiles unset (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

1. azurerm_container_app_environment: Add support for workload_profile

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.

2. r/azurerm_container_app_environment: add infrastructure_resource_group_name

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.

3. azurerm_container_app_environment - add support for Consumption workload profile

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.

4. containerapps - review Optional+Computed properties

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).

5. azurerm_container_app_environment: fix diff suppress on infrastructure_resource_group_name

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 false

The 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.

6. azurerm_container_app_environment - fix import for workload_profile

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment