I have this bicep file that deploys an Azure B2C tenant in location: 'Australia'
resource b2cDirectory 'Microsoft.AzureActiveDirectory/b2cDirectories#2021-04-01' = {
location: 'Australia'
name: 'tenantname1.onmicrosoft.com'
sku: {
name: 'PremiumP2'
tier: 'A0'
}
properties: {
createTenantProperties: {
countryCode: 'AU'
displayName: 'tenantname1 B1Cd223'
}
}
tags: {
Department: 'Dev'
}
}
This works fine. but it doesn't work for location: 'Europe' even though they say they support it.
This is the error I'm getting when I try to deploy this in location: 'Europe'.
Is this a temporary thing or am I missing something?
I tried in my environment and got below results:
Initially, I got same error in my environment.
{"status":"Failed","error":{"code":"Deployment Failed", "message":"Atleast one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-deployment-operations for usage details.","details":[{"code":"InternalSer verError", "message":"{\r\n"error"; {\r\n" "code":
"ResourceDeploymentFailure",\r\n"message": "The response for resou rce had empty or invalid content."\r\n }\r\n}"}]}}_
I tried with some changes in bicep code as below :
test.bicep:
resource b2cDirectory 'Microsoft.AzureActiveDirectory/b2cDirectories#2021-04-01' = {
location: 'europe'
name: 'demotenant326.onmicrosoft.com'
sku: {
name: 'Standard'
tier: 'A0'
}
properties: {
createTenantProperties: {
countryCode: 'DE'
displayName: 'demo1tenantv B1Cd223'
}
}
tags: {
Department: 'pro'
}
}
In the above bicep file I changed sku, country code = 'DE' indicates **Germany**and it deploys an Azure B2C tenant with location: 'europe' successfully.
Console:
New-AzResourceGroupDeployment -TemplateFile test.bicep -ResourceGroupName <your resource grp>
WARNING: /home/venkatesan/test.bicep(2,15) : Warning no-hardcoded-location: A resource location should not use a hard-coded string or variable value. Please use a parameter value, an expression, or the string 'global'. Found: 'europe' [https://aka.ms/bicep/linter/no-hardcoded-location]
DeploymentName : test
ResourceGroupName : <your resource grp>
ProvisioningState : Succeeded
Timestamp : 2/17/2023 8:08:56 AM
Mode : Incremental
TemplateLink :
Parameters :
Outputs :
DeploymentDebugLogLevel :
Reference:
Region availability and data residency - Azure AD B2C | Microsoft Learn
Related
I'm having a heck of a time trying to deploy a simple Azure BlobFS linked service into an ADF using Bicep (which I have only really started to learn).
The bicep I have thus far is:
//---Data Factory
resource datafactory 'Microsoft.DataFactory/factories#2018-06-01' = {
name: adf_name
location: loc_name
identity: {
type: 'SystemAssigned'
}
properties: {
globalParameters: {}
publicNetworkAccess: 'Enabled'
}
}
//--- Data Factory Linked Service
resource adls_linked_service 'Microsoft.DataFactory/factories/linkedservices#2018-06-01' = {
name: 'ls_adf_to_adls'
parent: datafactory
properties: {
annotations: []
connectVia: {
parameters: {}
referenceName: 'AutoResolveIntegrationRuntime'
type: 'IntegrationRuntimeReference'
}
description: 'linked_service_for_adls'
parameters: {}
type: 'AzureBlobFS'
typeProperties: {
accountKey: datafactory.identity.principalId
azureCloudType: 'AzurePublic'
credential: {
referenceName: 'string'
type: 'CredentialReference'
}
servicePrincipalCredentialType: 'SecureString'
servicePrincipalId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
servicePrincipalKey: {
type: 'SecureString'
value: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
}
tenant: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
url: bicepstorage.properties.primaryEndpoints.blob
}
}
}
The ADF resource deploys fine by itself as does the ADLS (symbolic name is: bicepstorage). The issue is when I added the linkedservice resource block. I get:
New-AzResourceGroupDeployment: /home/vsts/work/1/s/psh/deploy_main.ps1:12
Line |
12 | New-AzResourceGroupDeployment `
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 22:46:27 - The deployment 'main' failed with error(s). Showing 1 out of
| 1 error(s). Status Message: Input is malformed. Reason: Could not get
| integration runtime details for AutoResolveIntegrationRuntime
| (Code:InputIsMalformedDetailed) CorrelationId:
| f77ef878-5314-46ea-9de6-65807845a104
The only integration runtime in the ADF is the 'AutoResolveIntegrationRuntime'. When I inspect it in the portal it's green, running and healthy.
I'm using task: AzurePowerShell#5 on ubuntu-latest in ADF, but I get the same error when I try to deploy the template directly from vscode.
I'm out of ideas and would really appreciate some assistance. I found the documentation for the 'connectVia' block (actually all the documentation on bicep linked services!) to be really confusing; if anyone could tell me exactly what is supposed to go in there, I'd really appreciate it.
Thanks.
As mentioned in this documentation, If you want to create a linked service to adls(blobfs) with default Azure IR (autoresolveintegrationruntime) then you can remove the ConnectionVia property in linked service block in your bicep template.
To test this I have created a bicep template which will deploy adlsgen2 storage account, data factory and a linked service to it using the service principal based authentication.
Here is the sample template for your reference:
param location string='westus'
//---Data Factory
resource storage 'Microsoft.Storage/storageAccounts#2022-09-01'={
name:'<storageAccountName>'
location:location
kind:'StorageV2'
sku:{
name:'Standard_GRS'
}
properties:{
accessTier:'Hot'
supportsHttpsTrafficOnly:true
isHnsEnabled:true
}
}
resource datafactory 'Microsoft.DataFactory/factories#2018-06-01' = {
name: '<AdfName>'
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
globalParameters: {}
publicNetworkAccess: 'Enabled'
}
}
//--- Data Factory Linked Service
resource adls_linked_service 'Microsoft.DataFactory/factories/linkedservices#2018-06-01' = {
name: '<linkedserviceName>'
parent: datafactory
properties: {
annotations: []
description: 'linked_service_for_adls'
parameters: {}
type: 'AzureBlobFS'
typeProperties: {
url: storage.properties.primaryEndpoints.dfs
//encryptedCredential:storage.listKeys(storage.id).keys[0].value
servicePrincipalCredential: {
type: 'SecureString'
value: '<serviceprincipalKey>'
}
servicePrincipalId:'<serviceprincipalappId>'
servicePrincipalCredentialType:'ServicePrincipalKey'
azureCloudType:'AzurePublic'
servicePrincipalKey: {
type: 'SecureString'
value: '<serviceprincipalKey>'
}
tenant: '<tenantId>'
}
}
}
I'm a contractor working on an existing Azure project. Currently, my client is manually configuring all their Azure resources for each environment (Dev, QA, Prod). I know this is shocking to people, but their subscriptions are a mess. I'm trying to setup IaC deployments using bicep.
For the Azure App Services, they have an IP Access Restriction setup to only allow traffic from their APIM instance. When I look at the access restrictions for the app service (under networking) for the main site, I can see it listed.
However, when I deploy using --what-if, it comes back saying it will create the access restriction rule. I'm not expecting this because it should already exist. I've searched high and low but can't find the answer.
apiAppService.bicep
#description('The name of the target app service without any prefix or suffix. i.e. Contoso')
param apiName string
#description('The abbreviation of the target environment. i.e. dev')
#allowed([
'dev'
'qa'
'prod'
])
param environment string
#description('The Azure region the resource group is to be created in.')
param region string
#description('The abbreviation of the Azure region included as part of the resource group name. i.e. NCUS')
param regionAbbreviation string
#description('The properties of the SKU for the app service plan.')
param appServicePlanSku object
#description('The runtime stack of the target app service. i.e. DOTNETCORE|6.0')
param runtimeStack string
#description('The values required to setup the IP access restriction')
param ipRestriction object
var appServicePlanName = 'ASP-${apiName}-${regionAbbreviation}-${environment}'
var appServiceName = 'productname-${apiName}-api-${environment}'
resource appServicePlan 'Microsoft.Web/serverfarms#2022-03-01' = {
name: appServicePlanName
location: region
sku: {
name: appServicePlanSku.name
tier: appServicePlanSku.tier
}
kind: 'linux'
properties: {
reserved: true
}
}
resource appService 'Microsoft.Web/sites#2022-03-01' = {
name: appServiceName
location: region
identity: {
type: 'SystemAssigned'
}
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
siteConfig: {
linuxFxVersion: runtimeStack
ipSecurityRestrictions: [
{
name: ipRestriction.name
action: ipRestriction.action
priority: ipRestriction.priority
ipAddress: ipRestriction.ipAddress
}
]
}
}
}
The results of the --what-if deployment
~ Microsoft.Web/sites/productname-apiname-api-dev [2022-03-01]
+ properties.siteConfig.ipSecurityRestrictions: [
0:
action: "allow"
ipAddress: "a.b.c.d/32"
name: "Allow ONLY APIM"
priority: 300
]
+ properties.siteConfig.localMySqlEnabled: false
~ properties.httpsOnly: false => true
Am I trying to configure different things? What am I doing wrong?
Using Azure Resource Explorer proved to be very helpful. Check it out if you haven't and you're building bicep files. The IP restrictions are actually in a resource with a path 'config/web' off the app service resource. Essentially the definition looks like
resource webConfig 'Microsoft.Web/sites/config#2022-03-01' = {
name: 'web'
parent: appService
properties: {
linuxFxVersion: runtimeStack
ipSecurityRestrictions: [
{
name: ipRestriction.name
action: ipRestriction.action
priority: ipRestriction.priority
ipAddress: ipRestriction.ipAddress
}
{
name: 'Deny all'
description: 'Deny all access'
action: 'Deny'
priority: 2147483647
ipAddress: 'Any'
}
]
}
}
The name: 'web' and parent: appService is very important as is the default deny all rule at the end.
As said in the question above. The errror message is written below:
{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"InvalidParameters","message":"Invalid parameter: CustomHostnameOwnershipCheckFailed. A CNAME record pointing from test to apiaresocool.azure-api.net was not found.."}]}
I've tried deploying the app manually and it works fine. It creates the cname for me, without needing to verify it exists.
Here is my bicep file. I'm using main to call on this bicep file:
param api_Management_Name string = 'apiManage'
resource apiManagement 'Microsoft.ApiManagement/service#2021-08-01' = {
name: api_Management_Name
location: resourceGroup().location
sku: {
capacity:0
name: 'Consumption'
}
properties: {
customProperties: {
}
notificationSenderEmail: null
publisherEmail: '******' //I add my email here
publisherName: 'Clarion Housing'
virtualNetworkType: 'None'
hostnameConfigurations: [
{
certificatePassword: null
defaultSslBinding: true
encodedCertificate: null
hostName: 'test'
identityClientId: null
keyVaultId: null
negotiateClientCertificate: false
type: 'Proxy'
}
]
}
}
Please advise. Thanks
I've created a Bicep template. In it I create a user-assigned identity and reference it in other resources like this
var identityName = 'mid-dd-test'
var roleName = 'TestRole'
var roleDescription = 'Some test'
var roleScopes = [
resourceGroup().id
]
var resolvedActions = [
'Microsoft.Resources/subscriptions/resourcegroups/*'
'Microsoft.Compute/sshPublicKeys/*'
]
var permittedDataActions = []
resource userId 'Microsoft.ManagedIdentity/userAssignedIdentities#2018-11-30' = {
name: identityName
location: resourceGroup().location
}
resource roleDef 'Microsoft.Authorization/roleDefinitions#2018-01-01-preview' = {
name: guid(subscription().id, 'bicep', 'dsadsd')
properties: {
roleName: roleName
description: roleDescription
type: 'customRole'
assignableScopes: roleScopes
permissions: [
{
actions: resolvedActions
dataActions: permittedDataActions
}
]
}
}
resource roles 'Microsoft.Authorization/roleAssignments#2018-09-01-preview' = {
name: guid(subscription().id, 'bicep-roleassignments', 'dsddsd')
properties: {
principalId: userId.properties.principalId
roleDefinitionId: roleDef.id
}
}
Whenever I deploy this I need 2 runs. The first run ends in the error message:
Principal XXX does not exist in the directory YYY
where XXX would be a principal id the user-assigned identity has and YYY is my tenant id. If I now look into the portal the identity is created and XXX is the correct id.
So when I now simply re-run the deployment it works.
I consider it a bug in dependsOn which should relate to ARM templates and not Bicep. I could not find any place where I can report ARM template issues to Microsoft.
I'm asking to assure that I do not miss something else here.
Edit: Added complete working sample which shows the bug. To use it, copy the script content into a test.bicep locally. Then create a resource group (lets call it "rg-test"), ensure that your local POSH context is set correctly and execute the following line in the folder where you stored the bicep in:
New-AzResourceGroupDeployment -Name deploy -Mode Incremental -TemplateFile .\test.bicep -ResourceGroupName rg-test
In the role assignment, you need to specify the principalType to ServicePrincipal and also use an api version greater or equal than: 2018-09-01-preview.
When you create a service principal, it is created in an Azure AD. It takes some time for the service principal to be replicated globally. By setting the principalType to ServicePrincipal, it tells the ARM API t0 wait for the replication.
resource roles 'Microsoft.Authorization/roleAssignments#2018-09-01-preview' = {
name: guid(subscription().id, 'bicep-roleassignments', 'dsddsd')
properties: {
principalId: userId.properties.principalId
roleDefinitionId: roleDef.id
principalType: 'ServicePrincipal'
}
}
You need to reference a newly created identity inside identity property of the target resource. dependsOn is redundant because bicep creates resources in the correct order based on actual usage:
resource userId 'Microsoft.ManagedIdentity/userAssignedIdentities#2018-11-30' = {
name: 'myidentity'
location: resourceGroup().location
}
resource appService 'Microsoft.Web/sites#2021-02-01' = {
name: 'appserviceName'
location: resourceGroup().location
properties: {
//...
}
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'/subscriptions/{your_subscription_id}/resourceGroups/${resourceGroup().name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${userId.name}': {}
}
}
}
The documentation doesn't recommend to use dependsOn without as strong reason:
In most cases, you can use a symbolic name to imply the
dependency between resources. If you find yourself setting explicit
dependencies, you should consider if there's a way to remove it.
So bicep does not require the dependsOn segment if referencing the property correctly.
Need to reference the properties.principalId of the userId in the resource block.
So would look like:
userId.properties.principalId
Here's a quickstart that calls out in a working example how this would work.
I'm using Azure Bicep to create a virtualNetwork with a single subnet and then use that as the input for creating an aks cluster with : vnetSubnetID: virtualNetwork.properties.subnets[0].id
The first time I run the command, it creates the virtual network and cluster just fine, but the second time I run the command it gives this error :
{"error":{"code":"InvalidTemplateDeployment","message":"The template
deployment 'cluster' is not valid according to the validation
procedure. The tracking id is '[REDACTED_JUST_IN_CASE]'. See inner errors for
details.","details":[{"code":"PropertyChangeNotAllowed","message":"Provisioning
of resource(s) for container service playground-cluster0 in resource
group showcase-kevinplayground2 failed. Message: {\n "code":
"PropertyChangeNotAllowed",\n "message": "Changing property
'agentPoolProfile.vnetSubnetID' is not allowed.",\n "target":
"agentPoolProfile.vnetSubnetID"\n }. Details: "}]}}
I double checked and there is just the one subnet inside the virtualNetwork created by the deployment (no other magically appeared or anything).
I repeated the experiment on a second resource group and the same thing happened, so it's reproducible.
Here is the full bicep file (just call az deployment group create --resource-group showcase-kevinplayground2 -f cluster.bicep in the resource group of your choice)
targetScope = 'resourceGroup'
resource virtualNetwork 'Microsoft.Network/virtualNetworks#2021-02-01' = {
name: 'aksVirtualNetwork'
location: resourceGroup().location
properties:{
addressSpace:{
addressPrefixes:[
'10.10.0.0/16'
]
}
subnets:[
{
name: 'aks'
properties:{
addressPrefix: '10.10.5.0/24'
}
}
]
}
}
resource aksManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities#2018-11-30' = {
name: 'playgroundIdentity'
location: resourceGroup().location
}
resource aks 'Microsoft.ContainerService/managedClusters#2021-02-01' = {
name: 'playground-cluster0'
location: resourceGroup().location
identity: {
type:'UserAssigned'
userAssignedIdentities: {
'${aksManagedIdentity.id}': {}
}
}
sku: {
name: 'Basic'
tier: 'Free'
}
properties: {
kubernetesVersion: '1.21.2'
dnsPrefix: 'playground'
enableRBAC: true
networkProfile: {
networkPlugin: 'azure'
networkPolicy: 'calico'
}
aadProfile: {
managed: true
enableAzureRBAC: true
}
autoUpgradeProfile: {}
apiServerAccessProfile: {
enablePrivateCluster: false
}
agentPoolProfiles: [
{
name: 'aksnodes'
count: 1
vmSize: 'Standard_B2s'
osDiskSizeGB: 30
osDiskType: 'Managed'
vnetSubnetID: virtualNetwork.properties.subnets[0].id
osType: 'Linux'
maxCount: 1
minCount: 1
enableAutoScaling: true
type: 'VirtualMachineScaleSets'
mode: 'System'
orchestratorVersion: null
}
]
}
}
Looking at this reported github issue, you need to use the resourceId function.
In your case, something like that should work:
vnetSubnetID: resourceId('Microsoft.Network/virtualNetworks/subnets', 'aksVirtualNetwork', 'aks')