There is one Logic App Standard which uses a connector to Dataverse. An Access Policy is needed so that Workflows from the Logic App can use the connector. Below are the Bicep files, except the Service Plan which I don't have access to. Using various quickstart templates from Azure repos do not seem to solve the issue.
The question is why is this error popping up and what can be done to be solved?
The error is thrown only when the Access Policy is added and it looks like:
"errorCode: PropertyImmutable. Message: The property 'ConnectionAceStorageEntity.PrincipalId' is immutable."
Bicep for Connector:
param DataverseConnectionClient string
param DataverseConnectionName string
param DataverseConnectionTenant string
param Location string
@secure()
param DataverseConnectionSecret string
resource DataverseConnection 'Microsoft.Web/connections@2016-06-01' = {
// This property may give a warning but the it should work and passed further
// https://github.com/Azure/bicep/issues/3512
kind: 'V2'
name: DataverseConnectionName
location: Location
properties: {
displayName: DataverseConnectionName
parameterValues: {
'token:TenantId': DataverseConnectionTenant
'token:clientId': DataverseConnectionClient
'token:grantType': 'client_credentials'
'token:clientSecret': DataverseConnectionSecret
}
api: {
name: 'commondataservice'
displayName: 'Microsoft Dataverse (legacy)'
description: 'Provides access to the environment database in Microsoft Dataverse.'
category: 'Standard'
id: '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${Location}/managedApis/commondataservice'
type: 'Microsoft.Web/locations/managedApis'
}
}
}
// This reference may give a warning but the top level property 'connectionRuntimeUrl' should be offered back
// https://github.com/Azure/bicep/issues/3494
output connectionRuntimeUrl string = DataverseConnection.properties.connectionRuntimeUrl
Bicep for Logic App:
resource LogicAppSite 'Microsoft.Web/sites@2022-09-01' = {
name: LogicAppSiteName
location: LogicAppLocation
tags: {
'hidden-link: /app-insights-resource-id': '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Insights/components/${AppInsightsName}'
}
kind: 'functionapp,workflowapp'
identity: {
type: 'SystemAssigned'
}
properties: {
enabled: true
serverFarmId: ServerFarmId
reserved: false
isXenon: false
hyperV: false
vnetRouteAllEnabled: false
vnetImagePullEnabled: false
vnetContentShareEnabled: false
siteConfig: {
numberOfWorkers: 1
acrUseManagedIdentityCreds: false
alwaysOn: false
http20Enabled: false
appSettings: [
{
name: 'APP_KIND'
value: 'workflowApp'
}
{
name: 'AzureFunctionsJobHost__extensionBundle__id'
value: 'Microsoft.Azure.Functions.ExtensionBundle.Workflows'
}
{
name: 'AzureFunctionsJobHost__extensionBundle__version'
value: '[1.*, 2.0.0)'
}
{
name: 'AzureWebJobsStorage'
value: 'DefaultEndpointsProtocol=https;AccountName=${StorageAccountName};AccountKey=${listKeys('${resourceGroup().id}/providers/Microsoft.Storage/storageAccounts/${StorageAccountName}', '2019-06-01').keys[0].value};EndpointSuffix=core.windows.net'
}
// {
// name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING'
// value: 'DefaultEndpointsProtocol=https;AccountName=${StorageAccountName};AccountKey=${listKeys('${resourceGroup().id}/providers/Microsoft.Storage/storageAccounts/${StorageAccountName}', '2019-06-01').keys[0].value};EndpointSuffix=core.windows.net'
// }
// {
// name: 'WEBSITE_CONTENTSHARE'
// value: LogicAppSiteName
// }
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'WEBSITE_CONTENTOVERVNET'
value: '1'
}
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: reference(resourceId('Microsoft.Insights/components', AppInsightsName), '2020-02-02').ConnectionString
}
{
name: 'WORKFLOWS_SUBSCRIPTION_ID'
value: subscription().subscriptionId
}
{
name: 'WORKFLOWS_LOCATION_NAME'
value: LogicAppLocation
}
{
name: 'WORKFLOWS_RESOURCE_GROUP_NAME'
value: resourceGroup().name
}
{
name: 'WORKFLOWS_DATAVERSE_CONNECTION_NAME'
value: DataverseConnectionName
}
{
name: 'WORKFLOWS_DATAVERSE_CONN_ID'
value: DataverseConnection.id
}
{
name: 'WORKFLOWS_DATAVERSE_CONN_RUNTIMEURL'
// This reference may give a warning but the top level property 'connectionRuntimeUrl' should be offered back
// https://github.com/Azure/bicep/issues/3494
value: DataverseConnection.properties.connectionRuntimeUrl
}
{
name: 'WORKFLOWS_DATAVERSE_URL'
value: DataverseUrl
}
]
}
scmSiteAlsoStopped: false
clientAffinityEnabled: false
clientCertEnabled: false
clientCertMode: 'Required'
hostNamesDisabled: false
customDomainVerificationId: '...'
containerSize: 1536
dailyMemoryTimeQuota: 0
httpsOnly: true
redundancyMode: 'None'
publicNetworkAccess: 'Enabled'
storageAccountRequired: false
keyVaultReferenceIdentity: 'SystemAssigned'
}
}
resource LogicAppSiteName_web 'Microsoft.Web/sites/config@2022-09-01' = {
parent: LogicAppSite
name: 'web'
properties: {
numberOfWorkers: 1
defaultDocuments: [
'Default.htm'
'Default.html'
'Default.asp'
'index.htm'
'index.html'
'iisstart.htm'
'default.aspx'
'index.php'
]
netFrameworkVersion: 'v6.0'
requestTracingEnabled: false
remoteDebuggingEnabled: false
httpLoggingEnabled: false
acrUseManagedIdentityCreds: false
logsDirectorySizeLimit: 35
detailedErrorLoggingEnabled: false
publishingUsername: LogicAppSiteName
scmType: 'None'
use32BitWorkerProcess: false
webSocketsEnabled: false
alwaysOn: false
managedPipelineMode: 'Integrated'
preWarmedInstanceCount: 0
elasticWebAppScaleLimit: 0
functionsRuntimeScaleMonitoringEnabled: true
functionAppScaleLimit: 0
virtualApplications: [
{
virtualPath: '/'
physicalPath: 'site\\wwwroot'
preloadEnabled: false
}
]
loadBalancing: 'LeastRequests'
experiments: {
rampUpRules: []
}
autoHealEnabled: false
vnetRouteAllEnabled: true
vnetPrivatePortsCount: 0
publicNetworkAccess: 'Enabled'
cors: {
supportCredentials: false
}
localMySqlEnabled: false
managedServiceIdentityId: 37494
ipSecurityRestrictions: [
{
ipAddress: 'Any'
action: 'Allow'
priority: 2147483647
name: 'Allow all'
description: 'Allow all access'
}
]
http20Enabled: false
minTlsVersion: '1.2'
scmMinTlsVersion: '1.2'
azureStorageAccounts: {}
}
}
resource LogicAppSiteName_LogicAppSiteName_azurewebsites_net 'Microsoft.Web/sites/hostNameBindings@2022-09-01' = {
parent: LogicAppSite
name: '${LogicAppSiteName}.azurewebsites.net'
properties: {
siteName: LogicAppSiteName
hostNameType: 'Verified'
}
}
And finally the Bicep for Access Policy:
resource connections_dataverse_logicAppSystemAssignedIdentityObjectId 'Microsoft.Web/connections/accessPolicies@2016-06-01' = {
name: DataversePolicyName
parent: DataverseConnection
location: LogicAppLocation
properties: {
principal: {
type: 'ActiveDirectory'
identity: {
tenantId: subscription().tenantId
objectId: LogicAppSite.identity.principalId
}
}
}
}
Found the culprit: if the same connection is created manually, in the portal, with the same name but different PrincipalID, the ARM/Bicep deployment is not able to override it.
Just make sure that your experiments in portal.azure.com are not overlapping the deployments from pipelines.