Azure / bicep

Bicep is a declarative language for describing and deploying Azure resources
MIT License
3.25k stars 754 forks source link

App ManagedEnvironments module ignores infrastructureResourceGroup parameter #11221

Closed arnas78 closed 2 weeks ago

arnas78 commented 1 year ago

Bicep version Bicep CLI version 0.18.4

Describe the bug During Managed Environment resource deployment, bicep module ignores the infrastructureResourceGroup parameter that can be used while using API version 2022-11-01-preview. Before deploying the Managed Environment resource, a what-if command is ran for the bicep module with it's parameters, but during the actual deployment, it gets ignored and after checking the details of the Managed Environment resource, it can be seen that infrastructureResourceGroup parameter is set to null.

To Reproduce Bicep module code (module from Azure/ResourceModules with a few changes):

@description('Required. Name of the Container Apps Managed Environment.')
param name string

@description('Optional. Location for all Resources.')
param location string = resourceGroup().location

@allowed([
  'Consumption'
  'Premium'
])
@description('Optional. Managed environment SKU.')
param skuName string = 'Consumption'

@description('Optional. Logs destination. When set to azure-monitor all logs are configured via diagnostic settings')
param logsDestination string = 'azure-monitor'

@description('Optional. Application Insights connection string used by Dapr to export Service to Service communication telemetry.')
@secure()
param daprAIConnectionString string = ''

@description('Optional. Azure Monitor instrumentation key used by Dapr to export Service to Service communication telemetry.')
@secure()
param daprAIInstrumentationKey string = ''

@description('Optional. CIDR notation IP range assigned to the Docker bridge, network. It must not overlap with any other provided IP ranges and can only be used when the environment is deployed into a virtual network. If not provided, it will be set with a default value by the platform.')
param dockerBridgeCidr string = ''

@description('Conditional. Resource group name that contains a VNET.')
param vnetResourceGroupName string = ''

@description('Conditional. Resource name of a virtual network for infrastructure components. This is used to deploy the environment into a virtual network. Required if "internal" is set to true.')
param virtualNetworkName string = ''

@description('Name of the platform-managed resource group created for the Managed Environment to host infrastructure resources. If a subnet ID is provided, this resource group will be created in the same subscription as the subnet.')
param infrastructureResourceGroup string = ''

@description('Conditional. Resource name of a subnet for infrastructure components. This is used to deploy the environment into a virtual network. Must not overlap with any other provided IP ranges. Required if "internal" is set to true.')
param infrastructureSubnetName string = ''

@description('Optional. Boolean indicating the environment only has an internal load balancer. These environments do not have a public static IP resource. If set to true, then "infrastructureSubnetId" must be provided.')
param internal bool = true

@description('Optional. IP range in CIDR notation that can be reserved for environment infrastructure IP addresses. It must not overlap with any other provided IP ranges and can only be used when the environment is deployed into a virtual network. If not provided, it will be set with a default value by the platform.')
param platformReservedCidr string = ''

@description('Optional. An IP address from the IP range defined by "platformReservedCidr" that will be reserved for the internal DNS server. It must not be the first address in the range and can only be used when the environment is deployed into a virtual network. If not provided, it will be set with a default value by the platform.')
param platformReservedDnsIP string = ''

@description('Optional. Whether or not this Managed Environment is zone-redundant.')
param zoneRedundant bool = true

@description('Optional. Password of the certificate used by the custom domain.')
@secure()
param certificatePassword string = ''

@description('Optional. Certificate to use for the custom domain. PFX or PEM.')
@secure()
param certificateValue string = ''

@description('Optional. DNS suffix for the environment domain.')
param dnsSuffix string = ''

@allowed([
  ''
  'CanNotDelete'
  'ReadOnly'
])
@description('Optional. Specify the type of lock.')
param lock string = ''

@description('Optional. Workload profiles configured for the Managed Environment.')
param workloadProfiles array = []

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-07-01' existing = {
  name: virtualNetworkName
  scope: resourceGroup(vnetResourceGroupName)
}

resource subnet 'Microsoft.Network/virtualNetworks/subnets@2022-07-01' existing = {
  name: infrastructureSubnetName
  parent: virtualNetwork
}

resource managedEnvironment 'Microsoft.App/managedEnvironments@2022-11-01-preview' = {
  name: name
  location: location
  sku: {
    name: skuName
  }
  properties: {
    appLogsConfiguration: {
      destination: logsDestination
    }
    infrastructureResourceGroup: infrastructureResourceGroup
    daprAIConnectionString: daprAIConnectionString
    daprAIInstrumentationKey: daprAIInstrumentationKey
    customDomainConfiguration: {
      certificatePassword: certificatePassword
      certificateValue: !empty(certificateValue) ? certificateValue : null
      dnsSuffix: dnsSuffix
    }
    vnetConfiguration: {
      internal: internal
      infrastructureSubnetId: !empty(infrastructureSubnetName) && internal == true ? subnet.id : null
      dockerBridgeCidr: !empty(infrastructureSubnetName) && internal == true ? dockerBridgeCidr : null
      platformReservedCidr: !empty(infrastructureSubnetName) && internal == true ? platformReservedCidr : null
      platformReservedDnsIP: !empty(infrastructureSubnetName) && internal == true ? platformReservedDnsIP : null
    }
    workloadProfiles: !empty(workloadProfiles) ? workloadProfiles : null
    zoneRedundant: zoneRedundant
  }
}

