Azure / bicep-types-az

Bicep type definitions for ARM resources
MIT License
86 stars 27 forks source link

Microsoft.PowerPlatform/enterprisePolicies: Problem with Microsoft provided bicep template and work around (that has 'type' issue) #2251

Open robjdav opened 2 months ago

robjdav commented 2 months ago

Resource Type

Microsoft.PowerPlatform/enterprisePolicies

Api Version

2020-10-30-preview

Issue Type

Type is unavailable

Other Notes

I have been trying to deploy a Power Platform enterprise policy in Azure using Bicep. However, using the Bicep template provided by Microsoft here results in the deployment error : "Failed to create or update the enterprise policy, request body is null. (Code: InputValidationError)"

I was able to use a power shell script to deploy the enterprise policy, I then exported the resulting ARM template for this and decompiled into Bicep in VSCode. This resulted in a similar Bicep template but had some slight differences and intelli-sense picked up an potential error : "The property "virtualNetworks" expected a value of type "VirtualNetworkPropertiesList | null" but the provided value is of type "[object, object]". If this is an inaccuracy in the documentation, please report it to the Bicep Team."

However, this actually successfully deployed with no errors - I've provided examples of both templates below the first is the (non-working) Microsoft Template, the second is the exported Arm template which worked when converted to Bicep and then deployed.

Bicep Repro

Non working template - taken from here

param policyName string = 'vnetEPpowerplatform'
param vnetId string
param subnetName1 string
param subnetName2 string

resource enterprisePolicy 'Microsoft.PowerPlatform/enterprisePolicies@2020-10-30-preview' = {
  name: policyName
  location: 'uk'
  kind: 'NetworkInjection'
  properties: {
    healthStatus: 'Undetermined'
    networkInjection: {
        virtualNetworks: {

        value: [
          {
            id: vnetId
            subnet: {
              name: subnetName1
            }
          }
          {
            id: vnetId
            subnet: {
              name: subnetName2
            }
          }
        ]
      }
    }
  }
}

Below is the bicep template that worked (but has intelli-sense error):

param policyName string = 'vnetEPpowerplatform'
param vnetId string
param subnetName1 string
param subnetName2 string

resource enterprisePolicy 'Microsoft.PowerPlatform/enterprisePolicies@2020-10-30-preview' = {
  name: policyName
  location: 'uk'
  kind: 'NetworkInjection'
  properties: {
    healthStatus: 'Undetermined'
    networkInjection: {
      virtualNetworks: [
        {
          id: vnetId
          subnet: {
            name: subnetName1
          }
        }
        {
          id: vnetId
          subnet: {
            name: subnetName2
          }
        }
      ]
    }
  }
}

Confirm

webstean commented 2 months ago

Thanks - using this, I was able to come up with a version that works with the Terraform AZAPI provider (might help some else)

resource "azapi_resource" "pplatform_policy_injection" {
  for_each = azurerm_resource_group.powerapps

  type      = "Microsoft.PowerPlatform/enterprisePolicies@2020-10-30-preview"
  name      = "pplatform-epolicy-networking-${local.regions["sydney"].data_location}"
  location  = lower(local.regions[each.key].data_location)
  parent_id = each.value.id
  body = jsonencode({
    properties = {
      healthStatus = "Undetermined"
      networkInjection = {
        virtualNetworks = [
          {
            id = data.azurerm_virtual_network.vnet["sydney"].id
            subnet = {
              name = data.azurerm_subnet.pplatform["sydney"].name
            }
          },
          {
            id = data.azurerm_virtual_network.vnet["melbourne"].id
            subnet = {
              name = data.azurerm_subnet.pplatform["melbourne"].name
            }
          }
        ]
      }
    }
    ## "Encryption", "Identity", "Lockbox", "NetworkInjection", "PrivateEndpoint"
    kind = "NetworkInjection"
  })
  schema_validation_enabled = false
  tags                      = each.value.tags
  lifecycle {
    ignore_changes = [tags.created]
  }
}