diff --git a/internal/services/containerapps/container_app_environment_resource.go b/internal/services/containerapps/container_app_environment_resource.go index a8edc920dace..936bd80d025e 100644 --- a/internal/services/containerapps/container_app_environment_resource.go +++ b/internal/services/containerapps/container_app_environment_resource.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-helpers/resourcemanager/location" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourcegroups" "github.com/hashicorp/go-azure-helpers/resourcemanager/tags" "github.com/hashicorp/go-azure-sdk/resource-manager/containerapps/2023-05-01/managedenvironments" "github.com/hashicorp/go-azure-sdk/resource-manager/operationalinsights/2020-08-01/workspaces" @@ -36,6 +37,7 @@ type ContainerAppEnvironmentModel struct { ZoneRedundant bool `tfschema:"zone_redundancy_enabled"` Tags map[string]interface{} `tfschema:"tags"` WorkloadProfiles []helpers.WorkloadProfileModel `tfschema:"workload_profile"` + InfrastructureResourceGroup string `tfschema:"infrastructure_resource_group_name"` DefaultDomain string `tfschema:"default_domain"` DockerBridgeCidr string `tfschema:"docker_bridge_cidr"` @@ -89,6 +91,16 @@ func (r ContainerAppEnvironmentResource) Arguments() map[string]*pluginsdk.Schem Description: "The ID for the Log Analytics Workspace to link this Container Apps Managed Environment to.", }, + "infrastructure_resource_group_name": { + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + RequiredWith: []string{"workload_profile"}, + ValidateFunc: resourcegroups.ValidateName, + Description: "Name of the platform-managed resource group created for the Managed Environment to host infrastructure resources. **Note:** Only valid if a `workload_profile` is specified. If `infrastructure_subnet_id` is specified, this resource group will be created in the same subscription as `infrastructure_subnet_id`.", + }, + "infrastructure_subnet_id": { Type: pluginsdk.TypeString, Optional: true, @@ -195,6 +207,10 @@ func (r ContainerAppEnvironmentResource) Create() sdk.ResourceFunc { managedEnvironment.Properties.DaprAIConnectionString = pointer.To(containerAppEnvironment.DaprApplicationInsightsConnectionString) } + if containerAppEnvironment.InfrastructureResourceGroup != "" { + managedEnvironment.Properties.InfrastructureResourceGroup = pointer.To(containerAppEnvironment.InfrastructureResourceGroup) + } + if containerAppEnvironment.LogAnalyticsWorkspaceId != "" { logAnalyticsId, err := workspaces.ParseWorkspaceID(containerAppEnvironment.LogAnalyticsWorkspaceId) if err != nil { @@ -286,6 +302,7 @@ func (r ContainerAppEnvironmentResource) Read() sdk.ResourceFunc { state.StaticIP = pointer.From(props.StaticIP) state.DefaultDomain = pointer.From(props.DefaultDomain) state.WorkloadProfiles = helpers.FlattenWorkloadProfiles(props.WorkloadProfiles) + state.InfrastructureResourceGroup = pointer.From(props.InfrastructureResourceGroup) } } diff --git a/internal/services/containerapps/container_app_environment_resource_test.go b/internal/services/containerapps/container_app_environment_resource_test.go index e304eeaf018d..066a2d5746b9 100644 --- a/internal/services/containerapps/container_app_environment_resource_test.go +++ b/internal/services/containerapps/container_app_environment_resource_test.go @@ -160,6 +160,21 @@ func TestAccContainerAppEnvironment_zoneRedundant(t *testing.T) { }) } +func TestAccContainerAppEnvironment_infraResourceGroup(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_container_app_environment", "test") + r := ContainerAppEnvironmentResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.infraResourceGroup(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (r ContainerAppEnvironmentResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := managedenvironments.ParseManagedEnvironmentID(state.ID) if err != nil { @@ -399,3 +414,57 @@ resource "azurerm_subnet" "control" { `, r.template(data), data.RandomInteger) } + +func (r ContainerAppEnvironmentResource) infraResourceGroup(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +%[1]s + +resource "azurerm_virtual_network" "test" { + name = "acctestvirtnet%[2]d" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_subnet" "control" { + name = "control-plane" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.0.0/23"] + delegation { + name = "acctestdelegation%[2]d" + service_delegation { + actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] + name = "Microsoft.App/environments" + } + } +} + +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 + + infrastructure_resource_group_name = "rg-acctest-CAEnv%[2]d" + + workload_profile { + maximum_count = 2 + minimum_count = 0 + name = "My-GP-01" + workload_profile_type = "D4" + } + + zone_redundancy_enabled = true + + tags = { + Foo = "Bar" + secret = "sauce" + } +} +`, r.template(data), data.RandomInteger) +} diff --git a/website/docs/r/container_app_environment.html.markdown b/website/docs/r/container_app_environment.html.markdown index 608042096844..94a232cd965e 100644 --- a/website/docs/r/container_app_environment.html.markdown +++ b/website/docs/r/container_app_environment.html.markdown @@ -48,6 +48,10 @@ The following arguments are supported: * `dapr_application_insights_connection_string` - (Optional) Application Insights connection string used by Dapr to export Service to Service communication telemetry. Changing this forces a new resource to be created. +* `infrastructure_resource_group_name` - (Optional) Name of the platform-managed resource group created for the Managed Environment to host infrastructure resources. Changing this forces a new resource to be created. + +~> **Note:** Only valid if a `workload_profile` is specified. If `infrastructure_subnet_id` is specified, this resource group will be created in the same subscription as `infrastructure_subnet_id`. + * `infrastructure_subnet_id` - (Optional) The existing Subnet to use for the Container Apps Control Plane. Changing this forces a new resource to be created. ~> **NOTE:** The Subnet must have a `/21` or larger address space. @@ -74,9 +78,9 @@ A `workload_profile` block supports the following: * `workload_profile_type` - (Required) Workload profile type for the workloads to run on. Possible values include `D4`, `D8`, `D16`, `D32`, `E4`, `E8`, `E16` and `E32`. -* `maximum_count` - (Optional) The maximum number of instances of workload profile that can be deployed in the Container App Environment. +* `maximum_count` - (Required) The maximum number of instances of workload profile that can be deployed in the Container App Environment. -* `minimum_count` - (Optional) The minimum number of instances of workload profile that can be deployed in the Container App Environment. +* `minimum_count` - (Required) The minimum number of instances of workload profile that can be deployed in the Container App Environment. ## Attributes Reference