resource managedEnvironment_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock)) {
  name: '${managedEnvironment.name}-${lock}-lock'
  properties: {
    level: any(lock)
    notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.'
  }
  scope: managedEnvironment
}

@description('The name of the resource group the Managed Environment was deployed into.')
output resourceGroupName string = resourceGroup().name

@description('The location the resource was deployed into.')
output location string = managedEnvironment.location

@description('The name of the Managed Environment.')
output name string = managedEnvironment.name

@description('The resource ID of the Managed Environment.')
output resourceId string = managedEnvironment.id

Module deployment what-if output:

Scope: /subscriptions/subscriptionNumber/resourceGroups/rgName

  + Microsoft.App/managedEnvironments/menvName [2022-11-01-preview]

      apiVersion:                                               "2022-11-01-preview"
      id:                                                       "/subscriptions/subscriptionNumber/resourceGroups/rgName/providers/Microsoft.App/managedEnvironments/menvName"
      location:                                                 "regionName"
      name:                                                     "menvName"
      properties.appLogsConfiguration.destination:              "azure-monitor"
      properties.customDomainConfiguration.certificatePassword: "*******"
      properties.customDomainConfiguration.certificateValue:    "*******"
      properties.daprAIConnectionString:                        "*******"
      properties.daprAIInstrumentationKey:                      "*******"
      properties.infrastructureResourceGroup:                   "newRgName"
      properties.vnetConfiguration.infrastructureSubnetId:      "/subscriptions/subscriptionNumber/resourceGroups/rgName/providers/Microsoft.Network/virtualNetworks/vnetName/subnets/subnetName"
      properties.vnetConfiguration.internal:                    true
      properties.zoneRedundant:                                 true
      sku.name:                                                 "Consumption"
      type:                                                     "Microsoft.App/managedEnvironments"

Additional context After successful deployment, infrastructureResourceGroup is set to null and newly created MC Resource Group name is still randomly generated and not the one provided in properties.infrastructureResourceGroup. This parameter feature is required to make the newly created Managed Cluster Resource Group name follow the naming convention used throughout the project.

KrisSimon commented 5 months ago

I ran into the same issue with 2023-11-02-preview. How it is done? Can you provide a link to the commit, please?

arnas78 commented 5 months ago

@KrisSimon If I remember correctly, I just updated the API version to 2023-05-01 and it started working.

KrisSimon commented 4 months ago

Hi @arnas78 Thanks for your quick reply. For me it works when creating an capp-svc-lb inside the managed rg, but not if Azure deploy a kubernetes-internal LoadBalancer. Then the custom name is just ignored. Tried with 2023-05-01 and 2023-11-02-preview.

Can you please reopen this issue? 🙏

tichaczech commented 1 month ago

We have the same issue—the Resource Group name is ignored upon creation. We tried multiple versions starting from 2023-05-01, all to the latest (and we also updated the Bicep compiler). It works when created through the Azure portal.

Can you please reopen the issue? At least to find the reproduction steps...

Thank you!

alex-frankel commented 1 month ago

@tichaczech - can you provide the latest bicep code you are using? At a glance, this sounds like an issue with the ContainerApps API, not Bicep, but want to confirm.

If it's working in the portal during their create flow, you can download the template they use for that setting by selecting "Download template for automation" on the "Review + Create" tab.

ganhammar commented 1 month ago

I see the same issue, I'm trying to create a new environment using 2024-03-01 with the Sweden Central region where I have specified the infrastructureResourceGroup, but it's still trying to use a generated name (e.g. nicehill-e803ee94).

Here's part of the bicep that I'm using to create the environment:

resource managedEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
  name: 'me-my-project-dev-001'
  location: location
  tags: tags
  properties: {
    vnetConfiguration: {
      internal: true
      infrastructureSubnetId: subnet.id
    }
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalytics.properties.customerId
        sharedKey: logAnalytics.listKeys().primarySharedKey
      }
    }
    infrastructureResourceGroup: 'rg-my-project-infra-dev-001'
  }
}
ganhammar commented 1 month ago

I got it working by tweaking the Bicep a bit, not exactly sure which parameter fixed the issue for me, but, if it helps:

resource managedEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
  name: 'me-my-project-dev-001'
  location: location
  tags: tags
  properties: {
    vnetConfiguration: {
      internal: true
      infrastructureSubnetId: subnet.id
    }
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalytics.properties.customerId
        sharedKey: logAnalytics.listKeys().primarySharedKey
      }
    }
    infrastructureResourceGroup: 'rg-my-project-infra-dev-001'
    zoneRedundant: false
    workloadProfiles: [
      {
        workloadProfileType: 'Consumption'
        name: 'Consumption'
      }
    ]
    peerAuthentication: {
      mtls: {
        enabled: false
      }
    }
    peerTrafficConfiguration: {
      encryption: {
        enabled: false
      }
    }
  }
}
microsoft-github-policy-service[bot] commented 3 weeks ago

Hi @arnas78, this issue has been marked as stale because it was labeled as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 3 days of this comment. Thanks for contributing to bicep! :smile: :mechanical_arm: