diff --git a/azuredeploy.json b/azuredeploy.json index 0c735c47..5fa90063 100644 --- a/azuredeploy.json +++ b/azuredeploy.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "85984846235553802" + "templateHash": "11197593129532448033" } }, "parameters": { @@ -40,18 +40,11 @@ "description": "Specify the Enterprise Application Object Id. (This is the unique ID of the service principal object associated with the application.)" } }, - "enableBurstable": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Feature Flag: Enable Burstable Server Types" - } - }, "customVMSize": { "type": "string", "defaultValue": "", "metadata": { - "description": "Use customized server types." + "description": "The size of the VM to use for the cluster." } }, "ingressType": { @@ -74,25 +67,46 @@ "description": "Feature Flag: Enable Storage accounts public access." } }, - "enableManage": { + "enablePodSubnet": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Feature Flag: Enable management with a virtual machine and bastion host." + "description": "Feature Flag: Enable AKS Enhanced Subnet Support (Azure CNI)" } }, - "vmAdminUsername": { - "type": "string", - "defaultValue": "azureUser", + "clusterConfiguration": { + "type": "object", + "defaultValue": { + "enablePrivateCluster": "", + "enableNodeAutoProvisioning": "" + }, "metadata": { - "description": "(Optional) If manage then the ssh user name for the virtual machine." + "description": "Optional: Cluster Configuration Overrides" } }, - "enablePodSubnet": { - "type": "bool", - "defaultValue": false, + "clusterSoftware": { + "type": "object", + "defaultValue": { + "enable": true, + "osduCore": true, + "osduReference": true, + "osduVersion": "", + "repository": "", + "branch": "", + "tag": "" + }, "metadata": { - "description": "Feature Flag: Enable AKS Enhanced Subnet Support (Azure CNI)" + "description": "(Optional) Software Load Override - {enable/osduCore/osduReference} --> true/false, {repository} --> https://github.com/azure/osdu-devloper {branch} --> branch:main" + } + }, + "experimentalSoftware": { + "type": "object", + "defaultValue": { + "enable": false, + "adminUI": false + }, + "metadata": { + "description": "(Optional) Experimental Software Override - {enable/adminUI} --> true/false" } }, "vnetConfiguration": { @@ -123,31 +137,6 @@ "description": "Optional. Bring your own Virtual Network." } }, - "clusterSoftware": { - "type": "object", - "defaultValue": { - "enable": true, - "osduCore": true, - "osduReference": true, - "osduVersion": "", - "repository": "", - "branch": "", - "tag": "" - }, - "metadata": { - "description": "(Optional) Software Load Override - {enable/osduCore/osduReference} --> true/false, {repository} --> https://github.com/azure/osdu-devloper {branch} --> branch:main" - } - }, - "experimentalSoftware": { - "type": "object", - "defaultValue": { - "enable": false, - "adminUI": false - }, - "metadata": { - "description": "(Optional) Experimental Software Override - {enable/adminUI} --> true/false" - } - }, "clusterNetwork": { "type": "object", "defaultValue": { @@ -158,24 +147,6 @@ "metadata": { "description": "Cluster Network Overrides - {ingress} (Both/Internal/External), {serviceCidr}, {dnsServiceIP}" } - }, - "clusterNetworkPlugin": { - "type": "string", - "defaultValue": "azure", - "allowedValues": [ - "kubenet", - "azure" - ], - "metadata": { - "description": "The network plugin to use for the Kubernetes cluster." - } - }, - "clusterAdminIds": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional: Specify the AD Users and/or Groups that can manage the cluster." - } } }, "variables": { @@ -2660,6 +2631,7 @@ } }, { + "condition": "[variables('enableVnetInjection')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "network-blade", @@ -2692,9 +2664,6 @@ "identityId": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.principalId.value]" }, - "enableBastion": { - "value": "[parameters('enableManage')]" - }, "enablePodSubnet": { "value": "[parameters('enablePodSubnet')]" }, @@ -2734,7 +2703,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6534636039925862206" + "templateHash": "874063949568482708" } }, "definitions": { @@ -2867,6 +2836,7 @@ }, "enableBastion": { "type": "bool", + "defaultValue": false, "metadata": { "description": "Feature Flag to Enable Bastion" } @@ -6409,15 +6379,16 @@ "deploymentScriptIdentity": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" }, + "userAssignedIdentityName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" + }, "workspaceResourceId": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.resourceId.value]" }, "workspaceName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.name.value]" }, - "subnetId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value]" - }, + "subnetId": "[if(variables('enableVnetInjection'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value), createObject('value', ''))]", "cmekConfiguration": { "value": "[variables('cmekConfiguration')]" }, @@ -6445,7 +6416,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6347882963527520709" + "templateHash": "6675662845319092902" } }, "definitions": { @@ -6517,6 +6488,12 @@ "description": "The Diagnostics Workspace Name" } }, + "userAssignedIdentityName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent user assigned identity. Required if the template is used in a standalone deployment." + } + }, "deploymentScriptIdentity": { "type": "string", "metadata": { @@ -6570,7 +6547,8 @@ "containers": [ "system", "azure-webjobs-hosts", - "azure-webjobs-eventhub" + "azure-webjobs-eventhub", + "gitops" ], "tables": [ "partitionInfo" @@ -6661,9 +6639,26 @@ }, "storageDNSZoneForwarder": "[format('blob.{0}', environment().suffixes.storage)]", "storageDnsZoneName": "[format('privatelink.{0}', variables('storageDNSZoneForwarder'))]", + "directoryUploads": [ + { + "directory": "software" + }, + { + "directory": "charts" + }, + { + "directory": "stamp" + } + ], "cosmosDnsZoneName": "privatelink.documents.azure.com" }, "resources": { + "userAssignedIdentity": { + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "name": "[parameters('userAssignedIdentityName')]" + }, "vaultDNSZone": { "condition": "[parameters('enablePrivateLink')]", "type": "Microsoft.Network/privateDnsZones", @@ -9936,279 +9931,37 @@ "redis" ] }, - "sshKey": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-keyvault-sshkey', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "kvName": { - "value": "[reference('keyvault').outputs.name.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "useExistingManagedIdentity": { - "value": true - }, - "managedIdentityName": { - "value": "[parameters('deploymentScriptIdentity')]" - }, - "existingManagedIdentitySubId": { - "value": "[subscription().subscriptionId]" - }, - "existingManagedIdentityResourceGroupName": { - "value": "[resourceGroup().name]" - }, - "sshKeyName": { - "value": "PrivateLinkSSHKey-" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10238020194982496109" - }, - "name": "SSH Key Pair", - "description": "This module creates a SSH Key Pair and stores it in an Azure Key Vault", - "owner": "azure-global-energy" - }, - "parameters": { - "kvName": { - "type": "string", - "metadata": { - "description": "The name of the Azure Key Vault" - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "The location of the Key Vault and where to deploy the module resources to" - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "How the deployment script should be forced to execute" - } - }, - "rbacRoleNeeded": { - "type": "string", - "defaultValue": "b86a8fe4-44ce-4948-aee5-eccb2c155cd7", - "metadata": { - "description": "Azure RoleId that are required for the DeploymentScript resource to import images" - } - }, - "useExistingManagedIdentity": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Does the Managed Identity already exists, or should be created" - } - }, - "managedIdentityName": { - "type": "string", - "defaultValue": "[format('id-keyvault-ssh-{0}', parameters('location'))]", - "metadata": { - "description": "Name of the Managed Identity resource" - } - }, - "existingManagedIdentitySubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]", - "metadata": { - "description": "For an existing Managed Identity, the Subscription Id it is located in" - } - }, - "existingManagedIdentityResourceGroupName": { - "type": "string", - "defaultValue": "[resourceGroup().name]", - "metadata": { - "description": "For an existing Managed Identity, the Resource Group it is located in" - } - }, - "sshKeyName": { - "type": "string", - "metadata": { - "description": "The name of the SSH Key to be created.\nif name is my-virtual-machine-ssh then the private key will be named my-virtual-machine-sshprivate and the public key will be named my-virtual-machine-sshpublic.\n" - } - }, - "initialScriptDelay": { - "type": "string", - "defaultValue": "30s", - "metadata": { - "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" - } - }, - "cleanupPreference": { - "type": "string", - "defaultValue": "OnSuccess", - "allowedValues": [ - "OnSuccess", - "OnExpiration", - "Always" - ], - "metadata": { - "description": "When the script resource is cleaned up" - } - } - }, - "variables": { - "$fxv#0": "#!/bin/bash\nset -e\n\necho \"Waiting on Identity RBAC replication ($initialDelay)\"\nsleep $initialDelay\n\n# Generate the SSH key pair\necho \"Generating SSH key pair...\"\n#ssh-keygen -t rsa -b 4096 -C \"azure@example.com\" -f id_rsa -N \"\"\nssh-keygen -m PEM -t rsa -b 4096 -f id_rsa -q\n\n# Import the private key and public key as strings\nprivateKey=$(cat id_rsa)\npublicKey=$(cat id_rsa.pub)\n\n# Re-Login to Azure CLI using the managed identity\necho \"Logging in to Azure CLI using managed identity...\"\naz login --identity\n\necho \"Storing secret ${sshKeyName}private in Key Vault $keyVaultName...\"\nprivSecret=$(az keyvault secret set --vault-name \"$keyVaultName\" --name \"${sshKeyNamePrivate}\" --value \"$privateKey\")\n\necho \"Storing secret ${sshKeyName}public in Key Vault $keyVaultName...\"\npubSecret=$(az keyvault secret set --vault-name \"$keyVaultName\" --name \"${sshKeyNamePublic}\" --value \"$publicKey\")\n\nprivateSecretId=$(echo $privSecret | jq -r \".id\" | cut -d'/' -f-5) # remove the version from the url;\npublicSecretId=$(echo $pubSecret | jq -r \".id\" | cut -d'/' -f-5) # remove the version from the url;\n\njsonOutputString=$(jq -cn --arg public $publicSecretId --arg private $privateSecretId '{secretUris: $ARGS.named}')\necho $jsonOutputString\necho $jsonOutputString > $AZ_SCRIPTS_OUTPUT_PATH\n\n# Cleanup\nrm -f id_rsa id_rsa.pub", - "privateKeySecretName": "[format('{0}private', parameters('sshKeyName'))]", - "publicKeySecretName": "[format('{0}public', parameters('sshKeyName'))]" - }, - "resources": [ - { - "condition": "[not(parameters('useExistingManagedIdentity'))]", - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "name": "[parameters('managedIdentityName')]", - "location": "[parameters('location')]" - }, - { - "condition": "[not(empty(parameters('rbacRoleNeeded')))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('kvName'))]", - "name": "[guid(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRoleNeeded'))]", - "principalId": "[if(parameters('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId)]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" - ] - }, - { - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2023-08-01", - "name": "[format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('sshKeyName'), ':', ''), '/', '-'))]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} - } - }, - "kind": "AzureCLI", - "properties": { - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "azCliVersion": "2.63.0", - "timeout": "PT30M", - "retentionInterval": "PT1H", - "environmentVariables": [ - { - "name": "keyVaultName", - "value": "[parameters('kvName')]" - }, - { - "name": "sshKeyNamePrivate", - "value": "[variables('privateKeySecretName')]" - }, - { - "name": "sshKeyNamePublic", - "value": "[variables('publicKeySecretName')]" - }, - { - "name": "initialDelay", - "value": "[parameters('initialScriptDelay')]" - } - ], - "scriptContent": "[variables('$fxv#0')]", - "cleanupPreference": "[parameters('cleanupPreference')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", - "[extensionResourceId(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))))]" - ] - } - ], - "outputs": { - "publicKeyUri": { - "type": "string", - "metadata": { - "description": "The URI of the public key secret in the Key Vault" - }, - "value": "[reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('sshKeyName'), ':', ''), '/', '-'))), '2023-08-01').outputs.secretUris.public]" - }, - "privateKeyUri": { - "type": "string", - "metadata": { - "description": "The URI of the private key secret in the Key Vault" - }, - "value": "[reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('sshKeyName'), ':', ''), '/', '-'))), '2023-08-01').outputs.secretUris.private]" - }, - "publicKeySecretName": { - "type": "string", - "metadata": { - "description": "The name of the public key secret in the Key Vault" - }, - "value": "[variables('publicKeySecretName')]" - }, - "privateKeySecretName": { - "type": "string", - "metadata": { - "description": "The name of the private key secret in the Key Vault" - }, - "value": "[variables('privateKeySecretName')]" - } - } - } - }, - "dependsOn": [ - "keyvault" - ] - }, - "certificates": { + "vaultEndpoint": { + "condition": "[parameters('enablePrivateLink')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-keyvault-cert', parameters('bladeConfig').sectionName)]", + "name": "[format('{0}-keyvault-pep', parameters('bladeConfig').sectionName)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "kvName": { + "resourceName": { "value": "[reference('keyvault').outputs.name.value]" }, - "location": { - "value": "[parameters('location')]" - }, - "useExistingManagedIdentity": { - "value": true - }, - "managedIdentityName": { - "value": "[parameters('deploymentScriptIdentity')]" - }, - "existingManagedIdentitySubId": { - "value": "[subscription().subscriptionId]" - }, - "existingManagedIdentityResourceGroupName": { - "value": "[resourceGroup().name]" + "subnetResourceId": { + "value": "[parameters('subnetId')]" }, - "certificateNames": { + "groupIds": { "value": [ - "https-certificate" + "vault" ] }, - "initialScriptDelay": { - "value": "0" + "privateDnsZoneGroup": { + "value": { + "privateDNSResourceIds": [ + "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.vaultcore.azure.net')]" + ] + } }, - "validity": { - "value": 24 + "serviceResourceId": { + "value": "[reference('keyvault').outputs.resourceId.value]" } }, "template": { @@ -10218,549 +9971,166 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "16332457843273172675" - }, - "name": "Key Vault Certificate", - "description": "This module creates a Key Vault Certificate and stores it in an Azure Key Vault", - "owner": "azure-global-energy" + "templateHash": "3640359773342242706" + } }, "parameters": { - "kvName": { - "type": "string", - "metadata": { - "description": "The name of the Azure Key Vault" - } - }, - "location": { - "type": "string", - "metadata": { - "description": "The location to deploy the resources to" - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "How the deployment script should be forced to execute" - } - }, - "rbacRolesNeededOnKV": { - "type": "string", - "defaultValue": "a4417e6f-fecd-4de8-b567-7b0420556985", - "metadata": { - "description": "The RoleDefinitionId required for the DeploymentScript resource to interact with KeyVault" - } - }, - "useExistingManagedIdentity": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Does the Managed Identity already exists, or should be created" - } - }, - "managedIdentityName": { + "resourceName": { "type": "string", - "defaultValue": "[format('id-KeyVaultCertificateCreator-{0}', parameters('location'))]", "metadata": { - "description": "Name of the Managed Identity resource" + "description": "Required. Name of the private endpoint resource to create." } }, - "existingManagedIdentitySubId": { + "subnetResourceId": { "type": "string", - "defaultValue": "[subscription().subscriptionId]", "metadata": { - "description": "For an existing Managed Identity, the Subscription Id it is located in" + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." } }, - "existingManagedIdentityResourceGroupName": { + "serviceResourceId": { "type": "string", - "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "For an existing Managed Identity, the Resource Group it is located in" + "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "certificateNames": { + "groupIds": { "type": "array", "metadata": { - "description": "The names of the certificate to create. Use when creating many certificates." + "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "certificateCommonNames": { + "applicationSecurityGroups": { "type": "array", - "defaultValue": "[parameters('certificateNames')]", + "defaultValue": [], "metadata": { - "description": "The common names of the certificate to create. Use when creating many certificates." + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, - "initialScriptDelay": { + "customNetworkInterfaceName": { "type": "string", - "defaultValue": "0", + "defaultValue": "", "metadata": { - "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" + "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, - "cleanupPreference": { - "type": "string", - "defaultValue": "OnSuccess", - "allowedValues": [ - "OnSuccess", - "OnExpiration", - "Always" - ], + "ipConfigurations": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "When the script resource is cleaned up" + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." } }, - "issuerName": { - "type": "string", - "defaultValue": "Self", + "privateDnsZoneGroup": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Self, or user defined {IssuerName} for certificate signing" + "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." } }, - "issuerProvider": { + "location": { "type": "string", - "defaultValue": "", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Certificate Issuer Provider, DigiCert, GlobalSign, or internal options may be used." + "description": "Optional. Location for all Resources." } }, - "disabled": { + "crossTenant": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Create certificate in disabled state. Default: false" + "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." } }, - "accountId": { - "type": "string", - "defaultValue": "", + "roleAssignments": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Account ID of Certificate Issuer Account" + "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" } }, - "issuerPassword": { - "type": "securestring", - "defaultValue": "", + "tags": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Password of Certificate Issuer Account" + "description": "Tags." } }, - "organizationId": { + "lock": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Organization ID of Certificate Issuer Account" - } - }, - "isCrossTenant": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Override this parameter if using this in cross tenant scenarios" - } - }, - "reuseKey": { - "type": "bool", - "defaultValue": true, + "defaultValue": "NotSpecified", + "allowedValues": [ + "CanNotDelete", + "NotSpecified", + "ReadOnly" + ], "metadata": { - "description": "The default policy might cause errors about CSR being used before, so set this to false if that happens" + "description": "Optional. Specify the type of lock." } }, - "validity": { - "type": "int", - "defaultValue": 12, - "minValue": 1, - "maxValue": 1200, + "customDnsConfigs": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Optional. Override default validityInMonths 12 value" + "description": "Optional. Custom DNS configurations." } }, - "performRoleAssignment": { - "type": "bool", - "defaultValue": true, + "manualPrivateLinkServiceConnections": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Set to false to disable role assignments within this module. Default: true" + "description": "Optional. Manual PrivateLink Service Connections." } } }, "variables": { - "$fxv#0": "#!/bin/bash\nset -e\ninitialDelay=\"${initialDelay:-5}\"\nretryMax=\"${retryMax:-5}\"\ncertName=\"${certName:-default-cert}\"\ncertCommonName=\"${certCommonName:-default}\"\nvalidity=\"${validity:-12}\"\nakvName=\"${akvName:-keyvault}\"\nissuerName=\"${issuerName:-}\"\nreuseKey=\"${reuseKey:-true}\"\nretrySleep=\"${retrySleep:-5}\"\n\necho \"Waiting on Identity RBAC replication (\\\"$initialDelay\\\")\"\nsleep \"$initialDelay\"\n\n#Retry loop to catch errors (usually RBAC delays)\nretryLoopCount=0\nuntil [ \"$retryLoopCount\" -ge \"$retryMax\" ]\ndo\n echo \"Creating AKV Cert $certName with CN $certCommonName (attempt $retryLoopCount)...\"\n\n if [ -z \"$issuerName\" ] || [ -z \"$issuerProvider\" ]; then\n policy=$(az keyvault certificate get-default-policy \\\n | sed -e s/\\\"validityInMonths\\\":\\ 12/\\\"validityInMonths\\\":\\ \"${validity}\"/g \\\n | sed -e s/CN=CLIGetDefaultPolicy/CN=\"${certCommonName}\"/g )\n else\n if [ \"$issuerProvider\" == \"DigiCert\" ] || [ \"$issuerProvider\" == \"GlobalCert\" ]; then\n az keyvault certificate issuer create \\\n --vault-name \"$akvName\" \\\n --issuer-name \"$issuerName\" \\\n --provider-name \"$issuerProvider\" \\\n --account-id \"$accountId\" \\\n --password \"$issuerPassword\" \\\n --organizatiion-id \"$organizationId\"\n else\n az keyvault certificate issuer create \\\n --vault-name \"$akvName\" \\\n --issuer-name \"$issuerName\" \\\n --provider-name \"$issuerProvider\"\n fi\n policy=$(az keyvault certificate get-default-policy \\\n | sed -e s/\\\"validityInMonths\\\":\\ 12/\\\"validityInMonths\\\":\\ \"${validity}\"/g \\\n | sed -e s/CN=CLIGetDefaultPolicy/CN=\"${certCommonName}\"/g \\\n | sed -e s/\\\"name\\\":\\ \\\"Self\\\"/\\\"name\\\":\\ \\\"\"${issuerName}\"\\\"/g \\\n | sed -e s/\\\"reuseKey\\\":\\ true/\\\"reuseKey\\\":\\ \"${reuseKey}\"/g )\n fi\n az keyvault certificate create \\\n --vault-name \"$akvName\" \\\n -n \"$certName\" \\\n -p \"$policy\" \\\n --disabled \"$disabled\" \\\n && break\n\n sleep \"$retrySleep\"\n retryLoopCount=$((retryLoopCount+1))\ndone\n\necho \"Getting Certificate $certName\";\nretryLoopCount=0\ncreatedCert=$(az keyvault certificate show -n \"$certName\" --vault-name \"$akvName\" -o json)\nwhile [ -z \"$(echo \"$createdCert\" | jq -r '.x509ThumbprintHex')\" ] && [ $retryLoopCount -lt \"$retryMax\" ]\ndo\n echo \"Waiting for cert creation (attempt $retryLoopCount)...\"\n sleep $retrySleep\n createdCert=$(az keyvault certificate show -n $certName --vault-name $akvName -o json)\n retryLoopCount=$((retryLoopCount+1))\ndone\n\nunversionedSecretId=$(echo $createdCert | jq -r \".sid\" | cut -d'/' -f-5) # remove the version from the url;\njsonOutputString=$(echo $createdCert | jq --arg usid $unversionedSecretId '{name: .name ,certSecretId: {versioned: .sid, unversioned: $usid }, thumbprint: .x509Thumbprint, thumbprintHex: .x509ThumbprintHex}')\necho $jsonOutputString > $AZ_SCRIPTS_OUTPUT_PATH", - "delegatedManagedIdentityResourceId": "[if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))]" + "name": "[format('pep-{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]" }, "resources": [ { - "condition": "[not(parameters('useExistingManagedIdentity'))]", - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[parameters('managedIdentityName')]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2022-05-01", + "name": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]", "location": "[parameters('location')]", - "metadata": { - "description": "A new managed identity that will be created in this Resource Group, this is the default option" + "tags": "[parameters('tags')]", + "properties": { + "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", + "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", + "ipConfigurations": "[parameters('ipConfigurations')]", + "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "customDnsConfigs": "[parameters('customDnsConfigs')]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('resourceName')]", + "properties": { + "privateLinkServiceId": "[parameters('serviceResourceId')]", + "groupIds": "[parameters('groupIds')]" + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } } }, { - "condition": "[parameters('performRoleAssignment')]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('kvName'))]", - "name": "[guid(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), parameters('rbacRolesNeededOnKV'), parameters('managedIdentityName'), string(parameters('useExistingManagedIdentity')))]", + "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2017-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", + "name": "[format('{0}-{1}-lock', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')), parameters('lock'))]", "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRolesNeededOnKV'))]", - "principalId": "[if(parameters('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2018-11-30').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2018-11-30').principalId)]", - "principalType": "ServicePrincipal", - "delegatedManagedIdentityResourceId": "[if(parameters('isCrossTenant'), variables('delegatedManagedIdentityResourceId'), null())]" + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" + "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" ] }, { - "copy": { - "name": "createImportCerts", - "count": "[length(parameters('certificateNames'))]" - }, - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2023-08-01", - "name": "[format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} - } - }, - "kind": "AzureCLI", - "properties": { - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "azCliVersion": "2.63.0", - "timeout": "PT30M", - "retentionInterval": "PT1H", - "environmentVariables": [ - { - "name": "akvName", - "value": "[parameters('kvName')]" - }, - { - "name": "certName", - "value": "[parameters('certificateNames')[copyIndex()]]" - }, - { - "name": "certCommonName", - "value": "[parameters('certificateCommonNames')[copyIndex()]]" - }, - { - "name": "initialDelay", - "value": "[parameters('initialScriptDelay')]" - }, - { - "name": "issuerName", - "value": "[parameters('issuerName')]" - }, - { - "name": "issuerProvider", - "value": "[parameters('issuerProvider')]" - }, - { - "name": "disabled", - "value": "[toLower(string(parameters('disabled')))]" - }, - { - "name": "retryMax", - "value": "10" - }, - { - "name": "retrySleep", - "value": "5s" - }, - { - "name": "accountId", - "value": "[parameters('accountId')]" - }, - { - "name": "issuerPassword", - "secureValue": "[parameters('issuerPassword')]" - }, - { - "name": "organizationId", - "value": "[parameters('organizationId')]" - }, - { - "name": "reuseKey", - "value": "[toLower(string(parameters('reuseKey')))]" - }, - { - "name": "validity", - "value": "[string(parameters('validity'))]" - } - ], - "scriptContent": "[variables('$fxv#0')]", - "cleanupPreference": "[parameters('cleanupPreference')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", - "[extensionResourceId(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.KeyVault/vaults', parameters('kvName')), parameters('rbacRolesNeededOnKV'), parameters('managedIdentityName'), string(parameters('useExistingManagedIdentity'))))]" - ] - } - ], - "outputs": { - "certificateNames": { - "type": "array", - "metadata": { - "description": "Certificate names" - }, - "copy": { - "count": "[length(parameters('certificateNames'))]", - "input": "[createArray(reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))), '2023-08-01').outputs.name)]" - } - }, - "certificateSecretIds": { - "type": "array", - "metadata": { - "description": "KeyVault secret ids to the created version" - }, - "copy": { - "count": "[length(parameters('certificateNames'))]", - "input": "[createArray(reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))), '2023-08-01').outputs.certSecretId.versioned)]" - } - }, - "certificateSecretIdUnversioneds": { - "type": "array", - "metadata": { - "description": "KeyVault secret ids which uses the unversioned uri" - }, - "copy": { - "count": "[length(parameters('certificateNames'))]", - "input": "[createArray(reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))), '2023-08-01').outputs.certSecretId.unversioned)]" - } - }, - "certificateThumbpints": { - "type": "array", - "metadata": { - "description": "Certificate Thumbprints" - }, - "copy": { - "count": "[length(parameters('certificateNames'))]", - "input": "[createArray(reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))), '2023-08-01').outputs.thumbprint)]" - } - }, - "certificateThumbprintHexs": { - "type": "array", - "metadata": { - "description": "Certificate Thumbprints (in hex)" - }, - "copy": { - "count": "[length(parameters('certificateNames'))]", - "input": "[createArray(reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}', parameters('kvName'), replace(replace(parameters('certificateNames')[copyIndex()], ':', ''), '/', '-'))), '2023-08-01').outputs.thumbprintHex)]" - } - } - } - } - }, - "dependsOn": [ - "keyvault" - ] - }, - "vaultEndpoint": { - "condition": "[parameters('enablePrivateLink')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-keyvault-pep', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "resourceName": { - "value": "[reference('keyvault').outputs.name.value]" - }, - "subnetResourceId": { - "value": "[parameters('subnetId')]" - }, - "groupIds": { - "value": [ - "vault" - ] - }, - "privateDnsZoneGroup": { - "value": { - "privateDNSResourceIds": [ - "[resourceId('Microsoft.Network/privateDnsZones', 'privatelink.vaultcore.azure.net')]" - ] - } - }, - "serviceResourceId": { - "value": "[reference('keyvault').outputs.resourceId.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3640359773342242706" - } - }, - "parameters": { - "resourceName": { - "type": "string", - "metadata": { - "description": "Required. Name of the private endpoint resource to create." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "serviceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource that needs to be connected to the network." - } - }, - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." - } - }, - "applicationSecurityGroups": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "ipConfigurations": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all Resources." - } - }, - "crossTenant": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." - } - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Tags." - } - }, - "lock": { - "type": "string", - "defaultValue": "NotSpecified", - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ], - "metadata": { - "description": "Optional. Specify the type of lock." - } - }, - "customDnsConfigs": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "manualPrivateLinkServiceConnections": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Manual PrivateLink Service Connections." - } - } - }, - "variables": { - "name": "[format('pep-{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]" - }, - "resources": [ - { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2022-05-01", - "name": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "privateLinkServiceConnections": [ - { - "name": "[parameters('resourceName')]", - "properties": { - "privateLinkServiceId": "[parameters('serviceResourceId')]", - "groupIds": "[parameters('groupIds')]" - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - } - }, - { - "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2017-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", - "name": "[format('{0}-{1}-lock', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')), parameters('lock'))]", - "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" - ] - }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}', deployment().name, if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}', deployment().name, if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -12706,6 +12076,260 @@ "keyvault" ] }, + "gitOpsUpload": { + "copy": { + "name": "gitOpsUpload", + "count": "[length(variables('directoryUploads'))]", + "mode": "serial", + "batchSize": 1 + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-storage-{1}-upload', parameters('bladeConfig').sectionName, variables('directoryUploads')[copyIndex()].directory)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[reference('configStorage').outputs.name.value]" + }, + "location": { + "value": "[parameters('location')]" + }, + "useExistingManagedIdentity": { + "value": true + }, + "managedIdentityName": { + "value": "[parameters('userAssignedIdentityName')]" + }, + "existingManagedIdentitySubId": { + "value": "[subscription().subscriptionId]" + }, + "existingManagedIdentityResourceGroupName": { + "value": "[resourceGroup().name]" + }, + "directoryName": { + "value": "[variables('directoryUploads')[copyIndex()].directory]" + }, + "rbacRoleNeeded": { + "value": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "10894476303293941357" + }, + "name": "Blob Upload", + "description": "This module uploads a file to a blob storage account", + "owner": "daniel-scholl" + }, + "parameters": { + "storageAccountName": { + "type": "string", + "defaultValue": "[uniqueString(resourceGroup().id, deployment().name, 'blob')]", + "metadata": { + "description": "Desired name of the storage account" + } + }, + "containerName": { + "type": "string", + "defaultValue": "gitops", + "metadata": { + "description": "Name of the container" + } + }, + "filename": { + "type": "string", + "defaultValue": "main.zip", + "metadata": { + "description": "Name of the file as it is stored in the share" + } + }, + "directoryName": { + "type": "string", + "metadata": { + "description": "Name of the directory to upload" + } + }, + "softwareSource": { + "type": "string", + "defaultValue": "https://github.com/azure/osdu-developer", + "metadata": { + "description": "The source of the software to upload" + } + }, + "fileurl": { + "type": "string", + "defaultValue": "/archive/refs/heads/main.zip", + "metadata": { + "description": "Name of the file as it is stored in the share" + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location of the Storage Account and where to deploy the module resources to" + } + }, + "forceUpdateTag": { + "type": "string", + "defaultValue": "[utcNow()]", + "metadata": { + "description": "How the deployment script should be forced to execute" + } + }, + "rbacRoleNeeded": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Azure RoleId that are required for the DeploymentScript resource to upload blobs" + } + }, + "useExistingManagedIdentity": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Does the Managed Identity already exists, or should be created" + } + }, + "managedIdentityName": { + "type": "string", + "defaultValue": "[format('id-storage-share-{0}', parameters('location'))]", + "metadata": { + "description": "Name of the Managed Identity resource" + } + }, + "existingManagedIdentitySubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", + "metadata": { + "description": "For an existing Managed Identity, the Subscription Id it is located in" + } + }, + "existingManagedIdentityResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", + "metadata": { + "description": "For an existing Managed Identity, the Resource Group it is located in" + } + }, + "initialScriptDelay": { + "type": "string", + "defaultValue": "30s", + "metadata": { + "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" + } + }, + "cleanupPreference": { + "type": "string", + "defaultValue": "OnSuccess", + "allowedValues": [ + "OnSuccess", + "OnExpiration", + "Always" + ], + "metadata": { + "description": "When the script resource is cleaned up" + } + } + }, + "variables": { + "$fxv#0": "#!/bin/bash\nset -e\n\necho \"Waiting on Identity RBAC replication (${initialDelay})\"\nsleep ${initialDelay}\n\n# Installing required packages\napk add --no-cache curl zip unzip\n\n# Download the file using curl\necho \"Downloading file from ${URL}\"\ncurl -L -o repo.zip \"${URL}\"\n\n# Check if the download was successful\nif [ $? -ne 0 ]; then\n echo \"Failed to download the file from ${URL}\"\n exit 1\nfi\n\n# Create a directory for extracted files\nmkdir -p extracted_files\n\n# Unzip the file\necho \"Extracting contents...\"\nunzip -q repo.zip -d extracted_files\n\n# Find and replace 'kind: GitRepository' with 'kind: Bucket' in all files\nfind extracted_files -type f -path \"*/${UPLOAD_DIR}/*\" -exec sed -i '\n /sourceRef:/{\n N;N;N\n s/sourceRef:\\n[[:space:]]*kind: GitRepository\\n[[:space:]]*name: flux-system\\n[[:space:]]*namespace: flux-system/sourceRef:\\n kind: Bucket\\n name: flux-system\\n namespace: flux-system/g\n }' {} +\n\n# Find the software directory\nsoftware_dir=$(find extracted_files -type d -name \"${UPLOAD_DIR}\" -exec dirname {} \\;)\n\nif [ -z \"$software_dir\" ]; then\n echo \"Error: '${UPLOAD_DIR}' directory not found in the extracted contents.\"\n exit 1\nfi\n\n# Upload the contents of the software directory\necho \"Uploading files from ${software_dir} to blob container ${CONTAINER}\"\naz storage blob upload-batch --destination ${CONTAINER} --source \"${software_dir}\" --pattern \"${UPLOAD_DIR}/**\" --overwrite true --auth-mode login\necho \"Files from software directory uploaded to blob container ${CONTAINER}.\"\n\n# Clean up\nrm -rf extracted_files repo.zip\n" + }, + "resources": [ + { + "condition": "[not(parameters('useExistingManagedIdentity'))]", + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-07-31-preview", + "name": "[parameters('managedIdentityName')]", + "location": "[parameters('location')]" + }, + { + "condition": "[not(empty(parameters('rbacRoleNeeded')))]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRoleNeeded'))]", + "principalId": "[if(parameters('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-07-31-preview').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-07-31-preview').principalId)]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" + ] + }, + { + "type": "Microsoft.Resources/deploymentScripts", + "apiVersion": "2023-08-01", + "name": "[format('script-{0}-{1}', parameters('storageAccountName'), replace(replace(parameters('filename'), ':', ''), '/', '-'))]", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} + } + }, + "kind": "AzureCLI", + "properties": { + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "azCliVersion": "2.63.0", + "timeout": "PT30M", + "retentionInterval": "PT1H", + "environmentVariables": [ + { + "name": "AZURE_STORAGE_ACCOUNT", + "value": "[parameters('storageAccountName')]" + }, + { + "name": "AZURE_STORAGE_KEY", + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2023-05-01').keys[0].value]" + }, + { + "name": "FILE", + "value": "[parameters('filename')]" + }, + { + "name": "URL", + "value": "[format('{0}{1}', parameters('softwareSource'), parameters('fileurl'))]" + }, + { + "name": "CONTAINER", + "value": "[parameters('containerName')]" + }, + { + "name": "UPLOAD_DIR", + "value": "[string(parameters('directoryName'))]" + }, + { + "name": "initialDelay", + "value": "[parameters('initialScriptDelay')]" + } + ], + "scriptContent": "[variables('$fxv#0')]", + "cleanupPreference": "[parameters('cleanupPreference')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", + "[extensionResourceId(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))))]" + ] + } + ] + } + }, + "dependsOn": [ + "configStorage", + "userAssignedIdentity" + ] + }, "storageEndpoint": { "condition": "[parameters('enablePrivateLink')]", "type": "Microsoft.Resources/deployments", @@ -17735,7 +17359,7 @@ { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "manage-blade", + "name": "partition-blade", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -17744,8 +17368,8 @@ "parameters": { "bladeConfig": { "value": { - "sectionName": "manageblade", - "displayName": "Manage Resources" + "sectionName": "partitionblade", + "displayName": "Partition Resources" } }, "tags": { @@ -17753,43 +17377,33 @@ "id": "[variables('rg_unique_id')]" } }, - "manageLayerConfig": { - "value": { - "machine": { - "vmSize": "Standard_DS3_v2", - "imagePublisher": "Canonical", - "imageOffer": "UbuntuServer", - "imageSku": "18.04-LTS", - "authenticationType": "password" - }, - "bastion": { - "skuName": "Basic" - } - } - }, "location": { "value": "[parameters('location')]" }, - "enableTelemetry": { - "value": "[variables('enableTelemetry')]" - }, - "workspaceName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.name.value]" + "workspaceResourceId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.resourceId.value]" }, "kvName": { "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultName.value]" }, - "enableBastion": { - "value": "[parameters('enableManage')]" + "subnetId": "[if(variables('enableVnetInjection'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value), createObject('value', ''))]", + "enableBlobPublicAccess": { + "value": "[parameters('enableBlobPublicAccess')]" + }, + "enablePrivateLink": { + "value": "[variables('enablePrivateLink')]" + }, + "storageDNSZoneId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.storageDNSZoneId.value]" }, - "vmAdminUsername": { - "value": "[parameters('vmAdminUsername')]" + "cosmosDNSZoneId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.cosmosDNSZoneId.value]" }, - "vnetId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.vnetId.value]" + "partitions": { + "value": "[variables('configuration').partitions]" }, - "vmSubnetId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.vmSubnetId.value]" + "managedIdentityName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" } }, "template": { @@ -17800,7 +17414,7 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "3095133866282096959" + "templateHash": "4785118936734261568" } }, "definitions": { @@ -17820,76 +17434,6 @@ } } } - }, - "manageSettings": { - "type": "object", - "properties": { - "machine": { - "$ref": "#/definitions/machineSettings", - "metadata": { - "description": "The settings for the virtual machine" - } - }, - "bastion": { - "$ref": "#/definitions/bastionSettings", - "metadata": { - "description": "The settings for the bastion" - } - } - } - }, - "machineSettings": { - "type": "object", - "properties": { - "vmSize": { - "type": "string", - "metadata": { - "description": "The size of the virtual machine" - } - }, - "imagePublisher": { - "type": "string", - "metadata": { - "description": "The publisher of the image" - } - }, - "imageOffer": { - "type": "string", - "metadata": { - "description": "The offer of the image" - } - }, - "imageSku": { - "type": "string", - "metadata": { - "description": "The SKU of the image" - } - }, - "authenticationType": { - "type": "string", - "metadata": { - "description": "The authentication type of the virtual machine" - } - } - } - }, - "bastionSkuType": { - "type": "string", - "allowedValues": [ - "Basic", - "Standard" - ] - }, - "bastionSettings": { - "type": "object", - "properties": { - "skuName": { - "$ref": "#/definitions/bastionSkuType", - "metadata": { - "description": "The name of the SKU" - } - } - } } }, "parameters": { @@ -17912,30 +17456,39 @@ "description": "The tags to apply to the resources" } }, - "enableTelemetry": { + "enableBlobPublicAccess": { "type": "bool", - "defaultValue": false, "metadata": { - "description": "Feature Flag to Enable Telemetry" + "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." + } + }, + "enablePrivateLink": { + "type": "bool", + "metadata": { + "description": "Feature Flag to Enable Private Link" } }, - "vmAdminUsername": { + "workspaceResourceId": { "type": "string", "metadata": { - "description": "Specifies the name of the administrator account of the virtual machine." + "description": "The workspace resource Id for diagnostics" } }, - "vmAdminPasswordOrKey": { - "type": "securestring", - "defaultValue": "", + "subnetId": { + "type": "string", "metadata": { - "description": "Specifies the SSH Key or password for the virtual machine. SSH key is recommended." + "description": "The subnet id for Private Endpoints" } }, - "enableBastion": { - "type": "bool", + "cmekConfiguration": { + "type": "object", + "defaultValue": { + "kvUrl": "", + "keyName": "", + "identityId": "" + }, "metadata": { - "description": "Feature Flag to Enable Bastion" + "description": "Optional. Customer Managed Encryption Key." } }, "kvName": { @@ -17944,44 +17497,449 @@ "description": "The name of the Key Vault where the secret exists" } }, - "vnetId": { + "storageDNSZoneId": { "type": "string", "metadata": { - "description": "The Id of the virtual network" + "description": "Storage DNS Zone Id" } }, - "vmSubnetId": { + "cosmosDNSZoneId": { "type": "string", "metadata": { - "description": "The Id of the subnet for the virtual machine" + "description": "Cosmos DNS Zone Id" } }, - "workspaceName": { - "type": "string", + "partitions": { + "type": "array", + "defaultValue": [ + { + "name": "opendes" + } + ], "metadata": { - "description": "The workspace name for diagnostics" + "description": "List of Data Partitions" } }, - "manageLayerConfig": { - "$ref": "#/definitions/manageSettings", + "managedIdentityName": { + "type": "string", "metadata": { - "description": "The configuration for the manage section." + "description": "The managed identity name for deployment scripts" } } }, - "resources": { - "existingVault": { - "condition": "[parameters('enableBastion')]", - "existing": true, - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2023-07-01", - "name": "[parameters('kvName')]" + "variables": { + "partitionLayerConfig": { + "secrets": { + "storageAccountName": "storage", + "storageAccountKey": "storage-key", + "storageAccountBlob": "storage-account-blob-endpoint", + "cosmosConnectionString": "cosmos-connection", + "cosmosEndpoint": "cosmos-endpoint", + "cosmosPrimaryKey": "cosmos-primary-key" + }, + "storage": { + "sku": "Standard_LRS", + "containers": [ + "legal-service-azure-configuration", + "osdu-wks-mappings", + "wdms-osdu", + "file-staging-area", + "file-persistent-area" + ] + }, + "systemdb": { + "name": "osdu-system-db", + "containers": [ + { + "name": "Authority", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "EntityType", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "SchemaInfo", + "kind": "Hash", + "paths": [ + "/partitionId" + ] + }, + { + "name": "Source", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "WorkflowV2", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + } + ] + }, + "database": { + "name": "osdu-db", + "throughput": 4000, + "backup": "Continuous", + "containers": [ + { + "name": "Authority", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "EntityType", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "FileLocationEntity", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "IngestionStrategy", + "kind": "Hash", + "paths": [ + "/workflowType" + ] + }, + { + "name": "LegalTag", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "MappingInfo", + "kind": "Hash", + "paths": [ + "/sourceSchemaKind" + ] + }, + { + "name": "RegisterAction", + "kind": "Hash", + "paths": [ + "/dataPartitionId" + ] + }, + { + "name": "RegisterDdms", + "kind": "Hash", + "paths": [ + "/dataPartitionId" + ] + }, + { + "name": "RegisterSubscription", + "kind": "Hash", + "paths": [ + "/dataPartitionId" + ] + }, + { + "name": "RelationshipStatus", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "ReplayStatus", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "SchemaInfo", + "kind": "Hash", + "paths": [ + "/partitionId" + ] + }, + { + "name": "Source", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "StorageRecord", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "StorageSchema", + "kind": "Hash", + "paths": [ + "/kind" + ] + }, + { + "name": "TenantInfo", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "UserInfo", + "kind": "Hash", + "paths": [ + "/id" + ] + }, + { + "name": "Workflow", + "kind": "Hash", + "paths": [ + "/workflowId" + ] + }, + { + "name": "WorkflowCustomOperatorInfo", + "kind": "Hash", + "paths": [ + "/operatorId" + ] + }, + { + "name": "WorkflowCustomOperatorV2", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + }, + { + "name": "WorkflowRun", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + }, + { + "name": "WorkflowRunV2", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + }, + { + "name": "WorkflowRunStatus", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + }, + { + "name": "WorkflowV2", + "kind": "Hash", + "paths": [ + "/partitionKey" + ] + } + ] + }, + "servicebus": { + "sku": "Standard", + "topics": [ + { + "name": "indexing-progress", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "indexing-progresssubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "legaltags", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "legaltagssubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "recordstopic", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "recordstopicsubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + }, + { + "name": "wkssubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "recordstopicdownstream", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "downstreamsub", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "recordstopiceg", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "eg_sb_wkssubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "schemachangedtopic", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "schemachangedtopicsubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "schemachangedtopiceg", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "eg_sb_schemasubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "legaltagschangedtopiceg", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "eg_sb_legaltagssubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "statuschangedtopic", + "maxSizeInMegabytes": 5120, + "subscriptions": [ + { + "name": "statuschangedtopicsubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "statuschangedtopiceg", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "eg_sb_statussubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "recordstopic-v2", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "recordstopic-v2-subscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + }, + { + "name": "reindextopic", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "reindextopicsubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M", + "enableDeadLetteringOnMessageExpiration": false + } + ] + }, + { + "name": "entitlements-changed", + "maxSizeInMegabytes": 1024, + "subscriptions": [] + }, + { + "name": "replaytopic", + "maxSizeInMegabytes": 1024, + "subscriptions": [ + { + "name": "replaytopicsubscription", + "maxDeliveryCount": 5, + "lockDuration": "PT5M" + } + ] + } + ] + } + }, + "systemDatabase": { + "name": "[variables('partitionLayerConfig').systemdb.name]", + "containers": "[variables('partitionLayerConfig').systemdb.containers]" }, - "bastionHost": { - "condition": "[parameters('enableBastion')]", + "partitionDatabase": { + "name": "[variables('partitionLayerConfig').database.name]", + "containers": "[variables('partitionLayerConfig').database.containers]" + } + }, + "resources": { + "partitionStorage": { + "copy": { + "name": "partitionStorage", + "count": "[length(parameters('partitions'))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-bastion', parameters('bladeConfig').sectionName)]", + "name": "[format('{0}-azure-storage-{1}', parameters('bladeConfig').sectionName, copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -17989,2225 +17947,1750 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[format('bh-{0}{1}', replace(parameters('bladeConfig').sectionName, '-', ''), uniqueString(resourceGroup().id, parameters('bladeConfig').sectionName))]" - }, - "skuName": { - "value": "[parameters('manageLayerConfig').bastion.skuName]" - }, - "virtualNetworkResourceId": { - "value": "[parameters('vnetId')]" + "value": "[format('{0}{1}', replace(format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6)), '-', ''), uniqueString(resourceGroup().id, format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))))]" }, "location": { "value": "[parameters('location')]" }, - "enableTelemetry": { - "value": "[parameters('enableTelemetry')]" - }, "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" + "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName, 'partition', parameters('partitions')[copyIndex()].name, 'purpose', 'data'))]" + }, + "diagnosticWorkspaceId": { + "value": "[parameters('workspaceResourceId')]" + }, + "diagnosticLogsRetentionInDays": { + "value": 0 + }, + "allowBlobPublicAccess": { + "value": "[parameters('enableBlobPublicAccess')]" + }, + "sku": { + "value": "[variables('partitionLayerConfig').storage.sku]" + }, + "containers": { + "value": "[concat(variables('partitionLayerConfig').storage.containers, createArray(parameters('partitions')[copyIndex()].name))]" + }, + "cmekConfiguration": { + "value": "[parameters('cmekConfiguration')]" + }, + "keyVaultName": { + "value": "[parameters('kvName')]" + }, + "storageAccountSecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountName)]" + }, + "storageAccountKeySecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountKey)]" + }, + "storageAccountBlobEndpointSecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountBlob)]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.26.54.24096", - "templateHash": "13476650126267644156" - }, - "name": "Bastion Hosts", - "description": "This module deploys a Bastion Host.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true - } + "version": "0.30.23.60470", + "templateHash": "11231418961381694034" + } }, "parameters": { "name": { "type": "string", "metadata": { - "description": "Required. Name of the Azure Bastion resource." + "description": "Used to name all resources" } }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Location for all resources." + "description": "Resource Location." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Tags." } }, - "virtualNetworkResourceId": { + "lock": { "type": "string", + "defaultValue": "NotSpecified", + "allowedValues": [ + "CanNotDelete", + "NotSpecified", + "ReadOnly" + ], "metadata": { - "description": "Required. Shared services Virtual Network resource Id." + "description": "Optional. Specify the type of lock." } }, - "bastionSubnetPublicIpResourceId": { + "sku": { "type": "string", - "defaultValue": "", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Premium_LRS", + "Standard_GRS" + ], "metadata": { - "description": "Optional. The Public IP resource ID to associate to the azureBastionSubnet. If empty, then the Public IP that is created as part of this module will be applied to the azureBastionSubnet." + "description": "Specifies the storage account sku type." } }, - "publicIPAddressObject": { - "type": "object", - "defaultValue": { - "name": "[format('{0}-pip', parameters('name'))]" - }, + "accessTier": { + "type": "string", + "defaultValue": "Hot", + "allowedValues": [ + "Cool", + "Hot" + ], "metadata": { - "description": "Optional. Specifies the properties of the Public IP to create and be used by Azure Bastion, if no existing public IP was provided." + "description": "Specifies the storage account access tier." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "containers": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Optional. Array of Storage Containers to be created." } }, - "lock": { - "$ref": "#/definitions/lockType", + "tables": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Optional. Array of Storage Tables to be created." } }, - "skuName": { + "shares": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of Storage Shares to be created." + } + }, + "shareQuota": { + "type": "int", + "defaultValue": 5120, + "metadata": { + "description": "Optional. The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5120 (5TB). For Large File Shares, the maximum size is 102400 (100TB)." + } + }, + "enabledProtocols": { "type": "string", - "defaultValue": "Basic", + "defaultValue": "SMB", "allowedValues": [ - "Basic", - "Standard" + "NFS", + "SMB" + ], + "metadata": { + "description": "Optional. The authentication protocol that is used for the file share. Can only be specified when creating a share." + } + }, + "rootSquash": { + "type": "string", + "defaultValue": "NoRootSquash", + "allowedValues": [ + "AllSquash", + "NoRootSquash", + "RootSquash" ], "metadata": { - "description": "Optional. The SKU of this Bastion Host." + "description": "Optional. Permissions for NFS file shares are enforced by the client OS rather than the Azure Files service. Toggling the root squash behavior reduces the rights of the root user for NFS shares." } }, - "disableCopyPaste": { + "crossTenant": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable Copy Paste." + "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." } }, - "enableFileCopy": { - "type": "bool", - "defaultValue": true, + "roleAssignments": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Optional. Choose to disable or enable File Copy." + "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" } }, - "enableIpConnect": { - "type": "bool", - "defaultValue": false, + "diagnosticWorkspaceId": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Optional. Choose to disable or enable IP Connect." + "description": "Optional. Resource ID of the diagnostic log analytics workspace." } }, - "enableKerberos": { - "type": "bool", - "defaultValue": false, + "diagnosticStorageAccountId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account." + } + }, + "diagnosticEventHubAuthorizationRuleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "diagnosticEventHubName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category." + } + }, + "diagnosticLogsRetentionInDays": { + "type": "int", + "defaultValue": 365, + "minValue": 0, + "maxValue": 365, + "metadata": { + "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." + } + }, + "logsToEnable": { + "type": "array", + "defaultValue": [ + "StorageRead", + "StorageWrite", + "StorageDelete" + ], + "allowedValues": [ + "StorageRead", + "StorageWrite", + "StorageDelete" + ], + "metadata": { + "description": "Optional. The name of logs that will be streamed." + } + }, + "metricsToEnable": { + "type": "array", + "defaultValue": [ + "AllMetrics" + ], + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "Optional. The name of metrics that will be streamed." + } + }, + "cmekConfiguration": { + "type": "object", + "defaultValue": { + "kvUrl": "", + "keyName": "", + "identityId": "" + }, "metadata": { - "description": "Optional. Choose to disable or enable Kerberos authentication." + "description": "Optional. Customer Managed Encryption Key." + } + }, + "deleteRetention": { + "type": "int", + "defaultValue": 0, + "minValue": 0, + "maxValue": 7, + "metadata": { + "description": "Amount of days the soft deleted data is stored and available for recovery. 0 is off." } }, - "enableShareableLink": { + "allowBlobPublicAccess": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Choose to disable or enable Shareable Link." + "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." } }, - "scaleUnits": { - "type": "int", - "defaultValue": 2, + "privateLinkSettings": { + "type": "object", + "defaultValue": { + "subnetId": "1", + "vnetId": "1" + }, "metadata": { - "description": "Optional. The scale units for the Bastion Host resource." + "description": "Settings Required to Enable Private Link" } }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "keyVaultName": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "Optional: Key Vault Name to store secrets into" } }, - "tags": { + "storageAccountSecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account name into vault set the secret name." + } + }, + "storageAccountKeySecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account key into vault set the secret name." + } + }, + "storageAccountTableEndpointSecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account table endpoint into vault set the secret name." + } + }, + "storageAccountBlobEndpointSecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account blob endpoint into vault set the secret name." + } + }, + "storageAccountConnectionString": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account connectionstring into vault set the secret name." + } + }, + "basetime": { + "type": "string", + "defaultValue": "[utcNow('u')]", + "metadata": { + "description": "Optional: Current Date Time" + } + }, + "sasProperties": { "type": "object", - "nullable": true, + "defaultValue": { + "signedServices": "b", + "signedPermission": "rl", + "signedExpiry": "[dateTimeAdd(parameters('basetime'), 'P1Y')]", + "signedResourceTypes": "sco", + "signedProtocol": "https" + }, "metadata": { - "description": "Optional. Tags of the resource." + "description": "Optional: Default SAS TOken Properties to download Blob." } }, - "enableTelemetry": { + "saveToken": { "type": "bool", - "defaultValue": true, + "defaultValue": false, "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "description": "Optional: To save storage account sas token into vault set the properties." + } + }, + "isSystem": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional: Enable as System Storage." } } }, "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "avmTelemetry": { - "condition": "[parameters('enableTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-bastionhost.{0}.{1}', replace('0.2.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [], - "outputs": { - "telemetry": { - "type": "String", - "value": "For more information, see https://aka.ms/avm/TelemetryInfo" - } + "copy": [ + { + "name": "diagnosticsLogs", + "count": "[length(parameters('logsToEnable'))]", + "input": { + "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + }, + { + "name": "diagnosticsMetrics", + "count": "[length(parameters('metricsToEnable'))]", + "input": { + "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", + "timeGrain": null, + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" } } } - }, - "azureBastion": { - "type": "Microsoft.Network/bastionHosts", - "apiVersion": "2022-11-01", - "name": "[parameters('name')]", + ], + "enableCMEK": "[if(and(and(not(empty(parameters('cmekConfiguration').kvUrl)), not(empty(parameters('cmekConfiguration').keyName))), not(empty(parameters('cmekConfiguration').identityId))), true(), false())]", + "enablePrivateLink": "[and(not(equals(parameters('privateLinkSettings').vnetId, '1')), not(equals(parameters('privateLinkSettings').subnetId, '1')))]", + "privateEndpointName": "[format('{0}-PrivateEndpoint', parameters('name'))]", + "publicDNSZoneForwarder": "[format('blob.{0}', environment().suffixes.storage)]", + "privateDnsZoneName": "[format('privatelink.{0}', variables('publicDNSZoneForwarder'))]" + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-01-01", + "name": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "sku": { - "name": "[parameters('skuName')]" + "name": "[parameters('sku')]" }, - "properties": "[union(createObject('scaleUnits', if(equals(parameters('skuName'), 'Basic'), 2, parameters('scaleUnits')), 'ipConfigurations', createArray(createObject('name', 'IpConfAzureBastionSubnet', 'properties', union(createObject('subnet', createObject('id', format('{0}/subnets/AzureBastionSubnet', parameters('virtualNetworkResourceId')))), createObject('publicIPAddress', createObject('id', if(not(empty(parameters('bastionSubnetPublicIpResourceId'))), parameters('bastionSubnetPublicIpResourceId'), reference('publicIPAddress').outputs.resourceId.value)))))), 'enableKerberos', parameters('enableKerberos')), if(equals(parameters('skuName'), 'Standard'), createObject('enableTunneling', equals(parameters('skuName'), 'Standard'), 'disableCopyPaste', parameters('disableCopyPaste'), 'enableFileCopy', parameters('enableFileCopy'), 'enableIpConnect', parameters('enableIpConnect'), 'enableShareableLink', parameters('enableShareableLink')), createObject()))]", - "dependsOn": [ - "publicIPAddress" - ] - }, - "azureBastion_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/bastionHosts/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "kind": "StorageV2", + "identity": "[if(variables('enableCMEK'), createObject('type', 'UserAssigned', 'userAssignedIdentities', createObject(format('{0}', parameters('cmekConfiguration').identityId), createObject())), null())]", "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + "accessTier": "[parameters('accessTier')]", + "minimumTlsVersion": "TLS1_2", + "encryption": "[if(variables('enableCMEK'), createObject('identity', createObject('userAssignedIdentity', parameters('cmekConfiguration').identityId), 'services', createObject('blob', createObject('enabled', true()), 'table', createObject('enabled', true()), 'file', createObject('enabled', true())), 'keySource', 'Microsoft.Keyvault', 'keyvaultproperties', createObject('keyname', parameters('cmekConfiguration').keyName, 'keyvaulturi', parameters('cmekConfiguration').kvUrl)), createObject('services', createObject('blob', createObject('enabled', true()), 'table', createObject('enabled', true()), 'file', createObject('enabled', true())), 'keySource', 'Microsoft.Storage'))]", + "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]", + "networkAcls": "[if(variables('enablePrivateLink'), createObject('bypass', 'AzureServices', 'defaultAction', 'Deny'), createObject('bypass', 'AzureServices', 'defaultAction', 'Allow'))]" + } + }, + { + "type": "Microsoft.Storage/storageAccounts/blobServices", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", + "properties": "[if(greater(parameters('deleteRetention'), 0), createObject('changeFeed', createObject('enabled', true()), 'restorePolicy', createObject('enabled', true(), 'days', 7), 'isVersioningEnabled', true(), 'deleteRetentionPolicy', createObject('enabled', true(), 'days', max(parameters('deleteRetention'), 1))), createObject('deleteRetentionPolicy', createObject('enabled', false(), 'allowPermanentDelete', false())))]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts/tableServices", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", + "properties": {}, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts/fileServices", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", + "properties": { + "protocolSettings": {}, + "shareDeleteRetentionPolicy": { + "enabled": true, + "days": 7 + } }, "dependsOn": [ - "azureBastion" + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" ] }, - "azureBastion_diagnosticSettings": { + { "copy": { - "name": "azureBastion_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + "name": "storage_containers", + "count": "[length(parameters('containers'))]" + }, + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('containers')[copyIndex()])]", + "properties": { + "defaultEncryptionScope": "$account-encryption-key", + "denyEncryptionScopeOverride": false, + "publicAccess": "None" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/blobServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" + ] + }, + { + "copy": { + "name": "storage_tables", + "count": "[length(parameters('tables'))]" }, + "type": "Microsoft.Storage/storageAccounts/tableServices/tables", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('tables')[copyIndex()])]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/tableServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" + ] + }, + { + "copy": { + "name": "fileShare", + "count": "[length(parameters('shares'))]" + }, + "type": "Microsoft.Storage/storageAccounts/fileServices/shares", + "apiVersion": "2023-01-01", + "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('shares')[copyIndex()])]", + "properties": { + "shareQuota": "[parameters('shareQuota')]", + "rootSquash": "[if(equals(parameters('enabledProtocols'), 'NFS'), parameters('rootSquash'), null())]", + "enabledProtocols": "[parameters('enabledProtocols')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/fileServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" + ] + }, + { + "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]", + "name": "[format('{0}-{1}-lock', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), parameters('lock'))]", + "properties": { + "level": "[parameters('lock')]", + "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/bastionHosts/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", + "name": "storage-diagnostics", "properties": { - "copy": [ + "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", + "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", + "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", + "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", + "metrics": "[variables('diagnosticsMetrics')]", + "logs": "[variables('diagnosticsLogs')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts/blobServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[variables('privateDnsZoneName')]", + "location": "global", + "properties": {} + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2022-01-01", + "name": "[variables('privateEndpointName')]", + "location": "[parameters('location')]", + "properties": { + "privateLinkServiceConnections": [ { - "name": "logs", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", - "input": { - "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", - "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + "name": "[variables('privateEndpointName')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]", + "groupIds": [ + "blob" + ] } } ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + "subnet": { + "id": "[parameters('privateLinkSettings').subnetId]" + } }, "dependsOn": [ - "azureBastion" + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" ] }, - "azureBastion_roleAssignments": { - "copy": { - "name": "azureBastion_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', variables('privateEndpointName'), 'dnsgroupname')]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "dnsConfig", + "properties": { + "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]" + } + } + ] }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/bastionHosts/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Network/bastionHosts', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]", + "[resourceId('Microsoft.Network/privateEndpoints', variables('privateEndpointName'))]" + ] + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', variables('privateDnsZoneName'), 'link_to_vnet')]", + "location": "global", "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "registrationEnabled": false, + "virtualNetwork": { + "id": "[parameters('privateLinkSettings').vnetId]" + } }, "dependsOn": [ - "azureBastion" + "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]" ] }, - "publicIPAddress": { - "condition": "[empty(parameters('bastionSubnetPublicIpResourceId'))]", + { + "copy": { + "name": "storage_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Bastion-PIP', uniqueString(deployment().name, parameters('location')))]", + "name": "[format('{0}-rbac-{1}', deployment().name, copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "name": { - "value": "[parameters('publicIPAddressObject').name]" - }, - "enableTelemetry": { - "value": "[parameters('enableTelemetry')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "lock": { - "value": "[parameters('lock')]" - }, - "diagnosticSettings": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'diagnosticSettings')]" - }, - "publicIPAddressVersion": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'publicIPAddressVersion')]" - }, - "publicIPAllocationMethod": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'publicIPAllocationMethod')]" - }, - "publicIpPrefixResourceId": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'publicIPPrefixResourceId')]" + "description": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" }, - "roleAssignments": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'roleAssignments')]" + "principals": { + "value": "[parameters('roleAssignments')[copyIndex()].principals]" }, - "skuName": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'skuName')]" + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" }, - "skuTier": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'skuTier')]" + "principalType": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" }, - "tags": { - "value": "[coalesce(tryGet(parameters('publicIPAddressObject'), 'tags'), parameters('tags'))]" + "resourceId": { + "value": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" }, - "zones": { - "value": "[tryGet(parameters('publicIPAddressObject'), 'zones')]" + "crossTenant": { + "value": "[parameters('crossTenant')]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.26.54.24096", - "templateHash": "4718335757080871925" - }, - "name": "Public IP Addresses", - "description": "This module deploys a Public IP Address.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - }, - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "dnsSettingsType": { - "type": "object", - "properties": { - "domainNameLabel": { - "type": "string", - "metadata": { - "description": "Required. The domain name label. The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system." - } - }, - "domainNameLabelScope": { - "type": "string", - "allowedValues": [ - "", - "NoReuse", - "ResourceGroupReuse", - "SubscriptionReuse", - "TenantReuse" - ], - "metadata": { - "description": "Required. The domain name label scope. If a domain name label and a domain name label scope are specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system with a hashed value includes in FQDN." - } - }, - "fqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Fully Qualified Domain Name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone." - } - }, - "reverseFqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." - } - } - } - }, - "ddosSettingsType": { - "type": "object", - "properties": { - "ddosProtectionPlan": { - "type": "object", - "properties": { - "id": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the DDOS protection plan associated with the public IP address." - } - } - }, - "metadata": { - "description": "Required. The DDoS protection plan associated with the public IP address." - } - }, - "protectionMode": { - "type": "string", - "allowedValues": [ - "Enabled" - ], - "metadata": { - "description": "Required. The DDoS protection policy customizations." - } - } - } - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } - }, - "logCategoriesAndGroups": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." - } - }, - "categoryGroup": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "category": { - "type": "string", - "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." - } - }, - "enabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true + "version": "0.30.23.60470", + "templateHash": "18156083951928367" } }, "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the Public IP Address." - } - }, - "publicIpPrefixResourceId": { + "description": { "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the Public IP Prefix object. This is only needed if you want your Public IPs created in a PIP Prefix." - } + "defaultValue": "" }, - "publicIPAllocationMethod": { + "principalType": { "type": "string", - "defaultValue": "Static", - "allowedValues": [ - "Dynamic", - "Static" - ], - "metadata": { - "description": "Optional. The public IP address allocation method." - } + "defaultValue": "" }, - "zones": { - "type": "array", - "items": { - "type": "int" - }, - "defaultValue": [ - 1, - 2, - 3 - ], - "allowedValues": [ - 1, - 2, - 3 - ], - "metadata": { - "description": "Optional. A list of availability zones denoting the IP allocated for the resource needs to come from." - } + "roleDefinitionIdOrName": { + "type": "string" }, - "publicIPAddressVersion": { - "type": "string", - "defaultValue": "IPv4", - "allowedValues": [ - "IPv4", - "IPv6" - ], - "metadata": { - "description": "Optional. IP address version." - } + "resourceId": { + "type": "string" }, - "dnsSettings": { - "$ref": "#/definitions/dnsSettingsType", - "nullable": true, + "crossTenant": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Optional. The DNS settings of the public IP address." + "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." } }, - "lock": { - "$ref": "#/definitions/lockType", + "principals": { + "type": "array", "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Required. The IDs of the principals to assign the role to. A resourceId is required when used in a cross tenant scenario (i.e. crossTenant is true)" } - }, - "skuName": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Basic", - "Standard" - ], + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", + "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", + "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", + "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", + "Backup Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a795c7a0-d4a2-40c1-ae25-d81f01202912')]", + "Classic Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '')]", + "Classic Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '')]", + "Data Box Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'add466c9-e687-43fc-8d98-dfcf8d720be5')]", + "Data Box Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '028f4ed7-e2a9-465e-a8f4-9c0ffdfdc027')]", + "Data Lake Analytics Developer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '47b7735b-770e-4598-a7da-8b91488b4c88')]", + "Elastic SAN Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '80dcbedb-47ef-405d-95bd-188a1b4ac406')]", + "Elastic SAN Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'af6a70f8-3c9f-4105-acf1-d719e9fca4ca')]", + "Elastic SAN Volume Group Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8281131-f312-4f34-8d98-ae12be9f0d23')]", + "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", + "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", + "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", + "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", + "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", + "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", + "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]", + "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]", + "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]", + "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]", + "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", + "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", + "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", + "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", + "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", + "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principals'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principals')[copyIndex()].id]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "delegatedManagedIdentityResourceId": "[if(parameters('crossTenant'), parameters('principals')[copyIndex()].resourceId, null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[parameters('isSystem')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-name', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "system-storage" + }, + "value": { + "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", "metadata": { - "description": "Optional. Name of a public IP address SKU." + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." } }, - "skuTier": { + "name": { "type": "string", - "defaultValue": "Regional", - "allowedValues": [ - "Global", - "Regional" - ], "metadata": { - "description": "Optional. Tier of a public IP address SKU." + "description": "Required. The name of the secret." } }, - "ddosSettings": { - "$ref": "#/definitions/ddosSettingsType", - "nullable": true, + "value": { + "type": "securestring", "metadata": { - "description": "Optional. The DDoS protection plan configuration associated with the public IP address." + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" }, - "location": { + "resourceId": { "type": "string", - "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Location for all resources." - } + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "resourceGroupName": { + "type": "string", "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[parameters('isSystem')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-key', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "system-storage-key" + }, + "value": { + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, + "name": { + "type": "string", "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "description": "Required. The name of the secret." } }, - "idleTimeoutInMinutes": { - "type": "int", - "defaultValue": 4, + "value": { + "type": "securestring", "metadata": { - "description": "Optional. The idle timeout of the public IP address." + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" }, - "tags": { - "type": "object", - "nullable": true, + "resourceId": { + "type": "string", "metadata": { - "description": "Optional. Tags of the resource." - } + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "resourceGroupName": { + "type": "string", "metadata": { - "description": "Optional. The diagnostic settings of the service." - } + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[parameters('isSystem')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-endpoint', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + "name": { + "value": "system-storage-blob-endpoint" + }, + "value": { + "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.blob]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" } }, - "resources": { - "avmTelemetry": { - "condition": "[parameters('enableTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-publicipaddress.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [], - "outputs": { - "telemetry": { - "type": "String", - "value": "For more information, see https://aka.ms/avm/TelemetryInfo" - } - } - } + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." } }, - "publicIpAddress": { - "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2023-09-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('skuName')]", - "tier": "[parameters('skuTier')]" - }, - "zones": "[map(parameters('zones'), lambda('zone', string(lambdaVariables('zone'))))]", - "properties": { - "ddosSettings": "[parameters('ddosSettings')]", - "dnsSettings": "[parameters('dnsSettings')]", - "publicIPAddressVersion": "[parameters('publicIPAddressVersion')]", - "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", - "publicIPPrefix": "[if(not(empty(parameters('publicIpPrefixResourceId'))), createObject('id', parameters('publicIpPrefixResourceId')), null())]", - "idleTimeoutInMinutes": "[parameters('idleTimeoutInMinutes')]", - "ipTags": null + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." } }, - "publicIpAddress_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." }, - "dependsOn": [ - "publicIpAddress" - ] + "value": "[parameters('name')]" }, - "publicIpAddress_roleAssignments": { - "copy": { - "name": "publicIpAddress_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Network/publicIPAddresses', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." }, - "dependsOn": [ - "publicIpAddress" - ] + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" }, - "publicIpAddress_diagnosticSettings": { - "copy": { - "name": "publicIpAddress_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" - }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", - "properties": { - "copy": [ - { - "name": "metrics", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", - "input": { - "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", - "timeGrain": null - } - }, - { - "name": "logs", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", - "input": { - "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", - "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" - } - } - ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" - }, - "dependsOn": [ - "publicIpAddress" - ] - } - }, - "outputs": { "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group the public IP address was deployed into." + "description": "The name of the resource group the secret was created in." }, "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[parameters('isSystem')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-connectionstring', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "system-storage-connection" + }, + "value": { + "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value, environment().suffixes.storage)]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } }, "name": { "type": "string", "metadata": { - "description": "The name of the public IP address." - }, - "value": "[parameters('name')]" + "description": "Required. The name of the secret." + } }, - "resourceId": { + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { "type": "string", "metadata": { - "description": "The resource ID of the public IP address." + "description": "The name of the secret." }, - "value": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('name'))]" + "value": "[parameters('name')]" }, - "ipAddress": { + "resourceId": { "type": "string", "metadata": { - "description": "The public IP address of the public IP address resource." + "description": "The resource ID of the secret." }, - "value": "[coalesce(tryGet(reference('publicIpAddress'), 'ipAddress'), '')]" + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" }, - "location": { + "resourceGroupName": { "type": "string", "metadata": { - "description": "The location the resource was deployed into." + "description": "The name of the resource group the secret was created in." }, - "value": "[reference('publicIpAddress', '2023-09-01', 'full').location]" + "value": "[resourceGroup().name]" } } } - } - } - }, - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the Azure Bastion was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name the Azure Bastion." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID the Azure Bastion." - }, - "value": "[resourceId('Microsoft.Network/bastionHosts', parameters('name'))]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." }, - "value": "[reference('azureBastion', '2022-11-01', 'full').location]" + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] }, - "ipConfAzureBastionSubnet": { - "type": "object", - "metadata": { - "description": "The Public IPconfiguration object for the AzureBastionSubnet." - }, - "value": "[reference('azureBastion').ipConfigurations[0]]" - } - } - } - } - }, - "virtualMachine": { - "condition": "[parameters('enableBastion')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-machine', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "vmName": { - "value": "[format('vm-{0}{1}', replace(parameters('bladeConfig').sectionName, '-', ''), uniqueString(resourceGroup().id, parameters('bladeConfig').sectionName))]" - }, - "vmSize": { - "value": "[parameters('manageLayerConfig').machine.vmSize]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" - }, - "vmSubnetId": { - "value": "[parameters('vmSubnetId')]" - }, - "vmAdminUsername": { - "value": "[parameters('vmAdminUsername')]" - }, - "vmAdminPasswordOrKey": "[if(empty(parameters('vmAdminPasswordOrKey')), createObject('reference', createObject('keyVault', createObject('id', resourceId('Microsoft.KeyVault/vaults', parameters('kvName'))), 'secretName', 'PrivateLinkSSHKey-public')), createObject('value', parameters('vmAdminPasswordOrKey')))]", - "workspaceName": { - "value": "[parameters('workspaceName')]" - }, - "authenticationType": "[if(empty(parameters('vmAdminPasswordOrKey')), createObject('value', 'sshPublicKey'), createObject('value', 'password'))]" - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7840169146772349174" - } - }, - "parameters": { - "vmName": { - "type": "string", - "defaultValue": "simpleVM", - "metadata": { - "description": "Specifies the name of the virtual machine." - } - }, - "vmSize": { - "type": "string", - "defaultValue": "Standard_D2s_v3", - "metadata": { - "description": "Specifies the size of the virtual machine." - } - }, - "vmSubnetId": { - "type": "string", - "metadata": { - "description": "Specifies the resource id of the subnet hosting the virtual machine." - } - }, - "imagePublisher": { - "type": "string", - "defaultValue": "Canonical", - "metadata": { - "description": "Specifies the image publisher of the disk image used to create the virtual machine." - } - }, - "imageOffer": { - "type": "string", - "defaultValue": "0001-com-ubuntu-server-jammy", - "metadata": { - "description": "Specifies the offer of the platform image or marketplace image used to create the virtual machine." - } - }, - "imageSku": { - "type": "string", - "defaultValue": "22_04-lts-gen2", - "metadata": { - "description": "Specifies the Ubuntu version for the VM. This will pick a fully patched image of this given Ubuntu version." - } - }, - "authenticationType": { - "type": "string", - "defaultValue": "password", - "allowedValues": [ - "sshPublicKey", - "password" - ], - "metadata": { - "description": "Specifies the type of authentication when accessing the Virtual Machine. SSH key is recommended." - } - }, - "vmAdminUsername": { - "type": "string", - "metadata": { - "description": "Specifies the name of the administrator account of the virtual machine." - } - }, - "vmAdminPasswordOrKey": { - "type": "securestring", - "metadata": { - "description": "Specifies the SSH Key or password for the virtual machine. SSH key is recommended." - } - }, - "diskStorageAccountType": { - "type": "string", - "defaultValue": "Standard_LRS", - "allowedValues": [ - "Premium_LRS", - "StandardSSD_LRS", - "Standard_LRS", - "UltraSSD_LRS" - ], - "metadata": { - "description": "Specifies the storage account type for OS and data disk." - } - }, - "numDataDisks": { - "type": "int", - "defaultValue": 0, - "minValue": 0, - "maxValue": 64, - "metadata": { - "description": "Specifies the number of data disks of the virtual machine." - } - }, - "osDiskSize": { - "type": "int", - "defaultValue": 30, - "metadata": { - "description": "Specifies the size in GB of the OS disk of the VM." - } - }, - "dataDiskSize": { - "type": "int", - "defaultValue": 50, - "metadata": { - "description": "Specifies the size in GB of the OS disk of the virtual machine." - } - }, - "dataDiskCaching": { - "type": "string", - "defaultValue": "ReadWrite", - "metadata": { - "description": "Specifies the caching requirements for the data disks." - } - }, - "workspaceName": { - "type": "string", - "metadata": { - "description": "Specifies the name of the Log Analytics workspace." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Specifies the location." - } - }, - "tags": { - "type": "object", - "metadata": { - "description": "Specifies the resource tags." - } - } - }, - "variables": { - "vmNicName": "[format('{0}Nic', parameters('vmName'))]", - "linuxConfiguration": { - "disablePasswordAuthentication": true, - "ssh": { - "publicKeys": [ - { - "path": "[format('/home/{0}/.ssh/authorized_keys', parameters('vmAdminUsername'))]", - "keyData": "[parameters('vmAdminPasswordOrKey')]" - } - ] - }, - "provisionVMAgent": true - } - }, - "resources": [ { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2023-06-01", - "name": "[variables('vmNicName')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountSecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-name', deployment().name)]", "properties": { - "ipConfigurations": [ - { - "name": "ipconfig1", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "[parameters('vmSubnetId')]" + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('storageAccountSecretName')]" + }, + "value": { + "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" } } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } } - ] - } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] }, { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2023-09-01", - "name": "[parameters('vmName')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountKeySecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-key', deployment().name)]", "properties": { - "hardwareProfile": { - "vmSize": "[parameters('vmSize')]" + "expressionEvaluationOptions": { + "scope": "inner" }, - "osProfile": { - "computerName": "[parameters('vmName')]", - "adminUsername": "[parameters('vmAdminUsername')]", - "adminPassword": "[parameters('vmAdminPasswordOrKey')]", - "linuxConfiguration": "[if(equals(parameters('authenticationType'), 'password'), null(), variables('linuxConfiguration'))]" + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('storageAccountKeySecretName')]" + }, + "value": { + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value]" + } }, - "storageProfile": { - "copy": [ + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ { - "name": "dataDisks", - "count": "[length(range(0, parameters('numDataDisks')))]", - "input": { - "caching": "[parameters('dataDiskCaching')]", - "diskSizeGB": "[parameters('dataDiskSize')]", - "lun": "[range(0, parameters('numDataDisks'))[copyIndex('dataDisks')]]", - "name": "[format('{0}-DataDisk{1}', parameters('vmName'), range(0, parameters('numDataDisks'))[copyIndex('dataDisks')])]", - "createOption": "Empty", - "managedDisk": { - "storageAccountType": "[parameters('diskStorageAccountType')]" - } + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" } } ], - "imageReference": { - "publisher": "[parameters('imagePublisher')]", - "offer": "[parameters('imageOffer')]", - "sku": "[parameters('imageSku')]", - "version": "latest" - }, - "osDisk": { - "name": "[format('{0}_OSDisk', parameters('vmName'))]", - "caching": "ReadWrite", - "createOption": "FromImage", - "diskSizeGB": "[parameters('osDiskSize')]", - "managedDisk": { - "storageAccountType": "[parameters('diskStorageAccountType')]" + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" } } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountTableEndpointSecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-table-endpoint', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" }, - "networkProfile": { - "networkInterfaces": [ + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('storageAccountTableEndpointSecretName')]" + }, + "value": { + "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.table]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('vmNicName'))]" + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } } - ] + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } } }, "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', variables('vmNicName'))]" + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" ] }, { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2023-09-01", - "name": "[format('{0}/{1}', parameters('vmName'), 'LogAnalytics')]", - "location": "[parameters('location')]", + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountBlobEndpointSecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-blob-endpoint', deployment().name)]", "properties": { - "publisher": "Microsoft.EnterpriseCloud.Monitoring", - "type": "OmsAgentForLinux", - "typeHandlerVersion": "1.17", - "settings": { - "workspaceId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName')), '2022-10-01').customerId]", - "stopOnMultipleConnections": false + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('storageAccountBlobEndpointSecretName')]" + }, + "value": { + "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.blob]" + } }, - "protectedSettings": { - "workspaceKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspaceName')), '2022-10-01').primarySharedKey]" + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } } }, "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('vmName'))]" + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" ] - } - ] - } - }, - "dependsOn": [ - "existingVault" - ] - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'common-blade')]", - "[resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name))]", - "[resourceId('Microsoft.Resources/deployments', 'network-blade')]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "partition-blade", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "bladeConfig": { - "value": { - "sectionName": "partitionblade", - "displayName": "Partition Resources" - } - }, - "tags": { - "value": { - "id": "[variables('rg_unique_id')]" - } - }, - "location": { - "value": "[parameters('location')]" - }, - "workspaceResourceId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.resourceId.value]" - }, - "kvName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultName.value]" - }, - "subnetId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value]" - }, - "enableBlobPublicAccess": { - "value": "[parameters('enableBlobPublicAccess')]" - }, - "enablePrivateLink": { - "value": "[variables('enablePrivateLink')]" - }, - "storageDNSZoneId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.storageDNSZoneId.value]" - }, - "cosmosDNSZoneId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.cosmosDNSZoneId.value]" - }, - "partitionSize": "[if(parameters('enableBurstable'), createObject('value', 'Burstable'), createObject('value', 'Standard'))]", - "partitions": { - "value": "[variables('configuration').partitions]" - }, - "managedIdentityName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4458452595802791688" - } - }, - "definitions": { - "bladeSettings": { - "type": "object", - "properties": { - "sectionName": { - "type": "string", - "metadata": { - "description": "The name of the section name" - } - }, - "displayName": { - "type": "string", - "metadata": { - "description": "The display name of the section" + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountConnectionString'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-connectionstring', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('storageAccountConnectionString')]" + }, + "value": { + "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value, environment().suffixes.storage)]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), parameters('saveToken'))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-sasToken', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[format('{0}-SAS', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + }, + "value": { + "value": "[listAccountSAS(if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), '2022-05-01', parameters('sasProperties')).accountSasToken]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + ] + } + ], + "outputs": { + "id": { + "type": "string", + "metadata": { + "description": "The resource ID." + }, + "value": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the resource." + }, + "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" + } } } } - } - }, - "parameters": { - "bladeConfig": { - "$ref": "#/definitions/bladeSettings", - "metadata": { - "description": "The configuration for the blade section." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "The location of resources to deploy" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "The tags to apply to the resources" - } - }, - "enableBlobPublicAccess": { - "type": "bool", - "metadata": { - "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." - } - }, - "enablePrivateLink": { - "type": "bool", - "metadata": { - "description": "Feature Flag to Enable Private Link" - } - }, - "workspaceResourceId": { - "type": "string", - "metadata": { - "description": "The workspace resource Id for diagnostics" - } - }, - "subnetId": { - "type": "string", - "metadata": { - "description": "The subnet id for Private Endpoints" - } - }, - "cmekConfiguration": { - "type": "object", - "defaultValue": { - "kvUrl": "", - "keyName": "", - "identityId": "" - }, - "metadata": { - "description": "Optional. Customer Managed Encryption Key." - } - }, - "kvName": { - "type": "string", - "metadata": { - "description": "The name of the Key Vault where the secret exists" - } - }, - "storageDNSZoneId": { - "type": "string", - "metadata": { - "description": "Storage DNS Zone Id" - } - }, - "cosmosDNSZoneId": { - "type": "string", - "metadata": { - "description": "Cosmos DNS Zone Id" - } - }, - "partitionSize": { - "type": "string", - "defaultValue": "Burstable", - "allowedValues": [ - "Burstable", - "Standard" - ], - "metadata": { - "description": "The Partition Size" - } - }, - "partitions": { - "type": "array", - "defaultValue": [ - { - "name": "opendes" - } - ], - "metadata": { - "description": "List of Data Partitions" - } }, - "managedIdentityName": { - "type": "string", - "metadata": { - "description": "The managed identity name for deployment scripts" - } - } - }, - "variables": { - "partitionLayerConfig": { - "secrets": { - "storageAccountName": "storage", - "storageAccountKey": "storage-key", - "storageAccountBlob": "storage-account-blob-endpoint", - "cosmosConnectionString": "cosmos-connection", - "cosmosEndpoint": "cosmos-endpoint", - "cosmosPrimaryKey": "cosmos-primary-key" - }, - "storage": { - "sku": "Standard_LRS", - "containers": [ - "legal-service-azure-configuration", - "osdu-wks-mappings", - "wdms-osdu", - "file-staging-area", - "file-persistent-area" - ] + "partitionStorageEndpoint": { + "copy": { + "name": "partitionStorageEndpoint", + "count": "[length(parameters('partitions'))]" }, - "systemdb": { - "name": "osdu-system-db", - "containers": [ - { - "name": "Authority", - "kind": "Hash", - "paths": [ - "/id" - ] + "condition": "[parameters('enablePrivateLink')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-azure-storage-endpoint-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "resourceName": { + "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" }, - { - "name": "EntityType", - "kind": "Hash", - "paths": [ - "/id" - ] + "subnetResourceId": { + "value": "[parameters('subnetId')]" }, - { - "name": "SchemaInfo", - "kind": "Hash", - "paths": [ - "/partitionId" - ] + "serviceResourceId": { + "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.id.value]" }, - { - "name": "Source", - "kind": "Hash", - "paths": [ - "/id" + "groupIds": { + "value": [ + "blob" ] }, - { - "name": "WorkflowV2", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] + "privateDnsZoneGroup": { + "value": { + "privateDNSResourceIds": [ + "[parameters('storageDNSZoneId')]" + ] + } } - ] - }, - "database": { - "name": "osdu-db", - "Burstable": { - "throughput": 2000 }, - "Standard": { - "throughput": 4000 - }, - "backup": "Continuous", - "containers": [ - { - "name": "Authority", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "EntityType", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "FileLocationEntity", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "IngestionStrategy", - "kind": "Hash", - "paths": [ - "/workflowType" - ] - }, - { - "name": "LegalTag", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "MappingInfo", - "kind": "Hash", - "paths": [ - "/sourceSchemaKind" - ] - }, - { - "name": "RegisterAction", - "kind": "Hash", - "paths": [ - "/dataPartitionId" - ] - }, - { - "name": "RegisterDdms", - "kind": "Hash", - "paths": [ - "/dataPartitionId" - ] - }, - { - "name": "RegisterSubscription", - "kind": "Hash", - "paths": [ - "/dataPartitionId" - ] - }, - { - "name": "RelationshipStatus", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "ReplayStatus", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "SchemaInfo", - "kind": "Hash", - "paths": [ - "/partitionId" - ] - }, - { - "name": "Source", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "StorageRecord", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "StorageSchema", - "kind": "Hash", - "paths": [ - "/kind" - ] - }, - { - "name": "TenantInfo", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "UserInfo", - "kind": "Hash", - "paths": [ - "/id" - ] - }, - { - "name": "Workflow", - "kind": "Hash", - "paths": [ - "/workflowId" - ] - }, - { - "name": "WorkflowCustomOperatorInfo", - "kind": "Hash", - "paths": [ - "/operatorId" - ] - }, - { - "name": "WorkflowCustomOperatorV2", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] - }, - { - "name": "WorkflowRun", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] - }, - { - "name": "WorkflowRunV2", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] - }, - { - "name": "WorkflowRunStatus", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] - }, - { - "name": "WorkflowV2", - "kind": "Hash", - "paths": [ - "/partitionKey" - ] - } - ] - }, - "servicebus": { - "sku": "Standard", - "topics": [ - { - "name": "indexing-progress", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "indexing-progresssubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "legaltags", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "legaltagssubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "recordstopic", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "recordstopicsubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - }, - { - "name": "wkssubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "recordstopicdownstream", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "downstreamsub", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "recordstopiceg", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "eg_sb_wkssubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "schemachangedtopic", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "schemachangedtopicsubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "schemachangedtopiceg", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "eg_sb_schemasubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "legaltagschangedtopiceg", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "eg_sb_legaltagssubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "statuschangedtopic", - "maxSizeInMegabytes": 5120, - "subscriptions": [ - { - "name": "statuschangedtopicsubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "statuschangedtopiceg", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "eg_sb_statussubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "recordstopic-v2", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "recordstopic-v2-subscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - }, - { - "name": "reindextopic", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "reindextopicsubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M", - "enableDeadLetteringOnMessageExpiration": false - } - ] - }, - { - "name": "entitlements-changed", - "maxSizeInMegabytes": 1024, - "subscriptions": [] - }, - { - "name": "replaytopic", - "maxSizeInMegabytes": 1024, - "subscriptions": [ - { - "name": "replaytopicsubscription", - "maxDeliveryCount": 5, - "lockDuration": "PT5M" - } - ] - } - ] - } - }, - "systemDatabase": { - "name": "[variables('partitionLayerConfig').systemdb.name]", - "containers": "[variables('partitionLayerConfig').systemdb.containers]" - }, - "partitionDatabase": { - "name": "[variables('partitionLayerConfig').database.name]", - "containers": "[variables('partitionLayerConfig').database.containers]" - } - }, - "resources": { - "partitionStorage": { - "copy": { - "name": "partitionStorage", - "count": "[length(parameters('partitions'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-azure-storage-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('{0}{1}', replace(format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6)), '-', ''), uniqueString(resourceGroup().id, format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName, 'partition', parameters('partitions')[copyIndex()].name, 'purpose', 'data'))]" - }, - "diagnosticWorkspaceId": { - "value": "[parameters('workspaceResourceId')]" - }, - "diagnosticLogsRetentionInDays": { - "value": 0 - }, - "allowBlobPublicAccess": { - "value": "[parameters('enableBlobPublicAccess')]" - }, - "sku": { - "value": "[variables('partitionLayerConfig').storage.sku]" - }, - "containers": { - "value": "[concat(variables('partitionLayerConfig').storage.containers, createArray(parameters('partitions')[copyIndex()].name))]" - }, - "cmekConfiguration": { - "value": "[parameters('cmekConfiguration')]" - }, - "keyVaultName": { - "value": "[parameters('kvName')]" - }, - "storageAccountSecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountName)]" - }, - "storageAccountKeySecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountKey)]" - }, - "storageAccountBlobEndpointSecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.storageAccountBlob)]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11231418961381694034" - } + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "3640359773342242706" + } }, "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Used to name all resources" - } - }, - "location": { + "resourceName": { "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Resource Location." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, "metadata": { - "description": "Tags." + "description": "Required. Name of the private endpoint resource to create." } }, - "lock": { + "subnetResourceId": { "type": "string", - "defaultValue": "NotSpecified", - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ], "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." } }, - "sku": { + "serviceResourceId": { "type": "string", - "defaultValue": "Standard_LRS", - "allowedValues": [ - "Standard_LRS", - "Premium_LRS", - "Standard_GRS" - ], "metadata": { - "description": "Specifies the storage account sku type." + "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "accessTier": { - "type": "string", - "defaultValue": "Hot", - "allowedValues": [ - "Cool", - "Hot" - ], + "groupIds": { + "type": "array", "metadata": { - "description": "Specifies the storage account access tier." + "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "containers": { + "applicationSecurityGroups": { "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. Array of Storage Containers to be created." + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, - "tables": { - "type": "array", - "defaultValue": [], + "customNetworkInterfaceName": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Optional. Array of Storage Tables to be created." + "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, - "shares": { + "ipConfigurations": { "type": "array", "defaultValue": [], "metadata": { - "description": "Optional. Array of Storage Shares to be created." - } - }, - "shareQuota": { - "type": "int", - "defaultValue": 5120, - "metadata": { - "description": "Optional. The maximum size of the share, in gigabytes. Must be greater than 0, and less than or equal to 5120 (5TB). For Large File Shares, the maximum size is 102400 (100TB)." + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." } }, - "enabledProtocols": { - "type": "string", - "defaultValue": "SMB", - "allowedValues": [ - "NFS", - "SMB" - ], + "privateDnsZoneGroup": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Optional. The authentication protocol that is used for the file share. Can only be specified when creating a share." + "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." } }, - "rootSquash": { + "location": { "type": "string", - "defaultValue": "NoRootSquash", - "allowedValues": [ - "AllSquash", - "NoRootSquash", - "RootSquash" - ], + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Permissions for NFS file shares are enforced by the client OS rather than the Azure Files service. Toggling the root squash behavior reduces the rights of the root user for NFS shares." + "description": "Optional. Location for all Resources." } }, "crossTenant": { @@ -20224,424 +19707,191 @@ "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" } }, - "diagnosticWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace." - } - }, - "diagnosticStorageAccountId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account." - } - }, - "diagnosticEventHubAuthorizationRuleId": { - "type": "string", - "defaultValue": "", + "tags": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + "description": "Tags." } }, - "diagnosticEventHubName": { + "lock": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category." - } - }, - "diagnosticLogsRetentionInDays": { - "type": "int", - "defaultValue": 365, - "minValue": 0, - "maxValue": 365, - "metadata": { - "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." - } - }, - "logsToEnable": { - "type": "array", - "defaultValue": [ - "StorageRead", - "StorageWrite", - "StorageDelete" - ], + "defaultValue": "NotSpecified", "allowedValues": [ - "StorageRead", - "StorageWrite", - "StorageDelete" + "CanNotDelete", + "NotSpecified", + "ReadOnly" ], "metadata": { - "description": "Optional. The name of logs that will be streamed." + "description": "Optional. Specify the type of lock." } }, - "metricsToEnable": { + "customDnsConfigs": { "type": "array", - "defaultValue": [ - "AllMetrics" - ], - "allowedValues": [ - "AllMetrics" - ], + "defaultValue": [], "metadata": { - "description": "Optional. The name of metrics that will be streamed." + "description": "Optional. Custom DNS configurations." } }, - "cmekConfiguration": { - "type": "object", - "defaultValue": { - "kvUrl": "", - "keyName": "", - "identityId": "" - }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Optional. Customer Managed Encryption Key." + "description": "Optional. Manual PrivateLink Service Connections." + } + } + }, + "variables": { + "name": "[format('pep-{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]" + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2022-05-01", + "name": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", + "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", + "ipConfigurations": "[parameters('ipConfigurations')]", + "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "customDnsConfigs": "[parameters('customDnsConfigs')]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('resourceName')]", + "properties": { + "privateLinkServiceId": "[parameters('serviceResourceId')]", + "groupIds": "[parameters('groupIds')]" + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } } }, - "deleteRetention": { - "type": "int", - "defaultValue": 0, - "minValue": 0, - "maxValue": 7, - "metadata": { - "description": "Amount of days the soft deleted data is stored and available for recovery. 0 is off." - } - }, - "allowBlobPublicAccess": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates whether public access is enabled for all blobs or containers in the storage account. For security reasons, it is recommended to set it to false." - } - }, - "privateLinkSettings": { - "type": "object", - "defaultValue": { - "subnetId": "1", - "vnetId": "1" - }, - "metadata": { - "description": "Settings Required to Enable Private Link" - } - }, - "keyVaultName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: Key Vault Name to store secrets into" - } - }, - "storageAccountSecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account name into vault set the secret name." - } - }, - "storageAccountKeySecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account key into vault set the secret name." - } - }, - "storageAccountTableEndpointSecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account table endpoint into vault set the secret name." - } - }, - "storageAccountBlobEndpointSecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account blob endpoint into vault set the secret name." - } - }, - "storageAccountConnectionString": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account connectionstring into vault set the secret name." - } - }, - "basetime": { - "type": "string", - "defaultValue": "[utcNow('u')]", - "metadata": { - "description": "Optional: Current Date Time" - } - }, - "sasProperties": { - "type": "object", - "defaultValue": { - "signedServices": "b", - "signedPermission": "rl", - "signedExpiry": "[dateTimeAdd(parameters('basetime'), 'P1Y')]", - "signedResourceTypes": "sco", - "signedProtocol": "https" - }, - "metadata": { - "description": "Optional: Default SAS TOken Properties to download Blob." - } - }, - "saveToken": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional: To save storage account sas token into vault set the properties." - } - }, - "isSystem": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional: Enable as System Storage." - } - } - }, - "variables": { - "copy": [ - { - "name": "diagnosticsLogs", - "count": "[length(parameters('logsToEnable'))]", - "input": { - "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - }, - { - "name": "diagnosticsMetrics", - "count": "[length(parameters('metricsToEnable'))]", - "input": { - "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", - "timeGrain": null, - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" - } - } - } - ], - "enableCMEK": "[if(and(and(not(empty(parameters('cmekConfiguration').kvUrl)), not(empty(parameters('cmekConfiguration').keyName))), not(empty(parameters('cmekConfiguration').identityId))), true(), false())]", - "enablePrivateLink": "[and(not(equals(parameters('privateLinkSettings').vnetId, '1')), not(equals(parameters('privateLinkSettings').subnetId, '1')))]", - "privateEndpointName": "[format('{0}-PrivateEndpoint', parameters('name'))]", - "publicDNSZoneForwarder": "[format('blob.{0}', environment().suffixes.storage)]", - "privateDnsZoneName": "[format('privatelink.{0}', variables('publicDNSZoneForwarder'))]" - }, - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "name": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('sku')]" - }, - "kind": "StorageV2", - "identity": "[if(variables('enableCMEK'), createObject('type', 'UserAssigned', 'userAssignedIdentities', createObject(format('{0}', parameters('cmekConfiguration').identityId), createObject())), null())]", - "properties": { - "accessTier": "[parameters('accessTier')]", - "minimumTlsVersion": "TLS1_2", - "encryption": "[if(variables('enableCMEK'), createObject('identity', createObject('userAssignedIdentity', parameters('cmekConfiguration').identityId), 'services', createObject('blob', createObject('enabled', true()), 'table', createObject('enabled', true()), 'file', createObject('enabled', true())), 'keySource', 'Microsoft.Keyvault', 'keyvaultproperties', createObject('keyname', parameters('cmekConfiguration').keyName, 'keyvaulturi', parameters('cmekConfiguration').kvUrl)), createObject('services', createObject('blob', createObject('enabled', true()), 'table', createObject('enabled', true()), 'file', createObject('enabled', true())), 'keySource', 'Microsoft.Storage'))]", - "allowBlobPublicAccess": "[parameters('allowBlobPublicAccess')]", - "networkAcls": "[if(variables('enablePrivateLink'), createObject('bypass', 'AzureServices', 'defaultAction', 'Deny'), createObject('bypass', 'AzureServices', 'defaultAction', 'Allow'))]" - } - }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", - "properties": "[if(greater(parameters('deleteRetention'), 0), createObject('changeFeed', createObject('enabled', true()), 'restorePolicy', createObject('enabled', true(), 'days', 7), 'isVersioningEnabled', true(), 'deleteRetentionPolicy', createObject('enabled', true(), 'days', max(parameters('deleteRetention'), 1))), createObject('deleteRetentionPolicy', createObject('enabled', false(), 'allowPermanentDelete', false())))]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/tableServices", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", - "properties": {}, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "type": "Microsoft.Storage/storageAccounts/fileServices", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", - "properties": { - "protocolSettings": {}, - "shareDeleteRetentionPolicy": { - "enabled": true, - "days": 7 - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "copy": { - "name": "storage_containers", - "count": "[length(parameters('containers'))]" - }, - "type": "Microsoft.Storage/storageAccounts/blobServices/containers", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('containers')[copyIndex()])]", - "properties": { - "defaultEncryptionScope": "$account-encryption-key", - "denyEncryptionScopeOverride": false, - "publicAccess": "None" - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts/blobServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" - ] - }, - { - "copy": { - "name": "storage_tables", - "count": "[length(parameters('tables'))]" - }, - "type": "Microsoft.Storage/storageAccounts/tableServices/tables", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('tables')[copyIndex()])]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts/tableServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" - ] - }, - { - "copy": { - "name": "fileShare", - "count": "[length(parameters('shares'))]" - }, - "type": "Microsoft.Storage/storageAccounts/fileServices/shares", - "apiVersion": "2023-01-01", - "name": "[format('{0}/{1}/{2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default', parameters('shares')[copyIndex()])]", - "properties": { - "shareQuota": "[parameters('shareQuota')]", - "rootSquash": "[if(equals(parameters('enabledProtocols'), 'NFS'), parameters('rootSquash'), null())]", - "enabledProtocols": "[parameters('enabledProtocols')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts/fileServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]" - ] - }, { "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]", - "name": "[format('{0}-{1}-lock', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), parameters('lock'))]", + "apiVersion": "2017-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", + "name": "[format('{0}-{1}-lock', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')), parameters('lock'))]", "properties": { "level": "[parameters('lock')]", "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", - "name": "storage-diagnostics", - "properties": { - "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", - "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", - "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", - "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", - "metrics": "[variables('diagnosticsMetrics')]", - "logs": "[variables('diagnosticsLogs')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts/blobServices', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), 'default')]", - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" ] }, { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateDnsZones", - "apiVersion": "2020-06-01", - "name": "[variables('privateDnsZoneName')]", - "location": "global", - "properties": {} - }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2022-01-01", - "name": "[variables('privateEndpointName')]", - "location": "[parameters('location')]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}', deployment().name, if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", "properties": { - "privateLinkServiceConnections": [ - { - "name": "[variables('privateEndpointName')]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]", - "groupIds": [ - "blob" - ] - } + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDNSResourceIds": { + "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + }, + "privateEndpointName": { + "value": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]" } - ], - "subnet": { - "id": "[parameters('privateLinkSettings').subnetId]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', variables('privateEndpointName'), 'dnsgroupname')]", - "properties": { - "privateDnsZoneConfigs": [ - { - "name": "dnsConfig", - "properties": { - "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "3963716407284218965" + } + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "resourceName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2022-05-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('resourceName'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('resourceName')]" + }, + "id": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('resourceName'))]" } } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]", - "[resourceId('Microsoft.Network/privateEndpoints', variables('privateEndpointName'))]" - ] - }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", - "apiVersion": "2020-06-01", - "name": "[format('{0}/{1}', variables('privateDnsZoneName'), 'link_to_vnet')]", - "location": "global", - "properties": { - "registrationEnabled": false, - "virtualNetwork": { - "id": "[parameters('privateLinkSettings').vnetId]" } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDnsZoneName'))]" + "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" ] }, { "copy": { - "name": "storage_rbac", + "name": "privateEndpoint_roleAssignments", "count": "[length(parameters('roleAssignments'))]" }, "type": "Microsoft.Resources/deployments", @@ -20659,14 +19909,17 @@ "principals": { "value": "[parameters('roleAssignments')[copyIndex()].principals]" }, + "principalType": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + }, "roleDefinitionIdOrName": { "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" }, - "principalType": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + "condition": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'condition'), '')]" }, "resourceId": { - "value": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "value": "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" }, "crossTenant": { "value": "[parameters('crossTenant')]" @@ -20679,23 +19932,60 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "18156083951928367" + "templateHash": "17487462929719619113" } }, "parameters": { - "description": { + "roleDefinitionIdOrName": { "type": "string", - "defaultValue": "" + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource to apply the role assignment to." + } }, "principalType": { "type": "string", - "defaultValue": "" + "defaultValue": "", + "allowedValues": [ + "ServicePrincipal", + "Group", + "User", + "ForeignGroup", + "Device", + "" + ], + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } }, - "roleDefinitionIdOrName": { - "type": "string" + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The description of the role assignment." + } }, - "resourceId": { - "type": "string" + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition." + } }, "crossTenant": { "type": "bool", @@ -20715,37 +20005,7 @@ "builtInRoleNames": { "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Backup Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a795c7a0-d4a2-40c1-ae25-d81f01202912')]", - "Classic Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '')]", - "Classic Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '')]", - "Data Box Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'add466c9-e687-43fc-8d98-dfcf8d720be5')]", - "Data Box Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '028f4ed7-e2a9-465e-a8f4-9c0ffdfdc027')]", - "Data Lake Analytics Developer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '47b7735b-770e-4598-a7da-8b91488b4c88')]", - "Elastic SAN Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '80dcbedb-47ef-405d-95bd-188a1b4ac406')]", - "Elastic SAN Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'af6a70f8-3c9f-4105-acf1-d719e9fca4ca')]", - "Elastic SAN Volume Group Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8281131-f312-4f34-8d98-ae12be9f0d23')]", - "Reader and Data Access": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c12c1c16-33a1-487b-954d-41c89c60f349')]", - "Storage Account Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'e5e2a7ff-d759-4cd2-bb51-3152d37e2eb1')]", - "Storage Account Key Operator Service Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '81a9662b-bebf-436f-a333-f67b29880f12')]", - "Storage Blob Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ba92f5b4-2d11-453d-a403-e96b0029c9fe')]", - "Storage Blob Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", - "Storage Blob Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b7e6dc6d-f1e8-4753-8033-0f276bb0955b')]", - "Storage Blob Delegator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db58b8e5-c6ad-4a2a-8342-4190687cbf4a')]", - "Storage File Data SMB Share Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb')]", - "Storage File Data SMB Share Elevated Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7264617-510b-434b-a828-9731dc254ea7')]", - "Storage File Data SMB Share Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aba4ae5f-2193-4029-9191-0cb91df5e314')]", - "Storage Queue Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88')]", - "Storage Queue Data Message Processor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8a0f0c08-91a1-4084-bc3d-661d67233fed')]", - "Storage Queue Data Message Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c6a89b2d-59bc-44d0-9896-0f6e12d7b80a')]", - "Storage Queue Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '19e7f393-937e-4f77-808e-94535e297925')]", - "Storage Table Data Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0a9a7e1f-b9d0-4cc4-a60d-0319b160aaa3')]", - "Storage Table Data Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76199698-9eea-4c19-bc75-cec21354c6b6')]" + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]" } }, "resources": [ @@ -20756,13 +20016,15 @@ }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(last(split(parameters('resourceId'), '/')), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", - "properties": { + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", + "properties": { "description": "[parameters('description')]", "roleDefinitionId": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]", "principalId": "[parameters('principals')[copyIndex()].id]", "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", "delegatedManagedIdentityResourceId": "[if(parameters('crossTenant'), parameters('principals')[copyIndex()].resourceId, null())]" } } @@ -20770,568 +20032,699 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" ] - }, - { - "condition": "[parameters('isSystem')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-name', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "system-storage" - }, - "value": { - "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } + } + ], + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] + "value": "[resourceGroup().name]" }, - { - "condition": "[parameters('isSystem')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-key', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "system-storage-key" - }, - "value": { - "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] + "value": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]" }, - { - "condition": "[parameters('isSystem')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-endpoint', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "system-storage-blob-endpoint" - }, - "value": { - "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.blob]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } + "id": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] + "value": "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" }, - { - "condition": "[parameters('isSystem')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-connectionstring', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "system-storage-connection" - }, - "value": { - "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value, environment().suffixes.storage)]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] + "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))), '2022-05-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "[format('partitionStorage[{0}]', copyIndex())]", + "[format('partitionStorage[{0}]', copyIndex())]" + ] + }, + "partitionDb": { + "copy": { + "name": "partitionDb", + "count": "[length(parameters('partitions'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cosmos-db-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "resourceName": { + "value": "[format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))]" + }, + "resourceLocation": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName, 'partition', parameters('partitions')[copyIndex()].name, 'purpose', 'data'))]" + }, + "diagnosticWorkspaceId": { + "value": "[parameters('workspaceResourceId')]" + }, + "diagnosticLogsRetentionInDays": { + "value": 0 + }, + "isSystemPartition": "[if(equals(copyIndex(), 0), createObject('value', true()), createObject('value', false()))]", + "sqlDatabases": "[if(equals(copyIndex(), 0), createObject('value', union(array(variables('systemDatabase')), array(variables('partitionDatabase')))), createObject('value', array(variables('partitionDatabase'))))]", + "maxThroughput": { + "value": "[variables('partitionLayerConfig').database.throughput]" + }, + "backupPolicyType": { + "value": "[variables('partitionLayerConfig').database.backup]" + }, + "systemAssignedIdentity": { + "value": false + }, + "userAssignedIdentities": "[if(not(empty(parameters('cmekConfiguration').identityId)), createObject('value', createObject(format('{0}', parameters('cmekConfiguration').identityId), createObject())), createObject('value', createObject()))]", + "defaultIdentity": "[if(not(empty(parameters('cmekConfiguration').identityId)), createObject('value', parameters('cmekConfiguration').identityId), createObject('value', ''))]", + "kvKeyUri": "[if(and(not(empty(parameters('cmekConfiguration').kvUrl)), not(empty(parameters('cmekConfiguration').keyName))), createObject('value', format('{0}/keys/{1}', parameters('cmekConfiguration').kvUrl, parameters('cmekConfiguration').keyName)), createObject('value', ''))]", + "keyVaultName": { + "value": "[parameters('kvName')]" + }, + "databaseEndpointSecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosEndpoint)]" + }, + "databasePrimaryKeySecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosPrimaryKey)]" + }, + "databaseConnectionStringSecretName": { + "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosConnectionString)]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "17932091376944033154" + } + }, + "parameters": { + "resourceName": { + "type": "string", + "minLength": 3, + "maxLength": 20, + "metadata": { + "description": "Used to name all resources" + } }, - { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountSecretName'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-name', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "[parameters('storageAccountSecretName')]" - }, - "value": { - "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } + "resourceLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional: Resource Location." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Tags." + } + }, + "enableDeleteLock": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Enable lock to prevent accidental deletion" + } + }, + "multiwriteRegions": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Locations enabled for the Cosmos DB account." + } + }, + "maxThroughput": { + "type": "int", + "defaultValue": 4000, + "metadata": { + "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." + } + }, + "throughput": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." + } + }, + "systemAssignedIdentity": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedIdentities": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The ID(s) to assign to the resource." + } + }, + "defaultIdentity": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The default identity to be used." + } + }, + "databaseAccountOfferType": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Standard" + ], + "metadata": { + "description": "Optional. The offer type for the Cosmos DB database account." + } + }, + "defaultConsistencyLevel": { + "type": "string", + "defaultValue": "Session", + "allowedValues": [ + "Eventual", + "ConsistentPrefix", + "Session", + "BoundedStaleness", + "Strong" + ], + "metadata": { + "description": "Optional. The default consistency level of the Cosmos DB account." + } + }, + "automaticFailover": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable automatic failover for regions." + } + }, + "maxStalenessPrefix": { + "type": "int", + "defaultValue": 100000, + "minValue": 10, + "maxValue": 2147483647, + "metadata": { + "description": "Optional. Max stale requests. Required for BoundedStaleness. Valid ranges, Single Region: 10 to 1000000. Multi Region: 100000 to 1000000." + } + }, + "maxIntervalInSeconds": { + "type": "int", + "defaultValue": 300, + "minValue": 5, + "maxValue": 86400, + "metadata": { + "description": "Optional. Max lag time (minutes). Required for BoundedStaleness. Valid ranges, Single Region: 5 to 84600. Multi Region: 300 to 86400." + } + }, + "serverVersion": { + "type": "string", + "defaultValue": "4.2", + "allowedValues": [ + "3.2", + "3.6", + "4.0", + "4.2" + ], + "metadata": { + "description": "Optional. Specifies the MongoDB server version to use." + } + }, + "sqlDatabases": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. SQL Databases configurations." + } + }, + "gremlinDatabases": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Gremlin Databases configurations." + } + }, + "mongodbDatabases": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. MongoDB Databases configurations." + } + }, + "capabilitiesToAdd": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "EnableCassandra", + "EnableTable", + "EnableGremlin", + "EnableMongo", + "DisableRateLimitingResponses", + "EnableServerless" + ], + "metadata": { + "description": "Optional. List of Cosmos DB capabilities for the account." + } + }, + "backupPolicyType": { + "type": "string", + "defaultValue": "Periodic", + "allowedValues": [ + "Periodic", + "Continuous" + ], + "metadata": { + "description": "Optional. Describes the mode of backups." + } + }, + "backupPolicyContinuousTier": { + "type": "string", + "defaultValue": "Continuous30Days", + "allowedValues": [ + "Continuous30Days", + "Continuous7Days" + ], + "metadata": { + "description": "Optional. Configuration values for continuous mode backup." + } + }, + "backupIntervalInMinutes": { + "type": "int", + "defaultValue": 240, + "minValue": 60, + "maxValue": 1440, + "metadata": { + "description": "Optional. An integer representing the interval in minutes between two backups. Only applies to periodic backup type." + } + }, + "backupRetentionIntervalInHours": { + "type": "int", + "defaultValue": 8, + "minValue": 2, + "maxValue": 720, + "metadata": { + "description": "Optional. An integer representing the time (in hours) that each backup is retained. Only applies to periodic backup type." + } + }, + "backupStorageRedundancy": { + "type": "string", + "defaultValue": "Local", + "allowedValues": [ + "Geo", + "Local", + "Zone" + ], + "metadata": { + "description": "Optional. Enum to indicate type of backup residency. Only applies to periodic backup type." + } + }, + "roleAssignments": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" + } + }, + "diagnosticWorkspaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace." + } + }, + "diagnosticStorageAccountId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account." + } + }, + "diagnosticEventHubAuthorizationRuleId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "diagnosticEventHubName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category." + } + }, + "diagnosticLogsRetentionInDays": { + "type": "int", + "defaultValue": 365, + "minValue": 0, + "maxValue": 365, + "metadata": { + "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." + } + }, + "logsToEnable": { + "type": "array", + "defaultValue": [ + "DataPlaneRequests", + "MongoRequests", + "QueryRuntimeStatistics", + "PartitionKeyStatistics", + "PartitionKeyRUConsumption", + "ControlPlaneRequests", + "CassandraRequests", + "GremlinRequests", + "TableApiRequests" + ], + "allowedValues": [ + "DataPlaneRequests", + "MongoRequests", + "QueryRuntimeStatistics", + "PartitionKeyStatistics", + "PartitionKeyRUConsumption", + "ControlPlaneRequests", + "CassandraRequests", + "GremlinRequests", + "TableApiRequests" + ], + "metadata": { + "description": "Optional. The name of logs that will be streamed." + } + }, + "metricsToEnable": { + "type": "array", + "defaultValue": [ + "AllMetrics" + ], + "allowedValues": [ + "AllMetrics" + ], + "metadata": { + "description": "Optional. The name of metrics that will be streamed." + } + }, + "kvKeyUri": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Customer Managed Encryption Key." + } + }, + "crossTenant": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." + } + }, + "privateLinkSettings": { + "type": "object", + "defaultValue": { + "subnetId": "1", + "vnetId": "1" + }, + "metadata": { + "description": "Settings Required to Enable Private Link" + } + }, + "keyVaultName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: Key Vault Name to store secrets into" + } + }, + "databaseEndpointSecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account name into vault set the secret hame." + } + }, + "databasePrimaryKeySecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account key into vault set the secret hame." + } + }, + "databaseConnectionStringSecretName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional: To save storage account connectionstring into vault set the secret hame." + } + }, + "isSystemPartition": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional: Enable as System Partition." + } + } + }, + "variables": { + "copy": [ + { + "name": "diagnosticsLogs", + "count": "[length(parameters('logsToEnable'))]", + "input": { + "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" + } + } + }, + { + "name": "diagnosticsMetrics", + "count": "[length(parameters('metricsToEnable'))]", + "input": { + "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", + "timeGrain": null, + "enabled": true, + "retentionPolicy": { + "enabled": true, + "days": "[parameters('diagnosticLogsRetentionInDays')]" } } }, + { + "name": "databaseAccount_locations", + "count": "[length(parameters('multiwriteRegions'))]", + "input": { + "failoverPriority": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].failoverPriority]", + "isZoneRedundant": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].isZoneRedundant]", + "locationName": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].locationName]" + } + }, + { + "name": "capabilities", + "count": "[length(parameters('capabilitiesToAdd'))]", + "input": { + "name": "[parameters('capabilitiesToAdd')[copyIndex('capabilities')]]" + } + } + ], + "name": "[format('{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]", + "identityType": "[if(parameters('systemAssignedIdentity'), if(not(empty(parameters('userAssignedIdentities'))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(parameters('userAssignedIdentities'))), 'UserAssigned', 'None'))]", + "consistencyPolicy": { + "Eventual": { + "defaultConsistencyLevel": "Eventual" + }, + "ConsistentPrefix": { + "defaultConsistencyLevel": "ConsistentPrefix" + }, + "Session": { + "defaultConsistencyLevel": "Session" + }, + "BoundedStaleness": { + "defaultConsistencyLevel": "BoundedStaleness", + "maxStalenessPrefix": "[parameters('maxStalenessPrefix')]", + "maxIntervalInSeconds": "[parameters('maxIntervalInSeconds')]" + }, + "Strong": { + "defaultConsistencyLevel": "Strong" + } + }, + "kind": "[if(or(not(empty(parameters('sqlDatabases'))), not(empty(parameters('gremlinDatabases')))), 'GlobalDocumentDB', if(not(empty(parameters('mongodbDatabases'))), 'MongoDB', 'Parse'))]", + "backupPolicy": "[if(equals(parameters('backupPolicyType'), 'Continuous'), createObject('type', parameters('backupPolicyType'), 'continuousModeProperties', createObject('tier', parameters('backupPolicyContinuousTier'))), createObject('type', parameters('backupPolicyType'), 'periodicModeProperties', createObject('backupIntervalInMinutes', parameters('backupIntervalInMinutes'), 'backupRetentionIntervalInHours', parameters('backupRetentionIntervalInHours'), 'backupStorageRedundancy', parameters('backupStorageRedundancy'))))]", + "databaseAccount_properties": "[union(createObject('databaseAccountOfferType', parameters('databaseAccountOfferType')), if(or(or(not(empty(parameters('sqlDatabases'))), not(empty(parameters('mongodbDatabases')))), not(empty(parameters('gremlinDatabases')))), createObject('consistencyPolicy', variables('consistencyPolicy')[parameters('defaultConsistencyLevel')], 'enableMultipleWriteLocations', if(empty(parameters('multiwriteRegions')), false(), true()), 'locations', if(empty(parameters('multiwriteRegions')), createArray(createObject('failoverPriority', 0, 'isZoneRedundant', false(), 'locationName', parameters('resourceLocation'))), variables('databaseAccount_locations')), 'capabilities', variables('capabilities'), 'backupPolicy', variables('backupPolicy')), createObject()), if(not(empty(parameters('sqlDatabases'))), createObject('enableAutomaticFailover', parameters('automaticFailover'), 'AnalyticalStorageConfiguration', createObject('schemaType', 'WellDefined'), 'defaultIdentity', if(not(empty(parameters('defaultIdentity'))), format('UserAssignedIdentity={0}', parameters('defaultIdentity')), 'FirstPartyIdentity'), 'enablePartitionKeyMonitor', true(), 'enablePartitionMerge', false(), 'keyVaultKeyUri', if(not(empty(parameters('kvKeyUri'))), parameters('kvKeyUri'), null())), createObject()), if(not(empty(parameters('mongodbDatabases'))), createObject('apiProperties', createObject('serverVersion', parameters('serverVersion'))), createObject('EnabledApiTypes', createArray('Sql'))))]", + "enablePrivateLink": "[and(not(equals(parameters('privateLinkSettings').vnetId, '1')), not(equals(parameters('privateLinkSettings').subnetId, '1')))]", + "privateEndpointName": "[format('{0}-PrivateEndpoint', variables('name'))]", + "privateDNSZoneName": "privatelink.documents.azure.com" + }, + "resources": [ + { + "type": "Microsoft.DocumentDB/databaseAccounts", + "apiVersion": "2022-08-15", + "name": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]", + "location": "[parameters('resourceLocation')]", + "tags": "[parameters('tags')]", + "identity": { + "type": "[variables('identityType')]", + "userAssignedIdentities": "[if(not(empty(parameters('userAssignedIdentities'))), parameters('userAssignedIdentities'), createObject())]" + }, + "kind": "[variables('kind')]", + "properties": "[variables('databaseAccount_properties')]" + }, + { + "condition": "[parameters('enableDeleteLock')]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2017-04-01", + "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", + "name": "[format('{0}-lock', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", + "properties": { + "level": "CanNotDelete" + }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" ] }, { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountKeySecretName'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-key', deployment().name)]", + "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", + "name": "storage-diagnostics", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "[parameters('storageAccountKeySecretName')]" - }, - "value": { - "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the secret." - } - }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" + "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", + "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", + "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", + "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", + "metrics": "[variables('diagnosticsMetrics')]", + "logs": "[variables('diagnosticsLogs')]", + "logAnalyticsDestinationType": "AzureDiagnostics" + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2021-02-01", + "name": "[variables('privateEndpointName')]", + "location": "[parameters('resourceLocation')]", + "properties": { + "subnet": { + "id": "[parameters('privateLinkSettings').subnetId]" + }, + "privateLinkServiceConnections": [ + { + "name": "[variables('privateEndpointName')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", + "groupIds": [ + "Sql" + ] } } + ], + "customDnsConfigs": [ + { + "fqdn": "[variables('privateDNSZoneName')]" + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', variables('privateDNSZoneName'), format('{0}-link', variables('privateDNSZoneName')))]", + "location": "global", + "properties": { + "registrationEnabled": false, + "virtualNetwork": { + "id": "[parameters('privateLinkSettings').vnetId]" } }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]" ] }, { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountTableEndpointSecretName'))))]", + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateDnsZones", + "apiVersion": "2020-06-01", + "name": "[variables('privateDNSZoneName')]", + "location": "global" + }, + { + "condition": "[variables('enablePrivateLink')]", + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2022-01-01", + "name": "[format('{0}/{1}', variables('privateEndpointName'), 'dnsgroupname')]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "config1", + "properties": { + "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]", + "[resourceId('Microsoft.Network/privateEndpoints', variables('privateEndpointName'))]" + ] + }, + { + "copy": { + "name": "databaseAccount_sqlDatabases", + "count": "[length(parameters('sqlDatabases'))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-table-endpoint', deployment().name)]", + "name": "[format('{0}-{1}', deployment().name, parameters('sqlDatabases')[copyIndex()].name)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "databaseAccountName": { + "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" }, "name": { - "value": "[parameters('storageAccountTableEndpointSecretName')]" + "value": "[parameters('sqlDatabases')[copyIndex()].name]" }, - "value": { - "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.table]" + "throughput": { + "value": "[parameters('throughput')]" + }, + "maxThroughput": { + "value": "[parameters('maxThroughput')]" + }, + "containers": { + "value": "[coalesce(tryGet(parameters('sqlDatabases')[copyIndex()], 'containers'), createArray())]" } }, "template": { @@ -21341,148 +20734,232 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "4749529301937497394" + "templateHash": "7098548844242154112" } }, "parameters": { - "keyVaultName": { + "databaseAccountName": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." } }, "name": { "type": "string", "metadata": { - "description": "Required. The name of the secret." + "description": "Required. Name of the SQL database ." } }, - "value": { - "type": "securestring", + "containers": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" + "description": "Optional. Array of containers to deploy in the SQL database." } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" - ] - }, - { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountBlobEndpointSecretName'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-blob-endpoint', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "[parameters('storageAccountBlobEndpointSecretName')]" - }, - "value": { - "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').primaryEndpoints.blob]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", + "maxThroughput": { + "type": "int", + "defaultValue": 400, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." } }, - "name": { - "type": "string", + "throughput": { + "type": "int", + "defaultValue": -1, "metadata": { - "description": "Required. The name of the secret." + "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." } }, - "value": { - "type": "securestring", + "tags": { + "type": "object", + "defaultValue": {}, "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. Tags of the SQL database resource." } } }, "resources": [ { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases", + "apiVersion": "2022-08-15", + "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]", + "tags": "[parameters('tags')]", "properties": { - "value": "[parameters('value')]" + "options": "[if(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), createObject(), createObject('autoscaleSettings', if(equals(parameters('throughput'), -1), createObject('maxThroughput', parameters('maxThroughput')), null()), 'throughput', if(not(equals(parameters('throughput'), -1)), parameters('throughput'), null())))]", + "resource": { + "id": "[parameters('name')]" + } } + }, + { + "copy": { + "name": "container", + "count": "[length(parameters('containers'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}-sql-{2}', deployment().name, parameters('name'), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "databaseAccountName": { + "value": "[parameters('databaseAccountName')]" + }, + "sqlDatabaseName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('containers')[copyIndex()].name]" + }, + "paths": { + "value": "[parameters('containers')[copyIndex()].paths]" + }, + "kind": { + "value": "[parameters('containers')[copyIndex()].kind]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "7770544925063060791" + } + }, + "parameters": { + "databaseAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." + } + }, + "sqlDatabaseName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent SQL Database. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the container." + } + }, + "throughput": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the SQL Database resource." + } + }, + "paths": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of paths using which data within the container can be partitioned." + } + }, + "uniqueKeyPaths": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of unique key paths using which data within the container can be partitioned." + } + }, + "kind": { + "type": "string", + "defaultValue": "Hash", + "allowedValues": [ + "Hash", + "MultiHash", + "Range" + ], + "metadata": { + "description": "Optional. Indicates the kind of algorithm used for partitioning." + } + } + }, + "resources": [ + { + "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers", + "apiVersion": "2022-08-15", + "name": "[format('{0}/{1}/{2}', parameters('databaseAccountName'), parameters('sqlDatabaseName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "resource": { + "id": "[parameters('name')]", + "partitionKey": { + "paths": "[parameters('paths')]", + "kind": "[parameters('kind')]" + }, + "uniqueKeyPolicy": "[if(empty(parameters('uniqueKeyPaths')), null(), createObject('uniqueKeys', createArray(createObject('paths', parameters('uniqueKeyPaths')))))]" + }, + "options": "[if(or(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), equals(parameters('throughput'), -1)), null(), createObject('throughput', parameters('throughput')))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the container." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the container." + }, + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', parameters('databaseAccountName'), parameters('sqlDatabaseName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the container was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('databaseAccountName'), parameters('name'))]" + ] } ], "outputs": { "name": { "type": "string", "metadata": { - "description": "The name of the secret." + "description": "The name of the SQL database." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the secret." + "description": "The resource ID of the SQL database." }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('databaseAccountName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the resource group the secret was created in." + "description": "The name of the resource group the SQL database was created in." }, "value": "[resourceGroup().name]" } @@ -21490,28 +20967,37 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" ] }, { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('storageAccountConnectionString'))))]", + "copy": { + "name": "databaseAccount_gremlinDatabases", + "count": "[length(parameters('gremlinDatabases'))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-connectionstring', deployment().name)]", + "name": "[format('{0}-{1}', deployment().name, parameters('gremlinDatabases')[copyIndex()].name)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "databaseAccountName": { + "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" }, "name": { - "value": "[parameters('storageAccountConnectionString')]" + "value": "[parameters('gremlinDatabases')[copyIndex()].name]" }, - "value": { - "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};EndpointSuffix={2}', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), listKeys(resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))), '2023-01-01').keys[0].value, environment().suffixes.storage)]" + "throughput": { + "value": "[parameters('throughput')]" + }, + "maxThroughput": { + "value": "[parameters('maxThroughput')]" + }, + "graphs": { + "value": "[coalesce(tryGet(parameters('gremlinDatabases')[copyIndex()], 'graphs'), createArray())]" } }, "template": { @@ -21521,38 +21007,438 @@ "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "4749529301937497394" + "templateHash": "7000185662726108203" } }, "parameters": { - "keyVaultName": { + "name": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Required. Name of the Gremlin database." } }, - "name": { + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the Gremlin database resource." + } + }, + "databaseAccountName": { "type": "string", "metadata": { - "description": "Required. The name of the secret." + "description": "Conditional. The name of the parent Gremlin database. Required if the template is used in a standalone deployment." } }, - "value": { - "type": "securestring", + "graphs": { + "type": "array", + "defaultValue": [], "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. Array of graphs to deploy in the Gremlin database." + } + }, + "maxThroughput": { + "type": "int", + "defaultValue": 400, + "metadata": { + "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." + } + }, + "throughput": { + "type": "int", + "defaultValue": -1, + "metadata": { + "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." } } }, "resources": [ { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "type": "Microsoft.DocumentDB/databaseAccounts/gremlinDatabases", + "apiVersion": "2022-08-15", + "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]", + "tags": "[parameters('tags')]", "properties": { - "value": "[parameters('value')]" - } - } + "options": "[if(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), createObject(), createObject('autoscaleSettings', if(equals(parameters('throughput'), -1), createObject('maxThroughput', parameters('maxThroughput')), null()), 'throughput', if(not(equals(parameters('throughput'), -1)), parameters('throughput'), null())))]", + "resource": { + "id": "[parameters('name')]" + } + } + }, + { + "copy": { + "name": "gremlinDatabase_gremlinGraphs", + "count": "[length(parameters('graphs'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-{1}-graph-{2}', deployment().name, parameters('name'), parameters('graphs')[copyIndex()].name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('graphs')[copyIndex()].name]" + }, + "gremlinDatabaseName": { + "value": "[parameters('name')]" + }, + "databaseAccountName": { + "value": "[parameters('databaseAccountName')]" + }, + "automaticIndexing": { + "value": "[coalesce(tryGet(parameters('graphs')[copyIndex()], 'automaticIndexing'), true())]" + }, + "partitionKeyPaths": "[if(not(empty(parameters('graphs')[copyIndex()].partitionKeyPaths)), createObject('value', parameters('graphs')[copyIndex()].partitionKeyPaths), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "5271099334348231414" + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the graph." + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Tags of the Gremlin graph resource." + } + }, + "databaseAccountName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." + } + }, + "gremlinDatabaseName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Gremlin Database. Required if the template is used in a standalone deployment." + } + }, + "automaticIndexing": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Indicates if the indexing policy is automatic." + } + }, + "partitionKeyPaths": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of paths using which data within the container can be partitioned." + } + } + }, + "resources": [ + { + "type": "Microsoft.DocumentDB/databaseAccounts/gremlinDatabases/graphs", + "apiVersion": "2022-08-15", + "name": "[format('{0}/{1}/{2}', parameters('databaseAccountName'), parameters('gremlinDatabaseName'), parameters('name'))]", + "tags": "[parameters('tags')]", + "properties": { + "resource": { + "id": "[parameters('name')]", + "indexingPolicy": { + "automatic": "[parameters('automaticIndexing')]" + }, + "partitionKey": { + "paths": "[if(not(empty(parameters('partitionKeyPaths'))), parameters('partitionKeyPaths'), null())]" + } + } + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the graph." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the graph." + }, + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases/graphs', parameters('databaseAccountName'), parameters('gremlinDatabaseName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the graph was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases', parameters('databaseAccountName'), parameters('name'))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Gremlin database." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Gremlin database." + }, + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases', parameters('databaseAccountName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the Gremlin database was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "copy": { + "name": "databaseaccount_rbac", + "count": "[length(parameters('roleAssignments'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-rbac-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "description": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" + }, + "principals": { + "value": "[parameters('roleAssignments')[copyIndex()].principals]" + }, + "roleDefinitionIdOrName": { + "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + }, + "principalType": { + "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + }, + "resourceId": { + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + }, + "crossTenant": { + "value": "[parameters('crossTenant')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "11453009361404927356" + } + }, + "parameters": { + "description": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "principals": { + "type": "array", + "metadata": { + "description": "Required. The IDs of the principals to assign the role to. A resourceId is required when used in a cross tenant scenario (i.e. crossTenant is true)" + } + }, + "principalType": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "ServicePrincipal", + "Group", + "User", + "ForeignGroup", + "Device", + "" + ], + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the resource to apply the role assignment to." + } + }, + "condition": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "defaultValue": "2.0", + "allowedValues": [ + "2.0" + ], + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "crossTenant": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." + } + } + }, + "variables": { + "builtInRoleNames": { + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Cosmos DB Account Reader Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fbdf93bf-df7d-467e-a4d2-9458aa1360c8')]", + "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", + "CosmosBackupOperator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db7b14f2-5adf-42da-9f96-f2ee17bab5cb')]", + "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", + "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", + "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", + "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", + "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", + "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", + "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", + "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", + "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", + "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": [ + { + "copy": { + "name": "roleAssignment", + "count": "[length(parameters('principals'))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', last(split(parameters('resourceId'), '/')))]", + "name": "[guid(resourceId('Microsoft.DocumentDB/databaseAccounts', last(split(parameters('resourceId'), '/'))), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", + "properties": { + "description": "[parameters('description')]", + "roleDefinitionId": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]", + "principalId": "[parameters('principals')[copyIndex()].id]", + "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", + "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", + "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", + "delegatedManagedIdentityResourceId": "[if(parameters('crossTenant'), parameters('principals')[copyIndex()].resourceId, null())]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[parameters('isSystemPartition')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-name', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "system-cosmos-endpoint" + }, + "value": { + "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').documentEndpoint]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } ], "outputs": { "name": { @@ -21580,14 +21466,14 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" ] }, { - "condition": "[and(not(empty(parameters('keyVaultName'))), parameters('saveToken'))]", + "condition": "[parameters('isSystemPartition')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-sasToken', deployment().name)]", + "name": "[format('{0}-system-secret-key', deployment().name)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -21598,10 +21484,10 @@ "value": "[parameters('keyVaultName')]" }, "name": { - "value": "[format('{0}-SAS', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "value": "system-cosmos-primary-key" }, "value": { - "value": "[listAccountSAS(if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')), '2022-05-01', parameters('sasProperties')).accountSasToken]" + "value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').primaryMasterKey]" } }, "template": { @@ -21670,62 +21556,443 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" ] - } - ], - "outputs": { - "id": { - "type": "string", - "metadata": { - "description": "The resource ID." - }, - "value": "[resourceId('Microsoft.Storage/storageAccounts', if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name')))]" }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the resource." + { + "condition": "[parameters('isSystemPartition')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-system-secret-connection', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "system-cosmos-connection" + }, + "value": { + "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').connectionStrings[0].connectionString]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } }, - "value": "[if(greater(length(parameters('name')), 24), substring(parameters('name'), 0, 24), parameters('name'))]" - } - } - } - } - }, - "partitionStorageEndpoint": { - "copy": { - "name": "partitionStorageEndpoint", - "count": "[length(parameters('partitions'))]" - }, - "condition": "[parameters('enablePrivateLink')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-azure-storage-endpoint-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "resourceName": { - "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databaseEndpointSecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-name', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('databaseEndpointSecretName')]" + }, + "value": { + "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').documentEndpoint]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databasePrimaryKeySecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-key', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('databasePrimaryKeySecretName')]" + }, + "value": { + "value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').primaryMasterKey]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + }, + { + "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databaseConnectionStringSecretName'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secret-connection', deployment().name)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "name": { + "value": "[parameters('databaseConnectionStringSecretName')]" + }, + "value": { + "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').connectionStrings[0].connectionString]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "4749529301937497394" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the secret." + } + }, + "value": { + "type": "securestring", + "metadata": { + "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + } + } + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "properties": { + "value": "[parameters('value')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the secret." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the secret." + }, + "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the secret was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the database account." + }, + "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" + }, + "id": { + "type": "string", + "metadata": { + "description": "The resource ID of the database account." + }, + "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the database account was created in." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[if(and(parameters('systemAssignedIdentity'), contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').identity, 'principalId')), reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').identity.principalId, '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').location]" + } + } + } + } + }, + "partitionDbEndpoint": { + "copy": { + "name": "partitionDbEndpoint", + "count": "[length(parameters('partitions'))]" + }, + "condition": "[parameters('enablePrivateLink')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-cosmos-db-endpoint-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "resourceName": { + "value": "[reference(format('partitionDb[{0}]', copyIndex())).outputs.name.value]" }, "subnetResourceId": { "value": "[parameters('subnetId')]" }, "serviceResourceId": { - "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.id.value]" + "value": "[reference(format('partitionDb[{0}]', copyIndex())).outputs.id.value]" }, "groupIds": { "value": [ - "blob" + "sql" ] }, "privateDnsZoneGroup": { "value": { "privateDNSResourceIds": [ - "[parameters('storageDNSZoneId')]" + "[parameters('cosmosDNSZoneId')]" ] } } @@ -22176,1190 +22443,1575 @@ } }, "dependsOn": [ - "[format('partitionStorage[{0}]', copyIndex())]", - "[format('partitionStorage[{0}]', copyIndex())]" + "[format('partitionDb[{0}]', copyIndex())]", + "[format('partitionDb[{0}]', copyIndex())]" ] }, - "partitionDb": { + "partitonNamespace": { "copy": { - "name": "partitionDb", + "name": "partitonNamespace", "count": "[length(parameters('partitions'))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-cosmos-db-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "name": "[format('{0}-service-bus-{1}', parameters('bladeConfig').sectionName, copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "resourceName": { - "value": "[format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))]" + "name": { + "value": "[format('{0}{1}', replace(format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6)), '-', ''), uniqueString(resourceGroup().id, format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))))]" }, - "resourceLocation": { + "location": { "value": "[parameters('location')]" }, "tags": { "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName, 'partition', parameters('partitions')[copyIndex()].name, 'purpose', 'data'))]" }, - "diagnosticWorkspaceId": { - "value": "[parameters('workspaceResourceId')]" - }, - "diagnosticLogsRetentionInDays": { - "value": 0 - }, - "isSystemPartition": "[if(equals(copyIndex(), 0), createObject('value', true()), createObject('value', false()))]", - "sqlDatabases": "[if(equals(copyIndex(), 0), createObject('value', union(array(variables('systemDatabase')), array(variables('partitionDatabase')))), createObject('value', array(variables('partitionDatabase'))))]", - "maxThroughput": { - "value": "[variables('partitionLayerConfig').database[parameters('partitionSize')].throughput]" + "diagnosticSettings": { + "value": [ + { + "workspaceResourceId": "[parameters('workspaceResourceId')]" + } + ] }, - "backupPolicyType": { - "value": "[variables('partitionLayerConfig').database.backup]" + "skuObject": { + "value": { + "name": "[variables('partitionLayerConfig').servicebus.sku]", + "capacity": "[if(equals(variables('partitionLayerConfig').servicebus.sku, 'Premium'), 2, null())]" + } }, - "systemAssignedIdentity": { + "zoneRedundant": "[if(equals(variables('partitionLayerConfig').servicebus.sku, 'Premium'), createObject('value', true()), createObject('value', false()))]", + "disableLocalAuth": { "value": false }, - "userAssignedIdentities": "[if(not(empty(parameters('cmekConfiguration').identityId)), createObject('value', createObject(format('{0}', parameters('cmekConfiguration').identityId), createObject())), createObject('value', createObject()))]", - "defaultIdentity": "[if(not(empty(parameters('cmekConfiguration').identityId)), createObject('value', parameters('cmekConfiguration').identityId), createObject('value', ''))]", - "kvKeyUri": "[if(and(not(empty(parameters('cmekConfiguration').kvUrl)), not(empty(parameters('cmekConfiguration').keyName))), createObject('value', format('{0}/keys/{1}', parameters('cmekConfiguration').kvUrl, parameters('cmekConfiguration').keyName)), createObject('value', ''))]", - "keyVaultName": { - "value": "[parameters('kvName')]" - }, - "databaseEndpointSecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosEndpoint)]" - }, - "databasePrimaryKeySecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosPrimaryKey)]" + "authorizationRules": { + "value": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + ] }, - "databaseConnectionStringSecretName": { - "value": "[format('{0}-{1}', parameters('partitions')[copyIndex()].name, variables('partitionLayerConfig').secrets.cosmosConnectionString)]" + "topics": { + "copy": [ + { + "name": "value", + "count": "[length(variables('partitionLayerConfig').servicebus.topics)]", + "input": "[createObject('name', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].name, 'maxSizeInMegabytes', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].maxSizeInMegabytes, 'authorizationRules', createArray(createObject('name', 'RootManageSharedAccessKey', 'rights', createArray('Listen', 'Manage', 'Send'))), 'subscriptions', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].subscriptions)]" + } + ] } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17932091376944033154" - } - }, - "parameters": { - "resourceName": { - "type": "string", - "minLength": 3, - "maxLength": 20, - "metadata": { - "description": "Used to name all resources" - } - }, - "resourceLocation": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional: Resource Location." - } + "version": "0.29.47.4906", + "templateHash": "16891238855778423574" }, - "tags": { + "name": "Service Bus Namespaces", + "description": "This module deploys a Service Bus Namespace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Tags." - } + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourcesIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true }, - "enableDeleteLock": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable lock to prevent accidental deletion" - } + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true }, - "multiwriteRegions": { + "roleAssignmentType": { "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Locations enabled for the Cosmos DB account." - } - }, - "maxThroughput": { - "type": "int", - "defaultValue": 4000, - "metadata": { - "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." - } - }, - "throughput": { - "type": "int", - "defaultValue": -1, - "metadata": { - "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." - } + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true }, - "systemAssignedIdentity": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." - } + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } + } + } + }, + "nullable": true }, - "userAssignedIdentities": { + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. The ID(s) to assign to the resource." - } + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true }, - "defaultIdentity": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The default identity to be used." + "skuType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], + "metadata": { + "description": "Required. Name of this SKU. - Basic, Standard, Premium." + } + }, + "capacity": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The specified messaging units for the tier. Only used for Premium Sku tier." + } + } } }, - "databaseAccountOfferType": { - "type": "string", - "defaultValue": "Standard", - "allowedValues": [ - "Standard" - ], - "metadata": { - "description": "Optional. The offer type for the Cosmos DB database account." + "authorizationRuleType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "nullable": true, + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + } } }, - "defaultConsistencyLevel": { - "type": "string", - "defaultValue": "Session", - "allowedValues": [ - "Eventual", - "ConsistentPrefix", - "Session", - "BoundedStaleness", - "Strong" - ], - "metadata": { - "description": "Optional. The default consistency level of the Cosmos DB account." - } - }, - "automaticFailover": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable automatic failover for regions." - } - }, - "maxStalenessPrefix": { - "type": "int", - "defaultValue": 100000, - "minValue": 10, - "maxValue": 2147483647, - "metadata": { - "description": "Optional. Max stale requests. Required for BoundedStaleness. Valid ranges, Single Region: 10 to 1000000. Multi Region: 100000 to 1000000." - } - }, - "maxIntervalInSeconds": { - "type": "int", - "defaultValue": 300, - "minValue": 5, - "maxValue": 86400, - "metadata": { - "description": "Optional. Max lag time (minutes). Required for BoundedStaleness. Valid ranges, Single Region: 5 to 84600. Multi Region: 300 to 86400." - } - }, - "serverVersion": { - "type": "string", - "defaultValue": "4.2", - "allowedValues": [ - "3.2", - "3.6", - "4.0", - "4.2" - ], - "metadata": { - "description": "Optional. Specifies the MongoDB server version to use." - } - }, - "sqlDatabases": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. SQL Databases configurations." - } - }, - "gremlinDatabases": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Gremlin Databases configurations." - } - }, - "mongodbDatabases": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. MongoDB Databases configurations." - } - }, - "capabilitiesToAdd": { - "type": "array", - "defaultValue": [], - "allowedValues": [ - "EnableCassandra", - "EnableTable", - "EnableGremlin", - "EnableMongo", - "DisableRateLimitingResponses", - "EnableServerless" - ], - "metadata": { - "description": "Optional. List of Cosmos DB capabilities for the account." - } - }, - "backupPolicyType": { - "type": "string", - "defaultValue": "Periodic", - "allowedValues": [ - "Periodic", - "Continuous" - ], - "metadata": { - "description": "Optional. Describes the mode of backups." - } - }, - "backupPolicyContinuousTier": { - "type": "string", - "defaultValue": "Continuous30Days", - "allowedValues": [ - "Continuous30Days", - "Continuous7Days" - ], - "metadata": { - "description": "Optional. Configuration values for continuous mode backup." - } - }, - "backupIntervalInMinutes": { - "type": "int", - "defaultValue": 240, - "minValue": 60, - "maxValue": 1440, - "metadata": { - "description": "Optional. An integer representing the interval in minutes between two backups. Only applies to periodic backup type." - } - }, - "backupRetentionIntervalInHours": { - "type": "int", - "defaultValue": 8, - "minValue": 2, - "maxValue": 720, - "metadata": { - "description": "Optional. An integer representing the time (in hours) that each backup is retained. Only applies to periodic backup type." - } - }, - "backupStorageRedundancy": { - "type": "string", - "defaultValue": "Local", - "allowedValues": [ - "Geo", - "Local", - "Zone" - ], - "metadata": { - "description": "Optional. Enum to indicate type of backup residency. Only applies to periodic backup type." - } - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" - } - }, - "diagnosticWorkspaceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace." - } - }, - "diagnosticStorageAccountId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account." - } - }, - "diagnosticEventHubAuthorizationRuleId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." - } - }, - "diagnosticEventHubName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category." - } - }, - "diagnosticLogsRetentionInDays": { - "type": "int", - "defaultValue": 365, - "minValue": 0, - "maxValue": 365, - "metadata": { - "description": "Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely." - } - }, - "logsToEnable": { - "type": "array", - "defaultValue": [ - "DataPlaneRequests", - "MongoRequests", - "QueryRuntimeStatistics", - "PartitionKeyStatistics", - "PartitionKeyRUConsumption", - "ControlPlaneRequests", - "CassandraRequests", - "GremlinRequests", - "TableApiRequests" - ], - "allowedValues": [ - "DataPlaneRequests", - "MongoRequests", - "QueryRuntimeStatistics", - "PartitionKeyStatistics", - "PartitionKeyRUConsumption", - "ControlPlaneRequests", - "CassandraRequests", - "GremlinRequests", - "TableApiRequests" - ], - "metadata": { - "description": "Optional. The name of logs that will be streamed." - } - }, - "metricsToEnable": { - "type": "array", - "defaultValue": [ - "AllMetrics" - ], - "allowedValues": [ - "AllMetrics" - ], - "metadata": { - "description": "Optional. The name of metrics that will be streamed." - } - }, - "kvKeyUri": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Customer Managed Encryption Key." - } - }, - "crossTenant": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." - } - }, - "privateLinkSettings": { + "disasterRecoveryConfigType": { "type": "object", - "defaultValue": { - "subnetId": "1", - "vnetId": "1" - }, - "metadata": { - "description": "Settings Required to Enable Private Link" - } - }, - "keyVaultName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: Key Vault Name to store secrets into" - } - }, - "databaseEndpointSecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account name into vault set the secret hame." - } - }, - "databasePrimaryKeySecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account key into vault set the secret hame." - } - }, - "databaseConnectionStringSecretName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional: To save storage account connectionstring into vault set the secret hame." - } - }, - "isSystemPartition": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional: Enable as System Partition." - } - } - }, - "variables": { - "copy": [ - { - "name": "diagnosticsLogs", - "count": "[length(parameters('logsToEnable'))]", - "input": { - "category": "[parameters('logsToEnable')[copyIndex('diagnosticsLogs')]]", - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the disaster recovery config." } - } - }, - { - "name": "diagnosticsMetrics", - "count": "[length(parameters('metricsToEnable'))]", - "input": { - "category": "[parameters('metricsToEnable')[copyIndex('diagnosticsMetrics')]]", - "timeGrain": null, - "enabled": true, - "retentionPolicy": { - "enabled": true, - "days": "[parameters('diagnosticLogsRetentionInDays')]" + }, + "alternateName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Primary/Secondary eventhub namespace name, which is part of GEO DR pairing." + } + }, + "partnerNamespace": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." } } }, - { - "name": "databaseAccount_locations", - "count": "[length(parameters('multiwriteRegions'))]", - "input": { - "failoverPriority": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].failoverPriority]", - "isZoneRedundant": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].isZoneRedundant]", - "locationName": "[parameters('multiwriteRegions')[copyIndex('databaseAccount_locations')].locationName]" - } - }, - { - "name": "capabilities", - "count": "[length(parameters('capabilitiesToAdd'))]", - "input": { - "name": "[parameters('capabilitiesToAdd')[copyIndex('capabilities')]]" - } - } - ], - "name": "[format('{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]", - "identityType": "[if(parameters('systemAssignedIdentity'), if(not(empty(parameters('userAssignedIdentities'))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(parameters('userAssignedIdentities'))), 'UserAssigned', 'None'))]", - "consistencyPolicy": { - "Eventual": { - "defaultConsistencyLevel": "Eventual" - }, - "ConsistentPrefix": { - "defaultConsistencyLevel": "ConsistentPrefix" - }, - "Session": { - "defaultConsistencyLevel": "Session" - }, - "BoundedStaleness": { - "defaultConsistencyLevel": "BoundedStaleness", - "maxStalenessPrefix": "[parameters('maxStalenessPrefix')]", - "maxIntervalInSeconds": "[parameters('maxIntervalInSeconds')]" - }, - "Strong": { - "defaultConsistencyLevel": "Strong" - } - }, - "kind": "[if(or(not(empty(parameters('sqlDatabases'))), not(empty(parameters('gremlinDatabases')))), 'GlobalDocumentDB', if(not(empty(parameters('mongodbDatabases'))), 'MongoDB', 'Parse'))]", - "backupPolicy": "[if(equals(parameters('backupPolicyType'), 'Continuous'), createObject('type', parameters('backupPolicyType'), 'continuousModeProperties', createObject('tier', parameters('backupPolicyContinuousTier'))), createObject('type', parameters('backupPolicyType'), 'periodicModeProperties', createObject('backupIntervalInMinutes', parameters('backupIntervalInMinutes'), 'backupRetentionIntervalInHours', parameters('backupRetentionIntervalInHours'), 'backupStorageRedundancy', parameters('backupStorageRedundancy'))))]", - "databaseAccount_properties": "[union(createObject('databaseAccountOfferType', parameters('databaseAccountOfferType')), if(or(or(not(empty(parameters('sqlDatabases'))), not(empty(parameters('mongodbDatabases')))), not(empty(parameters('gremlinDatabases')))), createObject('consistencyPolicy', variables('consistencyPolicy')[parameters('defaultConsistencyLevel')], 'enableMultipleWriteLocations', if(empty(parameters('multiwriteRegions')), false(), true()), 'locations', if(empty(parameters('multiwriteRegions')), createArray(createObject('failoverPriority', 0, 'isZoneRedundant', false(), 'locationName', parameters('resourceLocation'))), variables('databaseAccount_locations')), 'capabilities', variables('capabilities'), 'backupPolicy', variables('backupPolicy')), createObject()), if(not(empty(parameters('sqlDatabases'))), createObject('enableAutomaticFailover', parameters('automaticFailover'), 'AnalyticalStorageConfiguration', createObject('schemaType', 'WellDefined'), 'defaultIdentity', if(not(empty(parameters('defaultIdentity'))), format('UserAssignedIdentity={0}', parameters('defaultIdentity')), 'FirstPartyIdentity'), 'enablePartitionKeyMonitor', true(), 'enablePartitionMerge', false(), 'keyVaultKeyUri', if(not(empty(parameters('kvKeyUri'))), parameters('kvKeyUri'), null())), createObject()), if(not(empty(parameters('mongodbDatabases'))), createObject('apiProperties', createObject('serverVersion', parameters('serverVersion'))), createObject('EnabledApiTypes', createArray('Sql'))))]", - "enablePrivateLink": "[and(not(equals(parameters('privateLinkSettings').vnetId, '1')), not(equals(parameters('privateLinkSettings').subnetId, '1')))]", - "privateEndpointName": "[format('{0}-PrivateEndpoint', variables('name'))]", - "privateDNSZoneName": "privatelink.documents.azure.com" - }, - "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts", - "apiVersion": "2022-08-15", - "name": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]", - "location": "[parameters('resourceLocation')]", - "tags": "[parameters('tags')]", - "identity": { - "type": "[variables('identityType')]", - "userAssignedIdentities": "[if(not(empty(parameters('userAssignedIdentities'))), parameters('userAssignedIdentities'), createObject())]" - }, - "kind": "[variables('kind')]", - "properties": "[variables('databaseAccount_properties')]" - }, - { - "condition": "[parameters('enableDeleteLock')]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2017-04-01", - "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", - "name": "[format('{0}-lock', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", - "properties": { - "level": "CanNotDelete" - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - ] - }, - { - "condition": "[or(or(or(not(empty(parameters('diagnosticStorageAccountId'))), not(empty(parameters('diagnosticWorkspaceId')))), not(empty(parameters('diagnosticEventHubAuthorizationRuleId')))), not(empty(parameters('diagnosticEventHubName'))))]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", - "name": "storage-diagnostics", - "properties": { - "storageAccountId": "[if(not(empty(parameters('diagnosticStorageAccountId'))), parameters('diagnosticStorageAccountId'), null())]", - "workspaceId": "[if(not(empty(parameters('diagnosticWorkspaceId'))), parameters('diagnosticWorkspaceId'), null())]", - "eventHubAuthorizationRuleId": "[if(not(empty(parameters('diagnosticEventHubAuthorizationRuleId'))), parameters('diagnosticEventHubAuthorizationRuleId'), null())]", - "eventHubName": "[if(not(empty(parameters('diagnosticEventHubName'))), parameters('diagnosticEventHubName'), null())]", - "metrics": "[variables('diagnosticsMetrics')]", - "logs": "[variables('diagnosticsLogs')]", - "logAnalyticsDestinationType": "AzureDiagnostics" - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - ] + "nullable": true }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2021-02-01", - "name": "[variables('privateEndpointName')]", - "location": "[parameters('resourceLocation')]", + "migrationConfigurationsType": { + "type": "object", "properties": { - "subnet": { - "id": "[parameters('privateLinkSettings').subnetId]" - }, - "privateLinkServiceConnections": [ - { - "name": "[variables('privateEndpointName')]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]", - "groupIds": [ - "Sql" - ] - } + "postMigrationName": { + "type": "string", + "metadata": { + "description": "Required. Name to access Standard Namespace after migration." } - ], - "customDnsConfigs": [ - { - "fqdn": "[variables('privateDNSZoneName')]" + }, + "targetNamespace": { + "type": "string", + "metadata": { + "description": "Required. Existing premium Namespace resource ID which has no entities, will be used for migration." } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - ] - }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", - "apiVersion": "2020-06-01", - "name": "[format('{0}/{1}', variables('privateDNSZoneName'), format('{0}-link', variables('privateDNSZoneName')))]", - "location": "global", - "properties": { - "registrationEnabled": false, - "virtualNetwork": { - "id": "[parameters('privateLinkSettings').vnetId]" } }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]" - ] - }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateDnsZones", - "apiVersion": "2020-06-01", - "name": "[variables('privateDNSZoneName')]", - "location": "global" + "nullable": true }, - { - "condition": "[variables('enablePrivateLink')]", - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2022-01-01", - "name": "[format('{0}/{1}', variables('privateEndpointName'), 'dnsgroupname')]", + "networkRuleSetType": { + "type": "object", "properties": { - "privateDnsZoneConfigs": [ - { - "name": "config1", - "properties": { - "privateDnsZoneId": "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]" - } + "publicNetworkAccess": { + "type": "string", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "nullable": true, + "metadata": { + "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateDnsZones', variables('privateDNSZoneName'))]", - "[resourceId('Microsoft.Network/privateEndpoints', variables('privateEndpointName'))]" - ] - }, - { - "copy": { - "name": "databaseAccount_sqlDatabases", - "count": "[length(parameters('sqlDatabases'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}', deployment().name, parameters('sqlDatabases')[copyIndex()].name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" }, - "mode": "Incremental", - "parameters": { - "databaseAccountName": { - "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" + "defaultAction": { + "type": "string", + "allowedValues": [ + "Allow", + "Deny" + ], + "nullable": true, + "metadata": { + "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." + } + }, + "trustedServiceAccessEnabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not. Default is \"true\". It will not be set if publicNetworkAccess is \"Disabled\"." + } + }, + "ipRules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "action": { + "type": "string", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Required. The IP filter action." + } + }, + "ipMask": { + "type": "string", + "metadata": { + "description": "Required. The IP mask." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. List of IpRules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "virtualNetworkRules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "ignoreMissingVnetServiceEndpoint": { + "type": "bool", + "metadata": { + "description": "Required. The virtual network rule name." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. The ID of the subnet." + } + } + } }, + "nullable": true, + "metadata": { + "description": "Optional. List virtual network rules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + } + }, + "nullable": true + }, + "queueType": { + "type": "array", + "items": { + "type": "object", + "properties": { "name": { - "value": "[parameters('sqlDatabases')[copyIndex()].name]" + "type": "string", + "metadata": { + "description": "Required. The name of the queue." + } }, - "throughput": { - "value": "[parameters('throughput')]" + "autoDeleteOnIdle": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8061 timeSpan idle interval after which the queue is automatically deleted. The minimum duration is 5 minutes (PT5M)." + } }, - "maxThroughput": { - "value": "[parameters('maxThroughput')]" + "forwardDeadLetteredMessagesTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Queue/Topic name to forward the Dead Letter message." + } }, - "containers": { - "value": "[coalesce(tryGet(parameters('sqlDatabases')[copyIndex()], 'containers'), createArray())]" + "forwardTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Queue/Topic name to forward the messages." + } + }, + "maxMessageSizeInKilobytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the queue. This property is only used in Premium today and default is 1024." + } + }, + "authorizationRules": { + "$ref": "#/definitions/authorizationRuleType", + "nullable": true, + "metadata": { + "description": "Optional. Authorization Rules for the Service Bus Queue." + } + }, + "deadLetteringOnMessageExpiration": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether this queue has dead letter support when a message expires." + } + }, + "defaultMessageTimeToLive": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." + } + }, + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "enableBatchedOperations": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Value that indicates whether server-side batched operations are enabled." + } + }, + "enableExpress": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether Express Entities are enabled. An express queue holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." + } + }, + "enablePartitioning": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the queue is to be partitioned across multiple message brokers." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "nullable": true, + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "lockDuration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." + } + }, + "maxDeliveryCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum delivery count. A message is automatically deadlettered after this number of deliveries. default value is 10." + } + }, + "maxSizeInMegabytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum size of the queue in megabytes, which is the size of memory allocated for the queue. Default is 1024." + } + }, + "requiresDuplicateDetection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value indicating if this queue requires duplicate detection." + } + }, + "requiresSession": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the queue supports the concept of sessions." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "status": { + "type": "string", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." + } } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7098548844242154112" + } + }, + "nullable": true + }, + "topicType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the topic." } }, - "parameters": { - "databaseAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the SQL database ." - } - }, - "containers": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of containers to deploy in the SQL database." - } - }, - "maxThroughput": { - "type": "int", - "defaultValue": 400, - "metadata": { - "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." - } - }, - "throughput": { - "type": "int", - "defaultValue": -1, - "metadata": { - "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the SQL database resource." - } + "authorizationRules": { + "$ref": "#/definitions/authorizationRuleType", + "nullable": true, + "metadata": { + "description": "Optional. Authorization Rules for the Service Bus Topic." } }, - "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases", - "apiVersion": "2022-08-15", - "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]", - "tags": "[parameters('tags')]", - "properties": { - "options": "[if(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), createObject(), createObject('autoscaleSettings', if(equals(parameters('throughput'), -1), createObject('maxThroughput', parameters('maxThroughput')), null()), 'throughput', if(not(equals(parameters('throughput'), -1)), parameters('throughput'), null())))]", - "resource": { - "id": "[parameters('name')]" - } - } - }, - { - "copy": { - "name": "container", - "count": "[length(parameters('containers'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}-sql-{2}', deployment().name, parameters('name'), copyIndex())]", + "autoDeleteOnIdle": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the topic is automatically deleted. The minimum duration is 5 minutes." + } + }, + "defaultMessageTimeToLive": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." + } + }, + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "enableBatchedOperations": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Value that indicates whether server-side batched operations are enabled." + } + }, + "enableExpress": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether Express Entities are enabled. An express topic holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." + } + }, + "enablePartitioning": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the topic is to be partitioned across multiple message brokers." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "nullable": true, + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "maxMessageSizeInKilobytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the topic. This property is only used in Premium today and default is 1024." + } + }, + "maxSizeInMegabytes": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. Default is 1024." + } + }, + "requiresDuplicateDetection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value indicating if this topic requires duplicate detection." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "status": { + "type": "string", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." + } + }, + "supportOrdering": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Value that indicates whether the topic supports ordering." + } + }, + "subscriptions": { + "type": "array", + "items": { + "type": "object", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "databaseAccountName": { - "value": "[parameters('databaseAccountName')]" - }, - "sqlDatabaseName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[parameters('containers')[copyIndex()].name]" - }, - "paths": { - "value": "[parameters('containers')[copyIndex()].paths]" - }, - "kind": { - "value": "[parameters('containers')[copyIndex()].kind]" + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the service bus namespace topic subscription." } }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", + "autoDeleteOnIdle": { + "type": "string", + "nullable": true, "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7770544925063060791" - } - }, - "parameters": { - "databaseAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." - } - }, - "sqlDatabaseName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent SQL Database. Required if the template is used in a standalone deployment." - } - }, - "name": { + "description": "Optional. ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes." + } + }, + "clientAffineProperties": { + "type": "object", + "properties": { + "clientId": { "type": "string", "metadata": { - "description": "Required. Name of the container." - } - }, - "throughput": { - "type": "int", - "defaultValue": -1, - "metadata": { - "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." + "description": "Required. Indicates the Client ID of the application that created the client-affine subscription." } }, - "tags": { - "type": "object", - "defaultValue": {}, + "isDurable": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. Tags of the SQL Database resource." + "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is durable or not." } }, - "paths": { - "type": "array", - "defaultValue": [], + "isShared": { + "type": "bool", + "nullable": true, "metadata": { - "description": "Optional. List of paths using which data within the container can be partitioned." - } - }, - "uniqueKeyPaths": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List of unique key paths using which data within the container can be partitioned." - } - }, - "kind": { - "type": "string", - "defaultValue": "Hash", - "allowedValues": [ - "Hash", - "MultiHash", - "Range" - ], - "metadata": { - "description": "Optional. Indicates the kind of algorithm used for partitioning." + "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is shared or not." } } }, - "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers", - "apiVersion": "2022-08-15", - "name": "[format('{0}/{1}/{2}', parameters('databaseAccountName'), parameters('sqlDatabaseName'), parameters('name'))]", - "tags": "[parameters('tags')]", - "properties": { - "resource": { - "id": "[parameters('name')]", - "partitionKey": { - "paths": "[parameters('paths')]", - "kind": "[parameters('kind')]" - }, - "uniqueKeyPolicy": "[if(empty(parameters('uniqueKeyPaths')), null(), createObject('uniqueKeys', createArray(createObject('paths', parameters('uniqueKeyPaths')))))]" - }, - "options": "[if(or(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), equals(parameters('throughput'), -1)), null(), createObject('throughput', parameters('throughput')))]" - } - } + "nullable": true, + "metadata": { + "description": "Optional. The properties that are associated with a subscription that is client-affine." + } + }, + "deadLetteringOnMessageExpiration": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "deadLetteringOnFilterEvaluationExceptions": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "defaultMessageTimeToLive": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." + } + }, + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "enableBatchedOperations": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether server-side batched operations are enabled." + } + }, + "forwardDeadLetteredMessagesTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "forwardTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "isClientAffine": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "lockDuration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." + } + }, + "maxDeliveryCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." + } + }, + "requiresSession": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "status": { + "type": "string", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the container." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the container." - }, - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers', parameters('databaseAccountName'), parameters('sqlDatabaseName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the container was created in." - }, - "value": "[resourceGroup().name]" - } + "nullable": true, + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." } } - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('databaseAccountName'), parameters('name'))]" - ] - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the SQL database." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the SQL database." - }, - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/sqlDatabases', parameters('databaseAccountName'), parameters('name'))]" + } }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the SQL database was created in." - }, - "value": "[resourceGroup().name]" + "nullable": true, + "metadata": { + "description": "Optional. The subscriptions of the topic." } } } }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 260, + "metadata": { + "description": "Required. Name of the Service Bus Namespace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "skuObject": { + "$ref": "#/definitions/skuType", + "defaultValue": { + "name": "Premium", + "capacity": 2 + }, + "metadata": { + "description": "Required. The SKU of the Service Bus Namespace. Defaulted to Premium for ZoneRedundant configurations by default." + } + }, + "zoneRedundant": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enabled by default in order to align with resiliency best practices, thus requires Premium SKU." + } + }, + "minimumTlsVersion": { + "type": "string", + "defaultValue": "1.2", + "allowedValues": [ + "1.0", + "1.1", + "1.2" + ], + "metadata": { + "description": "Optional. The minimum TLS version for the cluster to support." + } + }, + "alternateName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Alternate name for namespace." + } + }, + "premiumMessagingPartitions": { + "type": "int", + "defaultValue": 1, + "metadata": { + "description": "Optional. The number of partitions of a Service Bus namespace. This property is only applicable to Premium SKU namespaces. The default value is 1 and possible values are 1, 2 and 4." + } + }, + "authorizationRules": { + "$ref": "#/definitions/authorizationRuleType", + "defaultValue": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + ], + "metadata": { + "description": "Optional. Authorization Rules for the Service Bus namespace." + } + }, + "migrationConfiguration": { + "$ref": "#/definitions/migrationConfigurationsType", + "metadata": { + "description": "Optional. The migration configuration." + } + }, + "disasterRecoveryConfig": { + "$ref": "#/definitions/disasterRecoveryConfigType", + "metadata": { + "description": "Optional. The disaster recovery configuration." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Disabled", + "Enabled", + "SecuredByPerimeter" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "networkRuleSets": { + "$ref": "#/definitions/networkRuleSetType", + "nullable": true, + "metadata": { + "description": "Optional. Configure networking options for Premium SKU Service Bus. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property disables SAS authentication for the Service Bus namespace." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "queues": { + "$ref": "#/definitions/queueType", + "nullable": true, + "metadata": { + "description": "Optional. The queues to create in the service bus namespace." + } + }, + "topics": { + "$ref": "#/definitions/topicType", + "nullable": true, + "metadata": { + "description": "Optional. The topics to create in the service bus namespace." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "requireInfrastructureEncryption": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters." + } + } + }, + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", + "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", + "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "cMKKeyVault" ] }, - { - "copy": { - "name": "databaseAccount_gremlinDatabases", - "count": "[length(parameters('gremlinDatabases'))]" - }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}', deployment().name, parameters('gremlinDatabases')[copyIndex()].name)]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.servicebus-namespace.{0}.{1}', replace('0.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, "mode": "Incremental", - "parameters": { - "databaseAccountName": { - "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" - }, - "name": { - "value": "[parameters('gremlinDatabases')[copyIndex()].name]" - }, - "throughput": { - "value": "[parameters('throughput')]" - }, - "maxThroughput": { - "value": "[parameters('maxThroughput')]" - }, - "graphs": { - "value": "[coalesce(tryGet(parameters('gremlinDatabases')[copyIndex()], 'graphs'), createArray())]" - } - }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7000185662726108203" - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the Gremlin database." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the Gremlin database resource." - } - }, - "databaseAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Gremlin database. Required if the template is used in a standalone deployment." - } - }, - "graphs": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of graphs to deploy in the Gremlin database." - } - }, - "maxThroughput": { - "type": "int", - "defaultValue": 400, - "metadata": { - "description": "Optional. Represents maximum throughput, the resource can scale up to. Cannot be set together with `throughput`. If `throughput` is set to something else than -1, this autoscale setting is ignored." - } - }, - "throughput": { - "type": "int", - "defaultValue": -1, - "metadata": { - "description": "Optional. Request Units per second (for example 10000). Cannot be set together with `maxThroughput`." - } + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" } - }, - "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts/gremlinDatabases", - "apiVersion": "2022-08-15", - "name": "[format('{0}/{1}', parameters('databaseAccountName'), parameters('name'))]", - "tags": "[parameters('tags')]", - "properties": { - "options": "[if(contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('databaseAccountName')), '2022-08-15').capabilities, createObject('name', 'EnableServerless')), createObject(), createObject('autoscaleSettings', if(equals(parameters('throughput'), -1), createObject('maxThroughput', parameters('maxThroughput')), null()), 'throughput', if(not(equals(parameters('throughput'), -1)), parameters('throughput'), null())))]", - "resource": { - "id": "[parameters('name')]" - } - } - }, - { - "copy": { - "name": "gremlinDatabase_gremlinGraphs", - "count": "[length(parameters('graphs'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}-graph-{2}', deployment().name, parameters('name'), parameters('graphs')[copyIndex()].name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[parameters('graphs')[copyIndex()].name]" - }, - "gremlinDatabaseName": { - "value": "[parameters('name')]" - }, - "databaseAccountName": { - "value": "[parameters('databaseAccountName')]" - }, - "automaticIndexing": { - "value": "[coalesce(tryGet(parameters('graphs')[copyIndex()], 'automaticIndexing'), true())]" - }, - "partitionKeyPaths": "[if(not(empty(parameters('graphs')[copyIndex()].partitionKeyPaths)), createObject('value', parameters('graphs')[copyIndex()].partitionKeyPaths), createObject('value', createArray()))]" - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5271099334348231414" - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the graph." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. Tags of the Gremlin graph resource." - } - }, - "databaseAccountName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Database Account. Required if the template is used in a standalone deployment." - } - }, - "gremlinDatabaseName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Gremlin Database. Required if the template is used in a standalone deployment." - } - }, - "automaticIndexing": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Indicates if the indexing policy is automatic." - } - }, - "partitionKeyPaths": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List of paths using which data within the container can be partitioned." - } - } - }, - "resources": [ - { - "type": "Microsoft.DocumentDB/databaseAccounts/gremlinDatabases/graphs", - "apiVersion": "2022-08-15", - "name": "[format('{0}/{1}/{2}', parameters('databaseAccountName'), parameters('gremlinDatabaseName'), parameters('name'))]", - "tags": "[parameters('tags')]", - "properties": { - "resource": { - "id": "[parameters('name')]", - "indexingPolicy": { - "automatic": "[parameters('automaticIndexing')]" - }, - "partitionKey": { - "paths": "[if(not(empty(parameters('partitionKeyPaths'))), parameters('partitionKeyPaths'), null())]" - } - } - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the graph." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the graph." - }, - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases/graphs', parameters('databaseAccountName'), parameters('gremlinDatabaseName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the graph was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases', parameters('databaseAccountName'), parameters('name'))]" - ] + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "serviceBusNamespace": { + "type": "Microsoft.ServiceBus/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('skuObject').name]", + "capacity": "[tryGet(parameters('skuObject'), 'capacity')]" + }, + "identity": "[variables('identity')]", + "properties": { + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), 'Disabled', 'Enabled'))]", + "minimumTlsVersion": "[parameters('minimumTlsVersion')]", + "alternateName": "[parameters('alternateName')]", + "zoneRedundant": "[parameters('zoneRedundant')]", + "disableLocalAuth": "[parameters('disableLocalAuth')]", + "premiumMessagingPartitions": "[if(equals(parameters('skuObject').name, 'Premium'), parameters('premiumMessagingPartitions'), 0)]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createArray(createObject('identity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), null()), 'keyName', parameters('customerManagedKey').keyName, 'keyVaultUri', reference('cMKKeyVault').vaultUri, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), 'requireInfrastructureEncryption', parameters('requireInfrastructureEncryption')), null())]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "serviceBusNamespace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "serviceBusNamespace" + ] + }, + "serviceBusNamespace_diagnosticSettings": { + "copy": { + "name": "serviceBusNamespace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the Gremlin database." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Gremlin database." - }, - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts/gremlinDatabases', parameters('databaseAccountName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the Gremlin database was created in." - }, - "value": "[resourceGroup().name]" + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" } } - } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] }, - { + "serviceBusNamespace_roleAssignments": { "copy": { - "name": "databaseaccount_rbac", - "count": "[length(parameters('roleAssignments'))]" + "name": "serviceBusNamespace_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "serviceBusNamespace" + ] + }, + "serviceBusNamespace_authorizationRules": { + "copy": { + "name": "serviceBusNamespace_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-rbac-{1}', deployment().name, copyIndex())]", + "name": "[format('{0}-AuthorizationRules-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "description": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" - }, - "principals": { - "value": "[parameters('roleAssignments')[copyIndex()].principals]" - }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "principalType": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + "namespaceName": { + "value": "[parameters('name')]" }, - "resourceId": { - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" }, - "crossTenant": { - "value": "[parameters('crossTenant')]" + "rights": { + "value": "[tryGet(parameters('authorizationRules')[copyIndex()], 'rights')]" } }, "template": { @@ -23368,143 +24020,102 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11453009361404927356" - } + "version": "0.29.47.4906", + "templateHash": "16659347344675880024" + }, + "name": "Service Bus Namespace Authorization Rules", + "description": "This module deploys a Service Bus Namespace Authorization Rule.", + "owner": "Azure/module-maintainers" }, "parameters": { - "description": { + "namespaceName": { "type": "string", - "defaultValue": "", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Optional. The description of the role assignment." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." } }, - "principals": { - "type": "array", + "name": { + "type": "string", "metadata": { - "description": "Required. The IDs of the principals to assign the role to. A resourceId is required when used in a cross tenant scenario (i.e. crossTenant is true)" + "description": "Required. The name of the authorization rule." } }, - "principalType": { - "type": "string", - "defaultValue": "", + "rights": { + "type": "array", + "defaultValue": [], "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" + "Listen", + "Manage", + "Send" ], "metadata": { - "description": "Optional. The principal type of the assigned principal ID." + "description": "Optional. The rights associated with the rule." } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "resources": [ + { + "type": "Microsoft.ServiceBus/namespaces/AuthorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" } - }, - "resourceId": { + } + ], + "outputs": { + "name": { "type": "string", "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" }, - "condition": { + "resourceId": { "type": "string", - "defaultValue": "", "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" - } + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', parameters('namespaceName'), parameters('name'))]" }, - "conditionVersion": { + "resourceGroupName": { "type": "string", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "crossTenant": { - "type": "bool", - "defaultValue": false, "metadata": { - "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." - } - } - }, - "variables": { - "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Cosmos DB Account Reader Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fbdf93bf-df7d-467e-a4d2-9458aa1360c8')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "CosmosBackupOperator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'db7b14f2-5adf-42da-9f96-f2ee17bab5cb')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principals'))]" + "description": "The name of the Resource Group the authorization rule was created in." }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.DocumentDB/databaseAccounts/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.DocumentDB/databaseAccounts', last(split(parameters('resourceId'), '/'))), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principals')[copyIndex()].id]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(parameters('crossTenant'), parameters('principals')[copyIndex()].resourceId, null())]" - } + "value": "[resourceGroup().name]" } - ] + } } }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] }, - { - "condition": "[parameters('isSystemPartition')]", + "serviceBusNamespace_disasterRecoveryConfig": { + "condition": "[not(empty(parameters('disasterRecoveryConfig')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-name', deployment().name)]", + "name": "[format('{0}-DisasterRecoveryConfig', uniqueString(deployment().name, parameters('location')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "namespaceName": { + "value": "[parameters('name')]" }, "name": { - "value": "system-cosmos-endpoint" + "value": "[coalesce(tryGet(parameters('disasterRecoveryConfig'), 'name'), 'default')]" }, - "value": { - "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').documentEndpoint]" + "alternateName": { + "value": "[tryGet(parameters('disasterRecoveryConfig'), 'alternateName')]" + }, + "partnerNamespaceResourceID": { + "value": "[tryGet(parameters('disasterRecoveryConfig'), 'partnerNamespace')]" } }, "template": { @@ -23513,37 +24124,52 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } + "version": "0.29.47.4906", + "templateHash": "2437567647402328568" + }, + "name": "Service Bus Namespace Disaster Recovery Configs", + "description": "This module deploys a Service Bus Namespace Disaster Recovery Config", + "owner": "Azure/module-maintainers" }, "parameters": { - "keyVaultName": { + "namespaceName": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." } }, "name": { "type": "string", + "defaultValue": "default", "metadata": { - "description": "Required. The name of the secret." + "description": "Optional. The name of the disaster recovery config." } }, - "value": { - "type": "securestring", + "alternateName": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. Primary/Secondary eventhub namespace name, which is part of GEO DR pairing." + } + }, + "partnerNamespaceResourceID": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." } } }, "resources": [ { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "type": "Microsoft.ServiceBus/namespaces/disasterRecoveryConfigs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", "properties": { - "value": "[parameters('value')]" + "alternateName": "[parameters('alternateName')]", + "partnerNamespace": "[parameters('partnerNamespaceResourceID')]" } } ], @@ -23551,21 +24177,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the secret." + "description": "The name of the disaster recovery config." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the secret." + "description": "The Resource ID of the disaster recovery config." }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "value": "[resourceId('Microsoft.ServiceBus/namespaces/disasterRecoveryConfigs', parameters('namespaceName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the resource group the secret was created in." + "description": "The name of the Resource Group the disaster recovery config was created in." }, "value": "[resourceGroup().name]" } @@ -23573,28 +24199,28 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] }, - { - "condition": "[parameters('isSystemPartition')]", + "serviceBusNamespace_migrationConfigurations": { + "condition": "[not(empty(coalesce(parameters('migrationConfiguration'), createObject())))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-key', deployment().name)]", + "name": "[format('{0}-MigrationConfigurations', uniqueString(deployment().name, parameters('location')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "namespaceName": { + "value": "[parameters('name')]" }, - "name": { - "value": "system-cosmos-primary-key" + "postMigrationName": { + "value": "[parameters('migrationConfiguration').postMigrationName]" }, - "value": { - "value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').primaryMasterKey]" + "targetNamespaceResourceId": { + "value": "[parameters('migrationConfiguration').targetNamespace]" } }, "template": { @@ -23603,37 +24229,43 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } + "version": "0.29.47.4906", + "templateHash": "5021121087195745079" + }, + "name": "Service Bus Namespace Migration Configuration", + "description": "This module deploys a Service Bus Namespace Migration Configuration.", + "owner": "Azure/module-maintainers" }, "parameters": { - "keyVaultName": { + "namespaceName": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." } }, - "name": { + "postMigrationName": { "type": "string", "metadata": { - "description": "Required. The name of the secret." + "description": "Required. Name to access Standard Namespace after migration." } }, - "value": { - "type": "securestring", + "targetNamespaceResourceId": { + "type": "string", "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Required. Existing premium Namespace resource ID which has no entities, will be used for migration." } } }, "resources": [ { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "type": "Microsoft.ServiceBus/namespaces/migrationConfigurations", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), '$default')]", "properties": { - "value": "[parameters('value')]" + "targetNamespace": "[parameters('targetNamespaceResourceId')]", + "postMigrationName": "[parameters('postMigrationName')]" } } ], @@ -23641,21 +24273,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the secret." + "description": "The name of the migration configuration." }, - "value": "[parameters('name')]" + "value": "$default" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the secret." + "description": "The Resource ID of the migration configuration." }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "value": "[resourceId('Microsoft.ServiceBus/namespaces/migrationConfigurations', parameters('namespaceName'), '$default')]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the resource group the secret was created in." + "description": "The name of the Resource Group the migration configuration was created in." }, "value": "[resourceGroup().name]" } @@ -23663,28 +24295,37 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] }, - { - "condition": "[parameters('isSystemPartition')]", + "serviceBusNamespace_networkRuleSet": { + "condition": "[or(not(empty(parameters('networkRuleSets'))), not(empty(parameters('privateEndpoints'))))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-system-secret-connection', deployment().name)]", + "name": "[format('{0}-NetworkRuleSet', uniqueString(deployment().name, parameters('location')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "namespaceName": { + "value": "[parameters('name')]" }, - "name": { - "value": "system-cosmos-connection" + "publicNetworkAccess": { + "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), 'Disabled', 'Enabled'))]" }, - "value": { - "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').connectionStrings[0].connectionString]" + "defaultAction": { + "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'defaultAction'), 'Allow')]" + }, + "trustedServiceAccessEnabled": { + "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'trustedServiceAccessEnabled'), true())]" + }, + "ipRules": { + "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'ipRules'), createArray())]" + }, + "virtualNetworkRules": { + "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'virtualNetworkRules'), createArray())]" } }, "template": { @@ -23693,37 +24334,89 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } + "version": "0.29.47.4906", + "templateHash": "18220065019802173538" + }, + "name": "Service Bus Namespace Network Rule Sets", + "description": "This module deploys a ServiceBus Namespace Network Rule Set.", + "owner": "Azure/module-maintainers" }, "parameters": { - "keyVaultName": { + "namespaceName": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Network Rule Set. Required if the template is used in a standalone deployment." } }, - "name": { + "publicNetworkAccess": { "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], "metadata": { - "description": "Required. The name of the secret." + "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." } }, - "value": { - "type": "securestring", + "defaultAction": { + "type": "string", + "defaultValue": "Allow", + "allowedValues": [ + "Allow", + "Deny" + ], "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." + } + }, + "trustedServiceAccessEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not. Default is \"true\". It will not be set if publicNetworkAccess is \"Disabled\"." + } + }, + "virtualNetworkRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List virtual network rules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "ipRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of IpRules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." } } }, + "variables": { + "copy": [ + { + "name": "networkRules", + "count": "[length(parameters('virtualNetworkRules'))]", + "input": { + "ignoreMissingVnetServiceEndpoint": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'ignoreMissingVnetServiceEndpoint'), parameters('virtualNetworkRules')[copyIndex('networkRules')].ignoreMissingVnetServiceEndpoint, null())]", + "subnet": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'subnetResourceId'), createObject('id', parameters('virtualNetworkRules')[copyIndex('networkRules')].subnetResourceId), null())]" + } + } + ] + }, "resources": [ { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", + "type": "Microsoft.ServiceBus/namespaces/networkRuleSets", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), 'default')]", "properties": { - "value": "[parameters('value')]" + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "defaultAction": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), if(or(not(empty(parameters('ipRules'))), not(empty(parameters('virtualNetworkRules')))), 'Deny', parameters('defaultAction')), null())]", + "trustedServiceAccessEnabled": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), parameters('trustedServiceAccessEnabled'), null())]", + "ipRules": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), parameters('ipRules'), null())]", + "virtualNetworkRules": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), variables('networkRules'), null())]" } } ], @@ -23731,21 +24424,21 @@ "name": { "type": "string", "metadata": { - "description": "The name of the secret." + "description": "The name of the network rule set." }, - "value": "[parameters('name')]" + "value": "default" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the secret." + "description": "The resource ID of the network rule set." }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "value": "[resourceId('Microsoft.ServiceBus/namespaces/networkRuleSets', parameters('namespaceName'), 'default')]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the resource group the secret was created in." + "description": "The name of the resource group the network rule set was created in." }, "value": "[resourceGroup().name]" } @@ -23753,269 +24446,580 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] }, - { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databaseEndpointSecretName'))))]", + "serviceBusNamespace_queues": { + "copy": { + "name": "serviceBusNamespace_queues", + "count": "[length(coalesce(parameters('queues'), createArray()))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-name', deployment().name)]", + "name": "[format('{0}-Queue-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" + "namespaceName": { + "value": "[parameters('name')]" }, "name": { - "value": "[parameters('databaseEndpointSecretName')]" + "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]" }, - "value": { - "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').documentEndpoint]" + "autoDeleteOnIdle": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'autoDeleteOnIdle')]" + }, + "forwardDeadLetteredMessagesTo": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'forwardDeadLetteredMessagesTo')]" + }, + "forwardTo": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'forwardTo')]" + }, + "maxMessageSizeInKilobytes": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxMessageSizeInKilobytes')]" + }, + "authorizationRules": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'authorizationRules')]" + }, + "deadLetteringOnMessageExpiration": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'deadLetteringOnMessageExpiration')]" + }, + "defaultMessageTimeToLive": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'defaultMessageTimeToLive')]" + }, + "duplicateDetectionHistoryTimeWindow": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow')]" + }, + "enableBatchedOperations": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enableBatchedOperations')]" + }, + "enableExpress": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enableExpress')]" + }, + "enablePartitioning": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enablePartitioning')]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "lockDuration": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'lockDuration')]" + }, + "maxDeliveryCount": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxDeliveryCount')]" + }, + "maxSizeInMegabytes": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxSizeInMegabytes')]" + }, + "requiresDuplicateDetection": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'requiresDuplicateDetection')]" + }, + "requiresSession": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'requiresSession')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "status": { + "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'status')]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" + "version": "0.29.47.4906", + "templateHash": "12442268068778335924" + }, + "name": "Service Bus Namespace Queue", + "description": "This module deploys a Service Bus Namespace Queue.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true } }, "parameters": { - "keyVaultName": { + "namespaceName": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." } }, "name": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Required. The name of the secret." + "description": "Required. Name of the Service Bus Queue." } }, - "value": { - "type": "securestring", - "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." - } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" - } - } - ], - "outputs": { - "name": { + "autoDeleteOnIdle": { "type": "string", + "nullable": true, "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" + "description": "Optional. ISO 8061 timeSpan idle interval after which the queue is automatically deleted. The minimum duration is 5 minutes (PT5M)." + } }, - "resourceId": { + "forwardDeadLetteredMessagesTo": { "type": "string", + "nullable": true, "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "description": "Optional. Queue/Topic name to forward the Dead Letter message." + } }, - "resourceGroupName": { + "forwardTo": { "type": "string", + "nullable": true, "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - ] - }, - { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databasePrimaryKeySecretName'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-key', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "[parameters('databasePrimaryKeySecretName')]" - }, - "value": { - "value": "[listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').primaryMasterKey]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { + "description": "Optional. Queue/Topic name to forward the messages." + } + }, + "lockDuration": { "type": "string", + "defaultValue": "PT1M", "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." } }, - "name": { - "type": "string", + "maxSizeInMegabytes": { + "type": "int", + "defaultValue": 1024, "metadata": { - "description": "Required. The name of the secret." + "description": "Optional. The maximum size of the queue in megabytes, which is the size of memory allocated for the queue. Default is 1024." } }, - "value": { - "type": "securestring", + "requiresDuplicateDetection": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. A value indicating if this queue requires duplicate detection." } - } - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" + }, + "requiresSession": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether the queue supports the concept of sessions." } - } - ], - "outputs": { - "name": { + }, + "defaultMessageTimeToLive": { "type": "string", + "defaultValue": "P14D", "metadata": { - "description": "The name of the secret." - }, - "value": "[parameters('name')]" + "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." + } }, - "resourceId": { - "type": "string", + "deadLetteringOnMessageExpiration": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "The resource ID of the secret." - }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "description": "Optional. A value that indicates whether this queue has dead letter support when a message expires." + } }, - "resourceGroupName": { + "enableBatchedOperations": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Value that indicates whether server-side batched operations are enabled." + } + }, + "duplicateDetectionHistoryTimeWindow": { "type": "string", + "defaultValue": "PT10M", "metadata": { - "description": "The name of the resource group the secret was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - ] - }, - { - "condition": "[and(not(empty(parameters('keyVaultName'))), not(empty(parameters('databaseConnectionStringSecretName'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secret-connection', deployment().name)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "name": { - "value": "[parameters('databaseConnectionStringSecretName')]" - }, - "value": { - "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15').connectionStrings[0].connectionString]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4749529301937497394" - } - }, - "parameters": { - "keyVaultName": { - "type": "string", + "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "maxDeliveryCount": { + "type": "int", + "defaultValue": 10, "metadata": { - "description": "Conditional. The name of the parent key vault. Required if the template is used in a standalone deployment." + "description": "Optional. The maximum delivery count. A message is automatically deadlettered after this number of deliveries. default value is 10." } }, - "name": { + "maxMessageSizeInKilobytes": { + "type": "int", + "defaultValue": 1024, + "metadata": { + "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the queue. This property is only used in Premium today and default is 1024." + } + }, + "status": { "type": "string", + "defaultValue": "Active", + "allowedValues": [ + "Active", + "Disabled", + "Restoring", + "SendDisabled", + "ReceiveDisabled", + "Creating", + "Deleting", + "Renaming", + "Unknown" + ], "metadata": { - "description": "Required. The name of the secret." + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." } }, - "value": { - "type": "securestring", + "enablePartitioning": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Required. The value of the secret. NOTE: \"value\" will never be returned from the service, as APIs using this model are is intended for internal use in ARM deployments. Users should use the data-plane REST service for interaction with vault secrets." + "description": "Optional. A value that indicates whether the queue is to be partitioned across multiple message brokers." + } + }, + "enableExpress": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether Express Entities are enabled. An express queue holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." + } + }, + "authorizationRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Authorization Rules for the Service Bus Queue." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." } } }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('name'))]", - "properties": { - "value": "[parameters('value')]" + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" } + ], + "builtInRoleNames": { + "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", + "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", + "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" } - ], + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.ServiceBus/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "queue": { + "type": "Microsoft.ServiceBus/namespaces/queues", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "autoDeleteOnIdle": "[if(not(empty(parameters('autoDeleteOnIdle'))), parameters('autoDeleteOnIdle'), null())]", + "defaultMessageTimeToLive": "[parameters('defaultMessageTimeToLive')]", + "deadLetteringOnMessageExpiration": "[parameters('deadLetteringOnMessageExpiration')]", + "duplicateDetectionHistoryTimeWindow": "[parameters('duplicateDetectionHistoryTimeWindow')]", + "enableBatchedOperations": "[parameters('enableBatchedOperations')]", + "enableExpress": "[parameters('enableExpress')]", + "enablePartitioning": "[parameters('enablePartitioning')]", + "forwardDeadLetteredMessagesTo": "[if(not(empty(parameters('forwardDeadLetteredMessagesTo'))), parameters('forwardDeadLetteredMessagesTo'), null())]", + "forwardTo": "[if(not(empty(parameters('forwardTo'))), parameters('forwardTo'), null())]", + "lockDuration": "[parameters('lockDuration')]", + "maxDeliveryCount": "[parameters('maxDeliveryCount')]", + "maxMessageSizeInKilobytes": "[if(equals(reference('namespace', '2022-10-01-preview', 'full').sku.name, 'Premium'), parameters('maxMessageSizeInKilobytes'), null())]", + "maxSizeInMegabytes": "[parameters('maxSizeInMegabytes')]", + "requiresDuplicateDetection": "[parameters('requiresDuplicateDetection')]", + "requiresSession": "[parameters('requiresSession')]", + "status": "[parameters('status')]" + }, + "dependsOn": [ + "namespace" + ] + }, + "queue_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/queues/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "queue" + ] + }, + "queue_roleAssignments": { + "copy": { + "name": "queue_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/queues/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces/queues', parameters('namespaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "queue" + ] + }, + "queue_authorizationRules": { + "copy": { + "name": "queue_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "queueName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" + }, + "rights": { + "value": "[coalesce(tryGet(parameters('authorizationRules')[copyIndex()], 'rights'), createArray())]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "13378473188831787359" + }, + "name": "Service Bus Namespace Queue Authorization Rules", + "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the service bus namepace queue." + } + }, + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." + } + }, + "queueName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Service Bus Namespace Queue. Required if the template is used in a standalone deployment." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.ServiceBus/namespaces/queues/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('queueName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces/queues/authorizationRules', parameters('namespaceName'), parameters('queueName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "queue" + ] + } + }, "outputs": { "name": { "type": "string", "metadata": { - "description": "The name of the secret." + "description": "The name of the deployed queue." }, "value": "[parameters('name')]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource ID of the secret." + "description": "The resource ID of the deployed queue." }, - "value": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('name'))]" + "value": "[resourceId('Microsoft.ServiceBus/namespaces/queues', parameters('namespaceName'), parameters('name'))]" }, "resourceGroupName": { "type": "string", "metadata": { - "description": "The name of the resource group the secret was created in." + "description": "The resource group of the deployed queue." }, "value": "[resourceGroup().name]" } @@ -24023,5845 +25027,4891 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" + "serviceBusNamespace" ] - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the database account." - }, - "value": "[if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))]" - }, - "id": { - "type": "string", - "metadata": { - "description": "The resource ID of the database account." - }, - "value": "[resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name')))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the database account was created in." - }, - "value": "[resourceGroup().name]" - }, - "systemAssignedPrincipalId": { - "type": "string", - "metadata": { - "description": "The principal ID of the system assigned identity." - }, - "value": "[if(and(parameters('systemAssignedIdentity'), contains(reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').identity, 'principalId')), reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').identity.principalId, '')]" }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." + "serviceBusNamespace_topics": { + "copy": { + "name": "serviceBusNamespace_topics", + "count": "[length(coalesce(parameters('topics'), createArray()))]" }, - "value": "[reference(resourceId('Microsoft.DocumentDB/databaseAccounts', if(greater(length(variables('name')), 26), substring(variables('name'), 0, 26), variables('name'))), '2022-08-15', 'full').location]" - } - } - } - } - }, - "partitionDbEndpoint": { - "copy": { - "name": "partitionDbEndpoint", - "count": "[length(parameters('partitions'))]" - }, - "condition": "[parameters('enablePrivateLink')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-cosmos-db-endpoint-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "resourceName": { - "value": "[reference(format('partitionDb[{0}]', copyIndex())).outputs.name.value]" - }, - "subnetResourceId": { - "value": "[parameters('subnetId')]" - }, - "serviceResourceId": { - "value": "[reference(format('partitionDb[{0}]', copyIndex())).outputs.id.value]" - }, - "groupIds": { - "value": [ - "sql" - ] - }, - "privateDnsZoneGroup": { - "value": { - "privateDNSResourceIds": [ - "[parameters('cosmosDNSZoneId')]" - ] - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3640359773342242706" - } - }, - "parameters": { - "resourceName": { - "type": "string", - "metadata": { - "description": "Required. Name of the private endpoint resource to create." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "serviceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the resource that needs to be connected to the network." - } - }, - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." - } - }, - "applicationSecurityGroups": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "ipConfigurations": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all Resources." - } - }, - "crossTenant": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." - } - }, - "roleAssignments": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Array of objects that describe RBAC permissions, format { roleDefinitionResourceId (string), principalId (string), principalType (enum), enabled (bool) }. Ref: https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Tags." - } - }, - "lock": { - "type": "string", - "defaultValue": "NotSpecified", - "allowedValues": [ - "CanNotDelete", - "NotSpecified", - "ReadOnly" - ], - "metadata": { - "description": "Optional. Specify the type of lock." - } - }, - "customDnsConfigs": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "manualPrivateLinkServiceConnections": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Manual PrivateLink Service Connections." - } - } - }, - "variables": { - "name": "[format('pep-{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]" - }, - "resources": [ - { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2022-05-01", - "name": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "privateLinkServiceConnections": [ - { - "name": "[parameters('resourceName')]", - "properties": { - "privateLinkServiceId": "[parameters('serviceResourceId')]", - "groupIds": "[parameters('groupIds')]" - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - } - }, - { - "condition": "[not(equals(parameters('lock'), 'NotSpecified'))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2017-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", - "name": "[format('{0}-{1}-lock', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')), parameters('lock'))]", - "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" - ] - }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-{1}', deployment().name, if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]", + "name": "[format('{0}-Topic-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "namespaceName": { + "value": "[parameters('name')]" }, - "privateEndpointName": { - "value": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3963716407284218965" - } + "name": { + "value": "[coalesce(parameters('topics'), createArray())[copyIndex()].name]" }, - "parameters": { - "privateEndpointName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." - } - }, - "privateDNSResourceIds": { - "type": "array", - "minLength": 1, - "maxLength": 5, - "metadata": { - "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." - } - }, - "resourceName": { - "type": "string", - "defaultValue": "default", - "metadata": { - "description": "Optional. The name of the private DNS zone group." - } - } + "authorizationRules": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'authorizationRules')]" }, - "variables": { - "copy": [ - { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", - "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", - "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" - } - } - } - ] + "autoDeleteOnIdle": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'autoDeleteOnIdle')]" }, - "resources": [ - { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2022-05-01", - "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('resourceName'))]", - "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint DNS zone group was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint DNS zone group." - }, - "value": "[parameters('resourceName')]" - }, - "id": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint DNS zone group." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('resourceName'))]" - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-rbac-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'description'), '')]" + "defaultMessageTimeToLive": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'defaultMessageTimeToLive')]" }, - "principals": { - "value": "[parameters('roleAssignments')[copyIndex()].principals]" + "duplicateDetectionHistoryTimeWindow": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow')]" }, - "principalType": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'principalType'), '')]" + "enableBatchedOperations": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enableBatchedOperations')]" }, - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" + "enableExpress": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enableExpress')]" }, - "condition": { - "value": "[coalesce(tryGet(parameters('roleAssignments')[copyIndex()], 'condition'), '')]" + "enablePartitioning": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enablePartitioning')]" }, - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "crossTenant": { - "value": "[parameters('crossTenant')]" + "maxMessageSizeInKilobytes": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'maxMessageSizeInKilobytes')]" + }, + "requiresDuplicateDetection": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'requiresDuplicateDetection')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "status": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'status')]" + }, + "supportOrdering": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'supportOrdering')]" + }, + "subscriptions": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'subscriptions')]" + }, + "maxSizeInMegabytes": { + "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'maxSizeInMegabytes')]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17487462929719619113" + "version": "0.29.47.4906", + "templateHash": "782028791267114581" + }, + "name": "Service Bus Namespace Topic", + "description": "This module deploys a Service Bus Namespace Topic.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "subscriptionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the service bus namespace topic subscription." + } + }, + "autoDeleteOnIdle": { + "type": "string", + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes." + } + }, + "clientAffineProperties": { + "type": "object", + "properties": { + "clientId": { + "type": "string", + "metadata": { + "description": "Required. Indicates the Client ID of the application that created the client-affine subscription." + } + }, + "isDurable": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is durable or not." + } + }, + "isShared": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is shared or not." + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The properties that are associated with a subscription that is client-affine." + } + }, + "deadLetteringOnMessageExpiration": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "deadLetteringOnFilterEvaluationExceptions": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "defaultMessageTimeToLive": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." + } + }, + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "enableBatchedOperations": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether server-side batched operations are enabled." + } + }, + "forwardDeadLetteredMessagesTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "forwardTo": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "isClientAffine": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "lockDuration": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." + } + }, + "maxDeliveryCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." + } + }, + "requiresSession": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "status": { + "type": "string", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "nullable": true, + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." + } + } + } + }, + "nullable": true } }, "parameters": { - "roleDefinitionIdOrName": { + "namespaceName": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Topic. Required if the template is used in a standalone deployment." } }, - "resourceId": { + "name": { "type": "string", + "minLength": 1, + "maxLength": 260, "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." + "description": "Required. Name of the Service Bus Topic." } }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], + "maxSizeInMegabytes": { + "type": "int", + "defaultValue": 1024, "metadata": { - "description": "Optional. The principal type of the assigned principal ID." + "description": "Optional. The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. Default is 1024." } }, - "description": { - "type": "string", - "defaultValue": "", + "requiresDuplicateDetection": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "Optional. The description of the role assignment." + "description": "Optional. A value indicating if this topic requires duplicate detection." } }, - "condition": { + "defaultMessageTimeToLive": { "type": "string", - "defaultValue": "", + "defaultValue": "P14D", "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." } }, - "conditionVersion": { - "type": "string", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], + "enableBatchedOperations": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "Optional. Version of the condition." + "description": "Optional. Value that indicates whether server-side batched operations are enabled." } }, - "crossTenant": { + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "defaultValue": "PT10M", + "metadata": { + "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "maxMessageSizeInKilobytes": { + "type": "int", + "defaultValue": 1024, + "metadata": { + "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the topic. This property is only used in Premium today and default is 1024. This property is only used if the `service-bus/namespace` sku is Premium." + } + }, + "supportOrdering": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Indicates if the module is used in a cross tenant scenario. If true, a resourceId must be provided in the role assignment's principal object." + "description": "Optional. Value that indicates whether the topic supports ordering." } }, - "principals": { + "autoDeleteOnIdle": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the topic is automatically deleted. The minimum duration is 5 minutes." + } + }, + "status": { + "type": "string", + "defaultValue": "Active", + "allowedValues": [ + "Active", + "Disabled", + "Restoring", + "SendDisabled", + "ReceiveDisabled", + "Creating", + "Deleting", + "Renaming", + "Unknown" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." + } + }, + "enablePartitioning": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether the topic is to be partitioned across multiple message brokers." + } + }, + "enableExpress": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether Express Entities are enabled. An express topic holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." + } + }, + "authorizationRules": { + "type": "array", + "defaultValue": [ + { + "name": "RootManageSharedAccessKey", + "properties": { + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + } + ], + "metadata": { + "description": "Optional. Authorization Rules for the Service Bus Topic." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "subscriptions": { "type": "array", + "defaultValue": [], "metadata": { - "description": "Required. The IDs of the principals to assign the role to. A resourceId is required when used in a cross tenant scenario (i.e. crossTenant is true)" + "description": "Optional. The subscriptions of the topic." } } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", + "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", + "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]" + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" } }, - "resources": [ - { + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.ServiceBus/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "topic": { + "type": "Microsoft.ServiceBus/namespaces/topics", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": "[union(createObject('autoDeleteOnIdle', parameters('autoDeleteOnIdle'), 'defaultMessageTimeToLive', parameters('defaultMessageTimeToLive'), 'duplicateDetectionHistoryTimeWindow', parameters('duplicateDetectionHistoryTimeWindow'), 'enableBatchedOperations', parameters('enableBatchedOperations'), 'enablePartitioning', parameters('enablePartitioning'), 'requiresDuplicateDetection', parameters('requiresDuplicateDetection'), 'status', parameters('status'), 'supportOrdering', parameters('supportOrdering'), 'maxSizeInMegabytes', parameters('maxSizeInMegabytes')), if(equals(reference('namespace', '2022-10-01-preview', 'full').sku.name, 'Premium'), createObject('enableExpress', parameters('enableExpress'), 'maxMessageSizeInKilobytes', parameters('maxMessageSizeInKilobytes')), createObject()))]", + "dependsOn": [ + "namespace" + ] + }, + "topic_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/topics/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "topic" + ] + }, + "topic_roleAssignments": { "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principals'))]" + "name": "topic_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principals')[copyIndex()].id, parameters('roleDefinitionIdOrName'))]", + "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/topics/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces/topics', parameters('namespaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[coalesce(tryGet(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principals')[copyIndex()].id]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(parameters('crossTenant'), parameters('principals')[copyIndex()].resourceId, null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" - ] - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint." - }, - "value": "[if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))]" - }, - "id": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name')))]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', if(greater(length(variables('name')), 24), substring(variables('name'), 0, 24), variables('name'))), '2022-05-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "[format('partitionDb[{0}]', copyIndex())]", - "[format('partitionDb[{0}]', copyIndex())]" - ] - }, - "partitonNamespace": { - "copy": { - "name": "partitonNamespace", - "count": "[length(parameters('partitions'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-service-bus-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[format('{0}{1}', replace(format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6)), '-', ''), uniqueString(resourceGroup().id, format('data{0}{1}', copyIndex(), substring(uniqueString(parameters('partitions')[copyIndex()].name), 0, 6))))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName, 'partition', parameters('partitions')[copyIndex()].name, 'purpose', 'data'))]" - }, - "diagnosticSettings": { - "value": [ - { - "workspaceResourceId": "[parameters('workspaceResourceId')]" - } - ] - }, - "skuObject": { - "value": { - "name": "[variables('partitionLayerConfig').servicebus.sku]", - "capacity": "[if(equals(variables('partitionLayerConfig').servicebus.sku, 'Premium'), 2, null())]" - } - }, - "zoneRedundant": "[if(equals(variables('partitionLayerConfig').servicebus.sku, 'Premium'), createObject('value', true()), createObject('value', false()))]", - "disableLocalAuth": { - "value": false - }, - "authorizationRules": { - "value": [ - { - "name": "RootManageSharedAccessKey", - "rights": [ - "Listen", - "Manage", - "Send" - ] - } - ] - }, - "topics": { - "copy": [ - { - "name": "value", - "count": "[length(variables('partitionLayerConfig').servicebus.topics)]", - "input": "[createObject('name', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].name, 'maxSizeInMegabytes', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].maxSizeInMegabytes, 'authorizationRules', createArray(createObject('name', 'RootManageSharedAccessKey', 'rights', createArray('Listen', 'Manage', 'Send'))), 'subscriptions', variables('partitionLayerConfig').servicebus.topics[copyIndex('value')].subscriptions)]" - } - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "16891238855778423574" - }, - "name": "Service Bus Namespaces", - "description": "This module deploys a Service Bus Namespace.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "managedIdentitiesType": { - "type": "object", - "properties": { - "systemAssigned": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enables system assigned managed identity on the resource." - } - }, - "userAssignedResourcesIds": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Optional. The resource ID(s) to assign to the resource." - } - } - }, - "nullable": true - }, - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - }, - "privateEndpointType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private endpoint." - } - }, - "location": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The location to deploy the private endpoint to." - } - }, - "privateLinkServiceConnectionName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private link connection to create." - } - }, - "service": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "privateDnsZoneGroup": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the Private DNS Zone Group." - } + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, - "privateDnsZoneGroupConfigs": { - "type": "array", - "items": { - "type": "object", - "properties": { + "dependsOn": [ + "topic" + ] + }, + "topic_authorizationRules": { + "copy": { + "name": "topic_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "topicName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" + }, + "rights": "[if(contains(parameters('authorizationRules')[copyIndex()], 'rights'), createObject('value', parameters('authorizationRules')[copyIndex()].rights), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "6843568331497160185" + }, + "name": "Service Bus Namespace Topic Authorization Rules", + "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group config." + "description": "Required. The name of the service bus namespace topic." } }, - "privateDnsZoneResourceId": { + "namespaceName": { "type": "string", "metadata": { - "description": "Required. The resource id of the private DNS zone." + "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." } + }, + "topicName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent Service Bus Namespace Topic. Required if the template is used in a standalone deployment." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.ServiceBus/namespaces/topics/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('topicName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/authorizationRules', parameters('namespaceName'), parameters('topicName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" } } - }, - "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } - } + }, + "dependsOn": [ + "topic" + ] }, - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone group to configure for the private endpoint." - } - }, - "isManualConnection": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. If Manual Private Link Connection is required." - } - }, - "manualConnectionRequestMessage": { - "type": "string", - "nullable": true, - "maxLength": 140, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." - } - }, - "customDnsConfigs": { - "type": "array", - "items": { - "type": "object", + "topic_subscription": { + "copy": { + "name": "topic_subscription", + "count": "[length(coalesce(parameters('subscriptions'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-subscription-{1}', deployment().name, copyIndex())]", "properties": { - "fqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } + "expressionEvaluationOptions": { + "scope": "inner" }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('subscriptions'), createArray())[copyIndex()].name]" }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "ipConfigurations": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "topicName": { + "value": "[parameters('name')]" + }, + "autoDeleteOnIdle": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'autoDeleteOnIdle'), 'PT1H')]" + }, + "defaultMessageTimeToLive": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'defaultMessageTimeToLive'), 'P14D')]" + }, + "duplicateDetectionHistoryTimeWindow": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow'), 'PT10M')]" + }, + "enableBatchedOperations": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'enableBatchedOperations'), true())]" + }, + "clientAffineProperties": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'clientAffineProperties'), createObject())]" + }, + "deadLetteringOnFilterEvaluationExceptions": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'deadLetteringOnFilterEvaluationExceptions'), true())]" + }, + "deadLetteringOnMessageExpiration": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'deadLetteringOnMessageExpiration'), false())]" + }, + "forwardDeadLetteredMessagesTo": { + "value": "[tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'forwardDeadLetteredMessagesTo')]" + }, + "forwardTo": { + "value": "[tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'forwardTo')]" + }, + "isClientAffine": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'isClientAffine'), false())]" + }, + "lockDuration": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'lockDuration'), 'PT1M')]" + }, + "maxDeliveryCount": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'maxDeliveryCount'), 10)]" + }, + "requiresSession": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'requiresSession'), false())]" + }, + "status": { + "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'status'), 'Active')]" } }, - "properties": { - "type": "object", - "properties": { - "groupId": { + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "13559505347925945415" + }, + "name": "Service Bus Namespace Topic Subscription", + "description": "This module deploys a Service Bus Namespace Topic Subscription.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The name of the service bus namespace topic subscription." } }, - "memberName": { + "namespaceName": { "type": "string", "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." } }, - "privateIPAddress": { + "topicName": { "type": "string", "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." + "description": "Conditional. The name of the parent Service Bus Namespace Topic. Required if the template is used in a standalone deployment." + } + }, + "autoDeleteOnIdle": { + "type": "string", + "defaultValue": "PT1H", + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the subscription is automatically deleted. The minimum duration is 5 minutes." + } + }, + "clientAffineProperties": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The properties that are associated with a subscription that is client-affine." + } + }, + "deadLetteringOnFilterEvaluationExceptions": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "deadLetteringOnMessageExpiration": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." + } + }, + "defaultMessageTimeToLive": { + "type": "string", + "defaultValue": "P10675199DT2H48M5.4775807S", + "metadata": { + "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." + } + }, + "duplicateDetectionHistoryTimeWindow": { + "type": "string", + "defaultValue": "PT10M", + "metadata": { + "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." + } + }, + "enableBatchedOperations": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. A value that indicates whether server-side batched operations are enabled." + } + }, + "forwardDeadLetteredMessagesTo": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "forwardTo": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." + } + }, + "isClientAffine": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "lockDuration": { + "type": "string", + "defaultValue": "PT1M", + "metadata": { + "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." + } + }, + "maxDeliveryCount": { + "type": "int", + "defaultValue": 10, + "metadata": { + "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." + } + }, + "requiresSession": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether the subscription supports the concept of session." + } + }, + "status": { + "type": "string", + "defaultValue": "Active", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the status of a messaging entity." } } }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." + "resources": [ + { + "type": "Microsoft.ServiceBus/namespaces/topics/subscriptions", + "apiVersion": "2021-11-01", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('topicName'), parameters('name'))]", + "properties": { + "autoDeleteOnIdle": "[parameters('autoDeleteOnIdle')]", + "clientAffineProperties": "[parameters('clientAffineProperties')]", + "deadLetteringOnFilterEvaluationExceptions": "[parameters('deadLetteringOnFilterEvaluationExceptions')]", + "deadLetteringOnMessageExpiration": "[parameters('deadLetteringOnMessageExpiration')]", + "defaultMessageTimeToLive": "[parameters('defaultMessageTimeToLive')]", + "duplicateDetectionHistoryTimeWindow": "[parameters('duplicateDetectionHistoryTimeWindow')]", + "enableBatchedOperations": "[parameters('enableBatchedOperations')]", + "forwardDeadLetteredMessagesTo": "[parameters('forwardDeadLetteredMessagesTo')]", + "forwardTo": "[if(not(empty(parameters('forwardTo'))), parameters('forwardTo'), null())]", + "isClientAffine": "[parameters('isClientAffine')]", + "lockDuration": "[parameters('lockDuration')]", + "maxDeliveryCount": "[parameters('maxDeliveryCount')]", + "requiresSession": "[parameters('requiresSession')]", + "status": "[parameters('status')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the topic subscription." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The Resource ID of the topic subscription." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/subscriptions', parameters('namespaceName'), parameters('topicName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Resource Group the topic subscription was created in." + }, + "value": "[resourceGroup().name]" + } } } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + }, + "dependsOn": [ + "namespace", + "topic" + ] } }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "items": { - "type": "string" + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed topic." + }, + "value": "[parameters('name')]" }, - "nullable": true, - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed topic." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed topic." + }, + "value": "[resourceGroup().name]" } + } + } + }, + "dependsOn": [ + "serviceBusNamespace" + ] + }, + "serviceBusNamespace_privateEndpoints": { + "copy": { + "name": "serviceBusNamespace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-serviceBusNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex()))]" }, - "customNetworkInterfaceName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" }, "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. Specify the type of lock." - } + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" }, "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" }, - "resourceGroupName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." - } + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" } - } - }, - "nullable": true - }, - "diagnosticSettingType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of diagnostic setting." - } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" }, - "logCategoriesAndGroups": { - "type": "array", - "items": { + "definitions": { + "privateDnsZoneGroupType": { "type": "object", "properties": { - "category": { + "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + "description": "Optional. The name of the Private DNS Zone Group." } }, - "categoryGroup": { + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + "description": "Optional. Specify the name of lock." } }, - "enabled": { - "type": "bool", + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], "nullable": true, "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." + "description": "Optional. Specify the type of lock." } } - } + }, + "nullable": true }, - "nullable": true, - "metadata": { - "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." - } - }, - "metricCategories": { - "type": "array", - "items": { + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + }, + "privateDnsZoneGroupConfigType": { "type": "object", "properties": { - "category": { + "name": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + "description": "Optional. The name of the private DNS zone group config." } }, - "enabled": { - "type": "bool", - "nullable": true, + "privateDnsZoneResourceId": { + "type": "string", "metadata": { - "description": "Optional. Enable or disable the category explicitly. Default is `true`." + "description": "Required. The resource id of the private DNS zone." } } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } } - }, - "nullable": true, - "metadata": { - "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." - } - }, - "logAnalyticsDestinationType": { - "type": "string", - "allowedValues": [ - "AzureDiagnostics", - "Dedicated" - ], - "nullable": true, - "metadata": { - "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." - } - }, - "workspaceResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." - } - }, - "storageAccountResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." } }, - "eventHubAuthorizationRuleResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } } }, - "eventHubName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" } }, - "marketplacePartnerResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." - } - } - } - }, - "nullable": true - }, - "customerManagedKeyType": { - "type": "object", - "properties": { - "keyVaultResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." - } - }, - "keyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the customer managed key to use for encryption." - } - }, - "keyVersion": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." - } - }, - "userAssignedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." - } - } - }, - "nullable": true - }, - "skuType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "allowedValues": [ - "Basic", - "Premium", - "Standard" - ], - "metadata": { - "description": "Required. Name of this SKU. - Basic, Standard, Premium." - } - }, - "capacity": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. The specified messaging units for the tier. Only used for Premium Sku tier." - } - } - } - }, - "authorizationRuleType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the authorization rule." - } - }, - "rights": { - "type": "array", - "allowedValues": [ - "Listen", - "Manage", - "Send" - ], - "nullable": true, - "metadata": { - "description": "Optional. The rights associated with the rule." - } - } - } - } - }, - "disasterRecoveryConfigType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the disaster recovery config." - } - }, - "alternateName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Primary/Secondary eventhub namespace name, which is part of GEO DR pairing." - } - }, - "partnerNamespace": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." - } - } - }, - "nullable": true - }, - "migrationConfigurationsType": { - "type": "object", - "properties": { - "postMigrationName": { - "type": "string", - "metadata": { - "description": "Required. Name to access Standard Namespace after migration." - } - }, - "targetNamespace": { - "type": "string", - "metadata": { - "description": "Required. Existing premium Namespace resource ID which has no entities, will be used for migration." - } - } - }, - "nullable": true - }, - "networkRuleSetType": { - "type": "object", - "properties": { - "publicNetworkAccess": { - "type": "string", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "nullable": true, - "metadata": { - "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." - } - }, - "defaultAction": { - "type": "string", - "allowedValues": [ - "Allow", - "Deny" - ], - "nullable": true, - "metadata": { - "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." - } - }, - "trustedServiceAccessEnabled": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not. Default is \"true\". It will not be set if publicNetworkAccess is \"Disabled\"." - } - }, - "ipRules": { - "type": "array", - "items": { - "type": "object", - "properties": { - "action": { - "type": "string", - "allowedValues": [ - "Allow", - "Deny" + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } ], - "metadata": { - "description": "Required. The IP filter action." + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, - "ipMask": { - "type": "string", - "metadata": { - "description": "Required. The IP mask." + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDnsZoneConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", + "input": { + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" + } + } + } + ] + }, + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } } - } + }, + "dependsOn": [ + "privateEndpoint" + ] } }, - "nullable": true, - "metadata": { - "description": "Optional. List of IpRules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." - } - }, - "virtualNetworkRules": { - "type": "array", - "items": { - "type": "object", - "properties": { - "ignoreMissingVnetServiceEndpoint": { - "type": "bool", - "metadata": { - "description": "Required. The virtual network rule name." - } + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. The ID of the subnet." - } - } + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" } - }, - "nullable": true, - "metadata": { - "description": "Optional. List virtual network rules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." } } }, - "nullable": true + "dependsOn": [ + "serviceBusNamespace" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployed service bus namespace." + }, + "value": "[resourceId('Microsoft.ServiceBus/namespaces', parameters('name'))]" }, - "queueType": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group of the deployed service bus namespace." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployed service bus namespace." + }, + "value": "[parameters('name')]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('serviceBusNamespace', '2022-10-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('serviceBusNamespace', '2022-10-01-preview', 'full').location]" + }, + "privateEndpoints": { "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the queue." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8061 timeSpan idle interval after which the queue is automatically deleted. The minimum duration is 5 minutes (PT5M)." - } - }, - "forwardDeadLetteredMessagesTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Queue/Topic name to forward the Dead Letter message." - } - }, - "forwardTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Queue/Topic name to forward the messages." - } - }, - "maxMessageSizeInKilobytes": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the queue. This property is only used in Premium today and default is 1024." - } - }, - "authorizationRules": { - "$ref": "#/definitions/authorizationRuleType", - "nullable": true, - "metadata": { - "description": "Optional. Authorization Rules for the Service Bus Queue." - } - }, - "deadLetteringOnMessageExpiration": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether this queue has dead letter support when a message expires." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "enableBatchedOperations": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Value that indicates whether server-side batched operations are enabled." - } - }, - "enableExpress": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether Express Entities are enabled. An express queue holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." - } - }, - "enablePartitioning": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the queue is to be partitioned across multiple message brokers." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "nullable": true, - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "lockDuration": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." - } - }, - "maxDeliveryCount": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. The maximum delivery count. A message is automatically deadlettered after this number of deliveries. default value is 10." - } - }, - "maxSizeInMegabytes": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. The maximum size of the queue in megabytes, which is the size of memory allocated for the queue. Default is 1024." - } - }, - "requiresDuplicateDetection": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value indicating if this queue requires duplicate detection." - } - }, - "requiresSession": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the queue supports the concept of sessions." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "nullable": true, - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "status": { - "type": "string", - "allowedValues": [ - "Active", - "Creating", - "Deleting", - "Disabled", - "ReceiveDisabled", - "Renaming", - "Restoring", - "SendDisabled", - "Unknown" - ], - "nullable": true, - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - } - } + "metadata": { + "description": "The private endpoints of the service bus namespace." }, - "nullable": true - }, - "topicType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the topic." - } - }, - "authorizationRules": { - "$ref": "#/definitions/authorizationRuleType", - "nullable": true, - "metadata": { - "description": "Optional. Authorization Rules for the Service Bus Topic." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the topic is automatically deleted. The minimum duration is 5 minutes." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "enableBatchedOperations": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Value that indicates whether server-side batched operations are enabled." - } - }, - "enableExpress": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether Express Entities are enabled. An express topic holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." - } - }, - "enablePartitioning": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the topic is to be partitioned across multiple message brokers." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "nullable": true, - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "maxMessageSizeInKilobytes": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the topic. This property is only used in Premium today and default is 1024." - } - }, - "maxSizeInMegabytes": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. Default is 1024." - } - }, - "requiresDuplicateDetection": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value indicating if this topic requires duplicate detection." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "nullable": true, - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "status": { - "type": "string", - "allowedValues": [ - "Active", - "Creating", - "Deleting", - "Disabled", - "ReceiveDisabled", - "Renaming", - "Restoring", - "SendDisabled", - "Unknown" - ], - "nullable": true, - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - }, - "supportOrdering": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Value that indicates whether the topic supports ordering." - } - }, - "subscriptions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the service bus namespace topic subscription." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes." - } - }, - "clientAffineProperties": { - "type": "object", - "properties": { - "clientId": { - "type": "string", - "metadata": { - "description": "Required. Indicates the Client ID of the application that created the client-affine subscription." - } - }, - "isDurable": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is durable or not." - } - }, - "isShared": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is shared or not." - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The properties that are associated with a subscription that is client-affine." - } - }, - "deadLetteringOnMessageExpiration": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "deadLetteringOnFilterEvaluationExceptions": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "enableBatchedOperations": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether server-side batched operations are enabled." - } - }, - "forwardDeadLetteredMessagesTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "forwardTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "isClientAffine": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "lockDuration": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." - } - }, - "maxDeliveryCount": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." - } - }, - "requiresSession": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "status": { - "type": "string", - "allowedValues": [ - "Active", - "Creating", - "Deleting", - "Disabled", - "ReceiveDisabled", - "Renaming", - "Restoring", - "SendDisabled", - "Unknown" - ], - "nullable": true, - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The subscriptions of the topic." - } - } + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" } - }, - "nullable": true + } } + } + } + } + }, + "blobUpload": { + "copy": { + "name": "blobUpload", + "count": "[length(parameters('partitions'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-storage-blob-upload-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "storageAccountName": { + "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" + }, + "location": { + "value": "[parameters('location')]" + }, + "useExistingManagedIdentity": { + "value": true + }, + "managedIdentityName": { + "value": "[parameters('managedIdentityName')]" + }, + "existingManagedIdentitySubId": { + "value": "[subscription().subscriptionId]" + }, + "existingManagedIdentityResourceGroupName": { + "value": "[resourceGroup().name]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "1648875899693105966" + }, + "name": "Blob Upload", + "description": "This module uploads a file to a blob storage account", + "owner": "azure-global-energy" }, "parameters": { - "name": { + "storageAccountName": { "type": "string", - "maxLength": 260, + "defaultValue": "[uniqueString(resourceGroup().id, deployment().name, 'blob')]", "metadata": { - "description": "Required. Name of the Service Bus Namespace." + "description": "Desired name of the storage account" } }, - "location": { + "containerName": { "type": "string", - "defaultValue": "[resourceGroup().location]", + "defaultValue": "legal-service-azure-configuration", "metadata": { - "description": "Optional. Location for all resources." + "description": "Name of the blob container" } }, - "skuObject": { - "$ref": "#/definitions/skuType", - "defaultValue": { - "name": "Premium", - "capacity": 2 - }, + "filename": { + "type": "string", + "defaultValue": "Legal_COO.json", "metadata": { - "description": "Required. The SKU of the Service Bus Namespace. Defaulted to Premium for ZoneRedundant configurations by default." + "description": "Name of the blob as it is stored in the blob container" } }, - "zoneRedundant": { - "type": "bool", - "defaultValue": true, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Enabled by default in order to align with resiliency best practices, thus requires Premium SKU." + "description": "The location of the Storage Account and where to deploy the module resources to" } }, - "minimumTlsVersion": { + "forceUpdateTag": { "type": "string", - "defaultValue": "1.2", - "allowedValues": [ - "1.0", - "1.1", - "1.2" - ], + "defaultValue": "[utcNow()]", "metadata": { - "description": "Optional. The minimum TLS version for the cluster to support." + "description": "How the deployment script should be forced to execute" } }, - "alternateName": { + "rbacRoleNeeded": { "type": "string", - "nullable": true, + "defaultValue": "", "metadata": { - "description": "Optional. Alternate name for namespace." + "description": "Azure RoleId that are required for the DeploymentScript resource to upload blobs" } }, - "premiumMessagingPartitions": { - "type": "int", - "defaultValue": 1, + "useExistingManagedIdentity": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Optional. The number of partitions of a Service Bus namespace. This property is only applicable to Premium SKU namespaces. The default value is 1 and possible values are 1, 2 and 4." + "description": "Does the Managed Identity already exists, or should be created" } }, - "authorizationRules": { - "$ref": "#/definitions/authorizationRuleType", - "defaultValue": [ - { - "name": "RootManageSharedAccessKey", - "rights": [ - "Listen", - "Manage", - "Send" - ] - } - ], + "managedIdentityName": { + "type": "string", + "defaultValue": "[format('id-storage-blob-{0}', parameters('location'))]", "metadata": { - "description": "Optional. Authorization Rules for the Service Bus namespace." + "description": "Name of the Managed Identity resource" } }, - "migrationConfiguration": { - "$ref": "#/definitions/migrationConfigurationsType", + "existingManagedIdentitySubId": { + "type": "string", + "defaultValue": "[subscription().subscriptionId]", "metadata": { - "description": "Optional. The migration configuration." + "description": "For an existing Managed Identity, the Subscription Id it is located in" } }, - "disasterRecoveryConfig": { - "$ref": "#/definitions/disasterRecoveryConfigType", + "existingManagedIdentityResourceGroupName": { + "type": "string", + "defaultValue": "[resourceGroup().name]", "metadata": { - "description": "Optional. The disaster recovery configuration." + "description": "For an existing Managed Identity, the Resource Group it is located in" } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", - "metadata": { - "description": "Optional. The diagnostic settings of the service." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", - "metadata": { - "description": "Optional. The managed identity definition for this resource." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "initialScriptDelay": { + "type": "string", + "defaultValue": "30s", "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" } }, - "publicNetworkAccess": { + "cleanupPreference": { "type": "string", - "defaultValue": "", + "defaultValue": "OnSuccess", "allowedValues": [ - "", - "Disabled", - "Enabled", - "SecuredByPerimeter" + "OnSuccess", + "OnExpiration", + "Always" ], "metadata": { - "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set." - } - }, - "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", - "metadata": { - "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." - } - }, - "networkRuleSets": { - "$ref": "#/definitions/networkRuleSetType", - "nullable": true, - "metadata": { - "description": "Optional. Configure networking options for Premium SKU Service Bus. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace." - } - }, - "disableLocalAuth": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. This property disables SAS authentication for the Service Bus namespace." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } - }, - "queues": { - "$ref": "#/definitions/queueType", - "nullable": true, - "metadata": { - "description": "Optional. The queues to create in the service bus namespace." - } - }, - "topics": { - "$ref": "#/definitions/topicType", - "nullable": true, - "metadata": { - "description": "Optional. The topics to create in the service bus namespace." - } - }, - "customerManagedKey": { - "$ref": "#/definitions/customerManagedKeyType", - "metadata": { - "description": "Optional. The customer managed key definition." - } - }, - "requireInfrastructureEncryption": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters." + "description": "When the script resource is cleaned up" } } }, "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" - } - ], - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", - "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", - "builtInRoleNames": { - "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", - "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", - "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } + "$fxv#0": "[{\n \"name\": \"Andorra\",\n \"alpha2\": \"AD\",\n \"numeric\": 16,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Arab Emirates\",\n \"alpha2\": \"AE\",\n \"numeric\": 784,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Afghanistan\",\n \"alpha2\": \"AF\",\n \"numeric\": 4,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Antigua and Barbuda\",\n \"alpha2\": \"AG\",\n \"numeric\": 28,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Anguilla\",\n \"alpha2\": \"AI\",\n \"numeric\": 660,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Albania\",\n \"alpha2\": \"AL\",\n \"numeric\": 8,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Armenia\",\n \"alpha2\": \"AM\",\n \"numeric\": 51,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Netherlands Antilles\",\n \"alpha2\": \"AN\",\n \"numeric\": 530,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Angola\",\n \"alpha2\": \"AO\",\n \"numeric\": 24,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Antarctica\",\n \"alpha2\": \"AQ\",\n \"numeric\": 10,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Argentina\",\n \"alpha2\": \"AR\",\n \"numeric\": 32,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"American Samoa\",\n \"alpha2\": \"AS\",\n \"numeric\": 16,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Austria\",\n \"alpha2\": \"AT\",\n \"numeric\": 40,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Australia\",\n \"alpha2\": \"AU\",\n \"numeric\": 36,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Aruba\",\n \"alpha2\": \"AW\",\n \"numeric\": 533,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Aland Islands\",\n \"alpha2\": \"AX\",\n \"numeric\": 248,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Azerbaijan\",\n \"alpha2\": \"AZ\",\n \"numeric\": 31,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Bosnia and Herzegovina\",\n \"alpha2\": \"BA\",\n \"numeric\": 70,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Barbados\",\n \"alpha2\": \"BB\",\n \"numeric\": 52,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bangladesh\",\n \"alpha2\": \"BD\",\n \"numeric\": 50,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Belgium\",\n \"alpha2\": \"BE\",\n \"numeric\": 56,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Burkina Faso\",\n \"alpha2\": \"BF\",\n \"numeric\": 854,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bulgaria\",\n \"alpha2\": \"BG\",\n \"numeric\": 100,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bahrain\",\n \"alpha2\": \"BH\",\n \"numeric\": 48,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Burundi\",\n \"alpha2\": \"BI\",\n \"numeric\": 108,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Benin\",\n \"alpha2\": \"BJ\",\n \"numeric\": 204,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Barthelemy\",\n \"alpha2\": \"BL\",\n \"numeric\": 652,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bermuda\",\n \"alpha2\": \"BM\",\n \"numeric\": 60,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Brunei Darussalam\",\n \"alpha2\": \"BN\",\n \"numeric\": 96,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bolivia\",\n \"alpha2\": \"BO\",\n \"numeric\": 68,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Brazil\",\n \"alpha2\": \"BR\",\n \"numeric\": 76,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bahamas\",\n \"alpha2\": \"BS\",\n \"numeric\": 44,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bhutan\",\n \"alpha2\": \"BT\",\n \"numeric\": 64,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bouvet Island\",\n \"alpha2\": \"BV\",\n \"numeric\": 74,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Botswana\",\n \"alpha2\": \"BW\",\n \"numeric\": 72,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Belarus\",\n \"alpha2\": \"BY\",\n \"numeric\": 112,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Belize\",\n \"alpha2\": \"BZ\",\n \"numeric\": 84,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Canada\",\n \"alpha2\": \"CA\",\n \"numeric\": 124,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cocos Islands\",\n \"alpha2\": \"CC\",\n \"numeric\": 166,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"The Democratic Republic of the Congo\",\n \"alpha2\": \"CD\",\n \"numeric\": 180,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Central African Republic\",\n \"alpha2\": \"CF\",\n \"numeric\": 140,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Congo\",\n \"alpha2\": \"CG\",\n \"numeric\": 178,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Switzerland\",\n \"alpha2\": \"CH\",\n \"numeric\": 756,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cote d'Ivoire\",\n \"alpha2\": \"CI\",\n \"numeric\": 384,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cook Islands\",\n \"alpha2\": \"CK\",\n \"numeric\": 184,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Chile\",\n \"alpha2\": \"CL\",\n \"numeric\": 152,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cameroon\",\n \"alpha2\": \"CM\",\n \"numeric\": 120,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"China\",\n \"alpha2\": \"CN\",\n \"numeric\": 156,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Colombia\",\n \"alpha2\": \"CO\",\n \"numeric\": 170,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Costa Rica\",\n \"alpha2\": \"CR\",\n \"numeric\": 188,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cuba\",\n \"alpha2\": \"CU\",\n \"numeric\": 192,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Cape Verde\",\n \"alpha2\": \"CV\",\n \"numeric\": 132,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Christmas Island\",\n \"alpha2\": \"CX\",\n \"numeric\": 162,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cyprus\",\n \"alpha2\": \"CY\",\n \"numeric\": 196,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Czech Republic\",\n \"alpha2\": \"CZ\",\n \"numeric\": 203,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Germany\",\n \"alpha2\": \"DE\",\n \"numeric\": 276,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Djibouti\",\n \"alpha2\": \"DJ\",\n \"numeric\": 262,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Denmark\",\n \"alpha2\": \"DK\",\n \"numeric\": 208,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Dominica\",\n \"alpha2\": \"DM\",\n \"numeric\": 212,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Dominican Republic\",\n \"alpha2\": \"DO\",\n \"numeric\": 214,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Algeria\",\n \"alpha2\": \"DZ\",\n \"numeric\": 12,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ecuador\",\n \"alpha2\": \"EC\",\n \"numeric\": 218,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Estonia\",\n \"alpha2\": \"EE\",\n \"numeric\": 233,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Egypt\",\n \"alpha2\": \"EG\",\n \"numeric\": 818,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Western Sahara\",\n \"alpha2\": \"EH\",\n \"numeric\": 732,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Eritrea\",\n \"alpha2\": \"ER\",\n \"numeric\": 232,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Spain\",\n \"alpha2\": \"ES\",\n \"numeric\": 724,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ethiopia\",\n \"alpha2\": \"ET\",\n \"numeric\": 231,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Finland\",\n \"alpha2\": \"FI\",\n \"numeric\": 246,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Fiji\",\n \"alpha2\": \"FJ\",\n \"numeric\": 242,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Falkland Islands\",\n \"alpha2\": \"FK\",\n \"numeric\": 238,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Federated States of Micronesia\",\n \"alpha2\": \"FM\",\n \"numeric\": 583,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Faroe Islands\",\n \"alpha2\": \"FO\",\n \"numeric\": 234,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"France\",\n \"alpha2\": \"FR\",\n \"numeric\": 250,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gabon\",\n \"alpha2\": \"GA\",\n \"numeric\": 266,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Kingdom\",\n \"alpha2\": \"GB\",\n \"numeric\": 826,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Grenada\",\n \"alpha2\": \"GD\",\n \"numeric\": 308,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Georgia\",\n \"alpha2\": \"GE\",\n \"numeric\": 268,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"French Guiana\",\n \"alpha2\": \"GF\",\n \"numeric\": 254,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guernsey\",\n \"alpha2\": \"GG\",\n \"numeric\": 831,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ghana\",\n \"alpha2\": \"GH\",\n \"numeric\": 288,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gibraltar\",\n \"alpha2\": \"GI\",\n \"numeric\": 292,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Greenland\",\n \"alpha2\": \"GL\",\n \"numeric\": 304,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gambia\",\n \"alpha2\": \"GM\",\n \"numeric\": 270,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guinea\",\n \"alpha2\": \"GN\",\n \"numeric\": 324,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guadeloupe\",\n \"alpha2\": \"GP\",\n \"numeric\": 312,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Equatorial Guinea\",\n \"alpha2\": \"GQ\",\n \"numeric\": 226,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Greece\",\n \"alpha2\": \"GR\",\n \"numeric\": 300,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"South Georgia and the South Sandwich Islands\",\n \"alpha2\": \"GS\",\n \"numeric\": 239,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guatemala\",\n \"alpha2\": \"GT\",\n \"numeric\": 320,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guam\",\n \"alpha2\": \"GU\",\n \"numeric\": 316,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guinea-Bissau\",\n \"alpha2\": \"GW\",\n \"numeric\": 624,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guyana\",\n \"alpha2\": \"GY\",\n \"numeric\": 328,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Hong Kong\",\n \"alpha2\": \"HK\",\n \"numeric\": 344,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Heard Island and McDonald Islands\",\n \"alpha2\": \"HM\",\n \"numeric\": 334,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Honduras\",\n \"alpha2\": \"HN\",\n \"numeric\": 340,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Croatia\",\n \"alpha2\": \"HR\",\n \"numeric\": 191,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Haiti\",\n \"alpha2\": \"HT\",\n \"numeric\": 332,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Hungary\",\n \"alpha2\": \"HU\",\n \"numeric\": 348,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Indonesia\",\n \"alpha2\": \"ID\",\n \"numeric\": 360,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Ireland\",\n \"alpha2\": \"IE\",\n \"numeric\": 372,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Israel\",\n \"alpha2\": \"IL\",\n \"numeric\": 376,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Isle of Man\",\n \"alpha2\": \"IM\",\n \"numeric\": 833,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"India\",\n \"alpha2\": \"IN\",\n \"numeric\": 356,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"British Indian Ocean Territory\",\n \"alpha2\": \"IO\",\n \"numeric\": 86,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Iraq\",\n \"alpha2\": \"IQ\",\n \"numeric\": 368,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Islamic Republic of Iran\",\n \"alpha2\": \"IR\",\n \"numeric\": 364,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Iceland\",\n \"alpha2\": \"IS\",\n \"numeric\": 352,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Italy\",\n \"alpha2\": \"IT\",\n \"numeric\": 380,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jersey\",\n \"alpha2\": \"JE\",\n \"numeric\": 832,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jamaica\",\n \"alpha2\": \"JM\",\n \"numeric\": 388,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jordan\",\n \"alpha2\": \"JO\",\n \"numeric\": 400,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Japan\",\n \"alpha2\": \"JP\",\n \"numeric\": 392,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kenya\",\n \"alpha2\": \"KE\",\n \"numeric\": 404,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kyrgyzstan\",\n \"alpha2\": \"KG\",\n \"numeric\": 417,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cambodia\",\n \"alpha2\": \"KH\",\n \"numeric\": 116,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kiribati\",\n \"alpha2\": \"KI\",\n \"numeric\": 296,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Comoros\",\n \"alpha2\": \"KM\",\n \"numeric\": 174,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Kitts and Nevis\",\n \"alpha2\": \"KN\",\n \"numeric\": 659,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Democratic People's Republic of Korea\",\n \"alpha2\": \"KP\",\n \"numeric\": 408,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Republic of Korea\",\n \"alpha2\": \"KR\",\n \"numeric\": 410,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kuwait\",\n \"alpha2\": \"KW\",\n \"numeric\": 414,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Cayman Islands\",\n \"alpha2\": \"KY\",\n \"numeric\": 136,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kazakhstan\",\n \"alpha2\": \"KZ\",\n \"numeric\": 398,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lao People's Democratic Republic\",\n \"alpha2\": \"LA\",\n \"numeric\": 418,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lebanon\",\n \"alpha2\": \"LB\",\n \"numeric\": 422,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Lucia\",\n \"alpha2\": \"LC\",\n \"numeric\": 662,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Liechtenstein\",\n \"alpha2\": \"LI\",\n \"numeric\": 438,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sri Lanka\",\n \"alpha2\": \"LK\",\n \"numeric\": 144,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Liberia\",\n \"alpha2\": \"LR\",\n \"numeric\": 430,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lesotho\",\n \"alpha2\": \"LS\",\n \"numeric\": 426,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lithuania\",\n \"alpha2\": \"LT\",\n \"numeric\": 440,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Luxembourg\",\n \"alpha2\": \"LU\",\n \"numeric\": 442,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Latvia\",\n \"alpha2\": \"LV\",\n \"numeric\": 428,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Libya\",\n \"alpha2\": \"LY\",\n \"numeric\": 434,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Morocco\",\n \"alpha2\": \"MA\",\n \"numeric\": 504,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Monaco\",\n \"alpha2\": \"MC\",\n \"numeric\": 492,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Republic of Moldova\",\n \"alpha2\": \"MD\",\n \"numeric\": 498,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Montenegro\",\n \"alpha2\": \"ME\",\n \"numeric\": 499,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Martin\",\n \"alpha2\": \"MF\",\n \"numeric\": 663,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Madagascar\",\n \"alpha2\": \"MG\",\n \"numeric\": 450,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Marshall Islands\",\n \"alpha2\": \"MH\",\n \"numeric\": 584,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"The former Yugoslav Republic of Macedonia\",\n \"alpha2\": \"MK\",\n \"numeric\": 807,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mali\",\n \"alpha2\": \"ML\",\n \"numeric\": 466,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Myanmar\",\n \"alpha2\": \"MM\",\n \"numeric\": 104,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mongolia\",\n \"alpha2\": \"MN\",\n \"numeric\": 496,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Macao\",\n \"alpha2\": \"MO\",\n \"numeric\": 446,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Northern Mariana Islands\",\n \"alpha2\": \"MP\",\n \"numeric\": 580,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Martinique\",\n \"alpha2\": \"MQ\",\n \"numeric\": 474,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mauritania\",\n \"alpha2\": \"MR\",\n \"numeric\": 478,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Montserrat\",\n \"alpha2\": \"MS\",\n \"numeric\": 500,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Malta\",\n \"alpha2\": \"MT\",\n \"numeric\": 470,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mauritius\",\n \"alpha2\": \"MU\",\n \"numeric\": 480,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Maldives\",\n \"alpha2\": \"MV\",\n \"numeric\": 462,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Malawi\",\n \"alpha2\": \"MW\",\n \"numeric\": 454,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mexico\",\n \"alpha2\": \"MX\",\n \"numeric\": 484,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Malaysia\",\n \"alpha2\": \"MY\",\n \"numeric\": 458,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mozambique\",\n \"alpha2\": \"MZ\",\n \"numeric\": 508,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Namibia\",\n \"alpha2\": \"NA\",\n \"numeric\": 516,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"New Caledonia\",\n \"alpha2\": \"NC\",\n \"numeric\": 540,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Niger\",\n \"alpha2\": \"NE\",\n \"numeric\": 562,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Norfolk Island\",\n \"alpha2\": \"NF\",\n \"numeric\": 574,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nigeria\",\n \"alpha2\": \"NG\",\n \"numeric\": 566,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nicaragua\",\n \"alpha2\": \"NI\",\n \"numeric\": 558,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Netherlands\",\n \"alpha2\": \"NL\",\n \"numeric\": 528,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Norway\",\n \"alpha2\": \"NO\",\n \"numeric\": 578,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nepal\",\n \"alpha2\": \"NP\",\n \"numeric\": 524,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nauru\",\n \"alpha2\": \"NR\",\n \"numeric\": 520,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Niue\",\n \"alpha2\": \"NU\",\n \"numeric\": 570,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"New Zealand\",\n \"alpha2\": \"NZ\",\n \"numeric\": 554,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Oman\",\n \"alpha2\": \"OM\",\n \"numeric\": 512,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Panama\",\n \"alpha2\": \"PA\",\n \"numeric\": 591,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Peru\",\n \"alpha2\": \"PE\",\n \"numeric\": 604,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"French Polynesia\",\n \"alpha2\": \"PF\",\n \"numeric\": 258,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Papua New Guinea\",\n \"alpha2\": \"PG\",\n \"numeric\": 598,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Philippines\",\n \"alpha2\": \"PH\",\n \"numeric\": 608,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Pakistan\",\n \"alpha2\": \"PK\",\n \"numeric\": 586,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Poland\",\n \"alpha2\": \"PL\",\n \"numeric\": 616,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Pierre and Miquelon\",\n \"alpha2\": \"PM\",\n \"numeric\": 666,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Pitcairn\",\n \"alpha2\": \"PN\",\n \"numeric\": 612,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Puerto Rico\",\n \"alpha2\": \"PR\",\n \"numeric\": 630,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Palestinian Territory\",\n \"alpha2\": \"PS\",\n \"numeric\": 275,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Portugal\",\n \"alpha2\": \"PT\",\n \"numeric\": 620,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Palau\",\n \"alpha2\": \"PW\",\n \"numeric\": 585,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Paraguay\",\n \"alpha2\": \"PY\",\n \"numeric\": 600,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Qatar\",\n \"alpha2\": \"QA\",\n \"numeric\": 634,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Reunion\",\n \"alpha2\": \"RE\",\n \"numeric\": 638,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Romania\",\n \"alpha2\": \"RO\",\n \"numeric\": 642,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Serbia\",\n \"alpha2\": \"RS\",\n \"numeric\": 688,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Russian Federation\",\n \"alpha2\": \"RU\",\n \"numeric\": 643,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Rwanda\",\n \"alpha2\": \"RW\",\n \"numeric\": 646,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saudi Arabia\",\n \"alpha2\": \"SA\",\n \"numeric\": 682,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Solomon Islands\",\n \"alpha2\": \"SB\",\n \"numeric\": 90,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Seychelles\",\n \"alpha2\": \"SC\",\n \"numeric\": 690,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sudan\",\n \"alpha2\": \"SD\",\n \"numeric\": 729,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Sweden\",\n \"alpha2\": \"SE\",\n \"numeric\": 752,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Singapore\",\n \"alpha2\": \"SG\",\n \"numeric\": 702,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Helena\",\n \"alpha2\": \"SH\",\n \"numeric\": 654,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Slovenia\",\n \"alpha2\": \"SI\",\n \"numeric\": 705,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Svalbard and Jan Mayen\",\n \"alpha2\": \"SJ\",\n \"numeric\": 744,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Slovakia\",\n \"alpha2\": \"SK\",\n \"numeric\": 703,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sierra Leone\",\n \"alpha2\": \"SL\",\n \"numeric\": 694,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"San Marino\",\n \"alpha2\": \"SM\",\n \"numeric\": 674,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Senegal\",\n \"alpha2\": \"SN\",\n \"numeric\": 686,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Somalia\",\n \"alpha2\": \"SO\",\n \"numeric\": 706,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Suriname\",\n \"alpha2\": \"SR\",\n \"numeric\": 740,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"South Sudan\",\n \"alpha2\": \"SS\",\n \"numeric\": 728,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Sao Tome and Principe\",\n \"alpha2\": \"ST\",\n \"numeric\": 678,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"El Salvador\",\n \"alpha2\": \"SV\",\n \"numeric\": 222,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Syrian Arab Republic\",\n \"alpha2\": \"SY\",\n \"numeric\": 760,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Swaziland\",\n \"alpha2\": \"SZ\",\n \"numeric\": 748,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turks and Caicos Islands\",\n \"alpha2\": \"TC\",\n \"numeric\": 796,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Chad\",\n \"alpha2\": \"TD\",\n \"numeric\": 148,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Togo\",\n \"alpha2\": \"TG\",\n \"numeric\": 768,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Thailand\",\n \"alpha2\": \"TH\",\n \"numeric\": 764,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tajikistan\",\n \"alpha2\": \"TJ\",\n \"numeric\": 762,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tokelau\",\n \"alpha2\": \"TK\",\n \"numeric\": 772,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Timor-Leste\",\n \"alpha2\": \"TL\",\n \"numeric\": 626,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turkmenistan\",\n \"alpha2\": \"TM\",\n \"numeric\": 795,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tunisia\",\n \"alpha2\": \"TN\",\n \"numeric\": 788,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tonga\",\n \"alpha2\": \"TO\",\n \"numeric\": 776,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turkey\",\n \"alpha2\": \"TR\",\n \"numeric\": 792,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Trinidad and Tobago\",\n \"alpha2\": \"TT\",\n \"numeric\": 780,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tuvalu\",\n \"alpha2\": \"TV\",\n \"numeric\": 798,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Taiwan, Province of China\",\n \"alpha2\": \"TW\",\n \"numeric\": 158,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Republic of Tanzania\",\n \"alpha2\": \"TZ\",\n \"numeric\": 834,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ukraine\",\n \"alpha2\": \"UA\",\n \"numeric\": 804,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Uganda\",\n \"alpha2\": \"UG\",\n \"numeric\": 800,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United States Minor Outlying Islands\",\n \"alpha2\": \"UM\",\n \"numeric\": 581,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United States\",\n \"alpha2\": \"US\",\n \"numeric\": 840,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Uruguay\",\n \"alpha2\": \"UY\",\n \"numeric\": 858,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Uzbekistan\",\n \"alpha2\": \"UZ\",\n \"numeric\": 860,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Vincent and the Grenadines\",\n \"alpha2\": \"VC\",\n \"numeric\": 670,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Venezuela\",\n \"alpha2\": \"VE\",\n \"numeric\": 862,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"British Virgin Islands\",\n \"alpha2\": \"VG\",\n \"numeric\": 92,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Virgin Islands, U.S.\",\n \"alpha2\": \"VI\",\n \"numeric\": 850,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Vietnam\",\n \"alpha2\": \"VN\",\n \"numeric\": 704,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Vanuatu\",\n \"alpha2\": \"VU\",\n \"numeric\": 548,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Wallis and Futuna\",\n \"alpha2\": \"WF\",\n \"numeric\": 876,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Samoa\",\n \"alpha2\": \"WS\",\n \"numeric\": 882,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Yemen\",\n \"alpha2\": \"YE\",\n \"numeric\": 887,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"South Africa\",\n \"alpha2\": \"ZA\",\n \"numeric\": 710,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Zambia\",\n \"alpha2\": \"ZM\",\n \"numeric\": 894,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Zimbabwe\",\n \"alpha2\": \"ZW\",\n \"numeric\": 716,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Default\",\n \"alpha2\": \"XX\",\n \"numeric\": 999,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}\n]\n", + "$fxv#1": "#!/bin/bash\nset -e\n\necho \"Waiting on Identity RBAC replication ($initialDelay)\"\nsleep $initialDelay\n\n# Installing curl\napk add --no-cache curl\n\necho \"$CONTENT\" > ${FILE_NAME}\n\n# Upload the blob, overwriting if it exists\naz storage blob upload -f ${FILE_NAME} -c ${CONTAINER} -n ${FILE_NAME} --overwrite\necho \"Blob ${CONTAINER} uploaded to container ${CONTAINER}, overwriting if it existed.\"" }, - "resources": { - "cMKKeyVault::cMKKey": { - "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", - "existing": true, - "type": "Microsoft.KeyVault/vaults/keys", - "apiVersion": "2023-02-01", - "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", - "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", - "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", - "dependsOn": [ - "cMKKeyVault" - ] - }, - "avmTelemetry": { - "condition": "[parameters('enableTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.servicebus-namespace.{0}.{1}', replace('0.9.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [], - "outputs": { - "telemetry": { - "type": "String", - "value": "For more information, see https://aka.ms/avm/TelemetryInfo" - } - } - } - } - }, - "cMKKeyVault": { - "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", - "existing": true, - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2023-02-01", - "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", - "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", - "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" - }, - "cMKUserAssignedIdentity": { - "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", - "existing": true, + "resources": [ + { + "condition": "[not(parameters('useExistingManagedIdentity'))]", "type": "Microsoft.ManagedIdentity/userAssignedIdentities", "apiVersion": "2023-01-31", - "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", - "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", - "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" - }, - "serviceBusNamespace": { - "type": "Microsoft.ServiceBus/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('skuObject').name]", - "capacity": "[tryGet(parameters('skuObject'), 'capacity')]" - }, - "identity": "[variables('identity')]", - "properties": { - "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), 'Disabled', 'Enabled'))]", - "minimumTlsVersion": "[parameters('minimumTlsVersion')]", - "alternateName": "[parameters('alternateName')]", - "zoneRedundant": "[parameters('zoneRedundant')]", - "disableLocalAuth": "[parameters('disableLocalAuth')]", - "premiumMessagingPartitions": "[if(equals(parameters('skuObject').name, 'Premium'), parameters('premiumMessagingPartitions'), 0)]", - "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createArray(createObject('identity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), null()), 'keyName', parameters('customerManagedKey').keyName, 'keyVaultUri', reference('cMKKeyVault').vaultUri, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), 'requireInfrastructureEncryption', parameters('requireInfrastructureEncryption')), null())]" - }, - "dependsOn": [ - "cMKKeyVault", - "cMKUserAssignedIdentity" - ] + "name": "[parameters('managedIdentityName')]", + "location": "[parameters('location')]" }, - "serviceBusNamespace_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + { + "condition": "[not(empty(parameters('rbacRoleNeeded')))]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]", + "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]", "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRoleNeeded'))]", + "principalId": "[if(parameters('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId)]", + "principalType": "ServicePrincipal" }, "dependsOn": [ - "serviceBusNamespace" + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" ] }, - "serviceBusNamespace_diagnosticSettings": { - "copy": { - "name": "serviceBusNamespace_diagnosticSettings", - "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + { + "type": "Microsoft.Resources/deploymentScripts", + "apiVersion": "2023-08-01", + "name": "[format('script-{0}-{1}', parameters('storageAccountName'), replace(replace(parameters('filename'), ':', ''), '/', '-'))]", + "location": "[parameters('location')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} + } }, - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "kind": "AzureCLI", "properties": { - "copy": [ + "forceUpdateTag": "[parameters('forceUpdateTag')]", + "azCliVersion": "2.63.0", + "timeout": "PT30M", + "retentionInterval": "PT1H", + "environmentVariables": [ { - "name": "metrics", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", - "input": { - "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", - "timeGrain": null - } + "name": "AZURE_STORAGE_ACCOUNT", + "value": "[parameters('storageAccountName')]" }, { - "name": "logs", - "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", - "input": { - "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", - "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", - "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" - } + "name": "AZURE_STORAGE_KEY", + "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2023-04-01').keys[0].value]" + }, + { + "name": "CONTENT", + "value": "[variables('$fxv#0')]" + }, + { + "name": "FILE_NAME", + "value": "[parameters('filename')]" + }, + { + "name": "CONTAINER", + "value": "[parameters('containerName')]" + }, + { + "name": "initialDelay", + "value": "[parameters('initialScriptDelay')]" } ], - "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", - "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", - "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", - "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", - "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", - "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + "scriptContent": "[variables('$fxv#1')]", + "cleanupPreference": "[parameters('cleanupPreference')]" }, "dependsOn": [ - "serviceBusNamespace" + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", + "[extensionResourceId(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))))]" ] + } + ] + } + }, + "dependsOn": [ + "[format('partitionStorage[{0}]', copyIndex())]" + ] + }, + "partitionSecrets": { + "copy": { + "name": "partitionSecrets", + "count": "[length(parameters('partitions'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-secrets-{1}', parameters('bladeConfig').sectionName, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "keyVaultName": { + "value": "[parameters('kvName')]" + }, + "partitionName": { + "value": "[parameters('partitions')[copyIndex()].name]" + }, + "serviceBusName": { + "value": "[reference(format('partitonNamespace[{0}]', copyIndex())).outputs.name.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "3333956665359119971" + } + }, + "parameters": { + "keyVaultName": { + "type": "string", + "metadata": { + "description": "The name of the parent key vault." + } }, - "serviceBusNamespace_roleAssignments": { - "copy": { - "name": "serviceBusNamespace_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "partitionName": { + "type": "string", + "metadata": { + "description": "The name of the partition." + } + }, + "serviceBusName": { + "type": "string", + "metadata": { + "description": "The name of the service bus." + } + } + }, + "variables": { + "serviceBusEndpoint": "[format('{0}/AuthorizationRules/RootManageSharedAccessKey', resourceId('Microsoft.ServiceBus/namespaces', parameters('serviceBusName')))]" + }, + "resources": [ + { + "condition": "[not(equals(parameters('serviceBusName'), 'null'))]", + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-sb-connection', parameters('partitionName')))]", "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "serviceBusNamespace" - ] + "value": "[listKeys(variables('serviceBusEndpoint'), '2022-10-01-preview').primaryConnectionString]" + } }, - "serviceBusNamespace_authorizationRules": { - "copy": { - "name": "serviceBusNamespace_authorizationRules", - "count": "[length(parameters('authorizationRules'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-AuthorizationRules-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + { + "condition": "[not(equals(parameters('serviceBusName'), 'null'))]", + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-sb-namespace', parameters('partitionName')))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[parameters('authorizationRules')[copyIndex()].name]" - }, - "rights": { - "value": "[tryGet(parameters('authorizationRules')[copyIndex()], 'rights')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "16659347344675880024" - }, - "name": "Service Bus Namespace Authorization Rules", - "description": "This module deploys a Service Bus Namespace Authorization Rule.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the authorization rule." - } - }, - "rights": { - "type": "array", - "defaultValue": [], - "allowedValues": [ - "Listen", - "Manage", - "Send" - ], - "metadata": { - "description": "Optional. The rights associated with the rule." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/AuthorizationRules", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": { - "rights": "[parameters('rights')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the authorization rule." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the authorization rule." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/AuthorizationRules', parameters('namespaceName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the authorization rule was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "serviceBusNamespace" - ] + "value": "[parameters('serviceBusName')]" + } }, - "serviceBusNamespace_disasterRecoveryConfig": { - "condition": "[not(empty(parameters('disasterRecoveryConfig')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-DisasterRecoveryConfig', uniqueString(deployment().name, parameters('location')))]", + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-endpoint', parameters('partitionName')))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[coalesce(tryGet(parameters('disasterRecoveryConfig'), 'name'), 'default')]" - }, - "alternateName": { - "value": "[tryGet(parameters('disasterRecoveryConfig'), 'alternateName')]" - }, - "partnerNamespaceResourceID": { - "value": "[tryGet(parameters('disasterRecoveryConfig'), 'partnerNamespace')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "2437567647402328568" - }, - "name": "Service Bus Namespace Disaster Recovery Configs", - "description": "This module deploys a Service Bus Namespace Disaster Recovery Config", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "defaultValue": "default", - "metadata": { - "description": "Optional. The name of the disaster recovery config." - } - }, - "alternateName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Primary/Secondary eventhub namespace name, which is part of GEO DR pairing." - } - }, - "partnerNamespaceResourceID": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/disasterRecoveryConfigs", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": { - "alternateName": "[parameters('alternateName')]", - "partnerNamespace": "[parameters('partnerNamespaceResourceID')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the disaster recovery config." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The Resource ID of the disaster recovery config." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/disasterRecoveryConfigs', parameters('namespaceName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the disaster recovery config was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "serviceBusNamespace" - ] + "value": "http://elasticsearch-es-http.elastic-search:9200" + } }, - "serviceBusNamespace_migrationConfigurations": { - "condition": "[not(empty(coalesce(parameters('migrationConfiguration'), createObject())))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-MigrationConfigurations', uniqueString(deployment().name, parameters('location')))]", + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-username', parameters('partitionName')))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "postMigrationName": { - "value": "[parameters('migrationConfiguration').postMigrationName]" - }, - "targetNamespaceResourceId": { - "value": "[parameters('migrationConfiguration').targetNamespace]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5021121087195745079" - }, - "name": "Service Bus Namespace Migration Configuration", - "description": "This module deploys a Service Bus Namespace Migration Configuration.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." - } - }, - "postMigrationName": { - "type": "string", - "metadata": { - "description": "Required. Name to access Standard Namespace after migration." - } - }, - "targetNamespaceResourceId": { - "type": "string", - "metadata": { - "description": "Required. Existing premium Namespace resource ID which has no entities, will be used for migration." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/migrationConfigurations", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), '$default')]", - "properties": { - "targetNamespace": "[parameters('targetNamespaceResourceId')]", - "postMigrationName": "[parameters('postMigrationName')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the migration configuration." - }, - "value": "$default" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The Resource ID of the migration configuration." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/migrationConfigurations', parameters('namespaceName'), '$default')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the migration configuration was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "serviceBusNamespace" - ] + "value": "elastic-user" + } }, - "serviceBusNamespace_networkRuleSet": { - "condition": "[or(not(empty(parameters('networkRuleSets'))), not(empty(parameters('privateEndpoints'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-NetworkRuleSet', uniqueString(deployment().name, parameters('location')))]", + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-password', parameters('partitionName')))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "publicNetworkAccess": { - "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), 'Disabled', 'Enabled'))]" - }, - "defaultAction": { - "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'defaultAction'), 'Allow')]" - }, - "trustedServiceAccessEnabled": { - "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'trustedServiceAccessEnabled'), true())]" - }, - "ipRules": { - "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'ipRules'), createArray())]" - }, - "virtualNetworkRules": { - "value": "[coalesce(tryGet(parameters('networkRuleSets'), 'virtualNetworkRules'), createArray())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "18220065019802173538" - }, - "name": "Service Bus Namespace Network Rule Sets", - "description": "This module deploys a ServiceBus Namespace Network Rule Set.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Network Rule Set. Required if the template is used in a standalone deployment." - } - }, - "publicNetworkAccess": { - "type": "string", - "defaultValue": "Enabled", - "allowedValues": [ - "Enabled", - "Disabled" - ], - "metadata": { - "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." - } - }, - "defaultAction": { - "type": "string", - "defaultValue": "Allow", - "allowedValues": [ - "Allow", - "Deny" - ], - "metadata": { - "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." - } - }, - "trustedServiceAccessEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not. Default is \"true\". It will not be set if publicNetworkAccess is \"Disabled\"." - } - }, - "virtualNetworkRules": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List virtual network rules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." - } - }, - "ipRules": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. List of IpRules. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." - } - } - }, - "variables": { - "copy": [ - { - "name": "networkRules", - "count": "[length(parameters('virtualNetworkRules'))]", - "input": { - "ignoreMissingVnetServiceEndpoint": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'ignoreMissingVnetServiceEndpoint'), parameters('virtualNetworkRules')[copyIndex('networkRules')].ignoreMissingVnetServiceEndpoint, null())]", - "subnet": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'subnetResourceId'), createObject('id', parameters('virtualNetworkRules')[copyIndex('networkRules')].subnetResourceId), null())]" - } - } - ] - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/networkRuleSets", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), 'default')]", - "properties": { - "publicNetworkAccess": "[parameters('publicNetworkAccess')]", - "defaultAction": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), if(or(not(empty(parameters('ipRules'))), not(empty(parameters('virtualNetworkRules')))), 'Deny', parameters('defaultAction')), null())]", - "trustedServiceAccessEnabled": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), parameters('trustedServiceAccessEnabled'), null())]", - "ipRules": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), parameters('ipRules'), null())]", - "virtualNetworkRules": "[if(equals(parameters('publicNetworkAccess'), 'Enabled'), variables('networkRules'), null())]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the network rule set." - }, - "value": "default" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the network rule set." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/networkRuleSets', parameters('namespaceName'), 'default')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the network rule set was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "serviceBusNamespace" - ] + "value": "[substring(uniqueString(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), parameters('partitionName'), resourceGroup().id), 0, 8)]" + } }, - "serviceBusNamespace_queues": { - "copy": { - "name": "serviceBusNamespace_queues", - "count": "[length(coalesce(parameters('queues'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Queue-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-key', parameters('partitionName')))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[coalesce(parameters('queues'), createArray())[copyIndex()].name]" - }, - "autoDeleteOnIdle": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'autoDeleteOnIdle')]" - }, - "forwardDeadLetteredMessagesTo": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'forwardDeadLetteredMessagesTo')]" - }, - "forwardTo": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'forwardTo')]" - }, - "maxMessageSizeInKilobytes": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxMessageSizeInKilobytes')]" - }, - "authorizationRules": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'authorizationRules')]" - }, - "deadLetteringOnMessageExpiration": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'deadLetteringOnMessageExpiration')]" - }, - "defaultMessageTimeToLive": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'defaultMessageTimeToLive')]" - }, - "duplicateDetectionHistoryTimeWindow": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow')]" - }, - "enableBatchedOperations": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enableBatchedOperations')]" - }, - "enableExpress": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enableExpress')]" - }, - "enablePartitioning": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'enablePartitioning')]" - }, - "lock": { - "value": "[coalesce(tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" - }, - "lockDuration": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'lockDuration')]" - }, - "maxDeliveryCount": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxDeliveryCount')]" - }, - "maxSizeInMegabytes": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'maxSizeInMegabytes')]" - }, - "requiresDuplicateDetection": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'requiresDuplicateDetection')]" - }, - "requiresSession": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'requiresSession')]" - }, - "roleAssignments": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'roleAssignments')]" - }, - "status": { - "value": "[tryGet(coalesce(parameters('queues'), createArray())[copyIndex()], 'status')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "12442268068778335924" - }, - "name": "Service Bus Namespace Queue", - "description": "This module deploys a Service Bus Namespace Queue.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Queue. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Required. Name of the Service Bus Queue." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8061 timeSpan idle interval after which the queue is automatically deleted. The minimum duration is 5 minutes (PT5M)." - } - }, - "forwardDeadLetteredMessagesTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Queue/Topic name to forward the Dead Letter message." - } - }, - "forwardTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Queue/Topic name to forward the messages." - } - }, - "lockDuration": { - "type": "string", - "defaultValue": "PT1M", - "metadata": { - "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." - } - }, - "maxSizeInMegabytes": { - "type": "int", - "defaultValue": 1024, - "metadata": { - "description": "Optional. The maximum size of the queue in megabytes, which is the size of memory allocated for the queue. Default is 1024." - } - }, - "requiresDuplicateDetection": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value indicating if this queue requires duplicate detection." - } - }, - "requiresSession": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether the queue supports the concept of sessions." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "defaultValue": "P14D", - "metadata": { - "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." - } - }, - "deadLetteringOnMessageExpiration": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. A value that indicates whether this queue has dead letter support when a message expires." - } - }, - "enableBatchedOperations": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Value that indicates whether server-side batched operations are enabled." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "defaultValue": "PT10M", - "metadata": { - "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "maxDeliveryCount": { - "type": "int", - "defaultValue": 10, - "metadata": { - "description": "Optional. The maximum delivery count. A message is automatically deadlettered after this number of deliveries. default value is 10." - } - }, - "maxMessageSizeInKilobytes": { - "type": "int", - "defaultValue": 1024, - "metadata": { - "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the queue. This property is only used in Premium today and default is 1024." - } - }, - "status": { - "type": "string", - "defaultValue": "Active", - "allowedValues": [ - "Active", - "Disabled", - "Restoring", - "SendDisabled", - "ReceiveDisabled", - "Creating", - "Deleting", - "Renaming", - "Unknown" - ], - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - }, - "enablePartitioning": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether the queue is to be partitioned across multiple message brokers." - } - }, - "enableExpress": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether Express Entities are enabled. An express queue holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." - } - }, - "authorizationRules": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. Authorization Rules for the Service Bus Queue." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - } - }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" - } - ], - "builtInRoleNames": { - "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", - "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", - "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.ServiceBus/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "queue": { - "type": "Microsoft.ServiceBus/namespaces/queues", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": { - "autoDeleteOnIdle": "[if(not(empty(parameters('autoDeleteOnIdle'))), parameters('autoDeleteOnIdle'), null())]", - "defaultMessageTimeToLive": "[parameters('defaultMessageTimeToLive')]", - "deadLetteringOnMessageExpiration": "[parameters('deadLetteringOnMessageExpiration')]", - "duplicateDetectionHistoryTimeWindow": "[parameters('duplicateDetectionHistoryTimeWindow')]", - "enableBatchedOperations": "[parameters('enableBatchedOperations')]", - "enableExpress": "[parameters('enableExpress')]", - "enablePartitioning": "[parameters('enablePartitioning')]", - "forwardDeadLetteredMessagesTo": "[if(not(empty(parameters('forwardDeadLetteredMessagesTo'))), parameters('forwardDeadLetteredMessagesTo'), null())]", - "forwardTo": "[if(not(empty(parameters('forwardTo'))), parameters('forwardTo'), null())]", - "lockDuration": "[parameters('lockDuration')]", - "maxDeliveryCount": "[parameters('maxDeliveryCount')]", - "maxMessageSizeInKilobytes": "[if(equals(reference('namespace', '2022-10-01-preview', 'full').sku.name, 'Premium'), parameters('maxMessageSizeInKilobytes'), null())]", - "maxSizeInMegabytes": "[parameters('maxSizeInMegabytes')]", - "requiresDuplicateDetection": "[parameters('requiresDuplicateDetection')]", - "requiresSession": "[parameters('requiresSession')]", - "status": "[parameters('status')]" - }, - "dependsOn": [ - "namespace" - ] - }, - "queue_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/queues/{1}', parameters('namespaceName'), parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "queue" - ] - }, - "queue_roleAssignments": { - "copy": { - "name": "queue_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/queues/{1}', parameters('namespaceName'), parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces/queues', parameters('namespaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", - "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "queue" - ] - }, - "queue_authorizationRules": { - "copy": { - "name": "queue_authorizationRules", - "count": "[length(parameters('authorizationRules'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('namespaceName')]" - }, - "queueName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[parameters('authorizationRules')[copyIndex()].name]" - }, - "rights": { - "value": "[coalesce(tryGet(parameters('authorizationRules')[copyIndex()], 'rights'), createArray())]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13378473188831787359" - }, - "name": "Service Bus Namespace Queue Authorization Rules", - "description": "This module deploys a Service Bus Namespace Queue Authorization Rule.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the service bus namepace queue." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." - } - }, - "queueName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace Queue. Required if the template is used in a standalone deployment." - } - }, - "rights": { - "type": "array", - "defaultValue": [], - "allowedValues": [ - "Listen", - "Manage", - "Send" - ], - "metadata": { - "description": "Optional. The rights associated with the rule." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/queues/authorizationRules", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('queueName'), parameters('name'))]", - "properties": { - "rights": "[parameters('rights')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the authorization rule." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The Resource ID of the authorization rule." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/queues/authorizationRules', parameters('namespaceName'), parameters('queueName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the authorization rule was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "queue" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed queue." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed queue." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/queues', parameters('namespaceName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed queue." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "serviceBusNamespace" - ] - }, - "serviceBusNamespace_topics": { - "copy": { - "name": "serviceBusNamespace_topics", - "count": "[length(coalesce(parameters('topics'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Topic-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[coalesce(parameters('topics'), createArray())[copyIndex()].name]" - }, - "authorizationRules": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'authorizationRules')]" - }, - "autoDeleteOnIdle": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'autoDeleteOnIdle')]" - }, - "defaultMessageTimeToLive": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'defaultMessageTimeToLive')]" - }, - "duplicateDetectionHistoryTimeWindow": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow')]" - }, - "enableBatchedOperations": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enableBatchedOperations')]" - }, - "enableExpress": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enableExpress')]" - }, - "enablePartitioning": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'enablePartitioning')]" - }, - "lock": { - "value": "[coalesce(tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" - }, - "maxMessageSizeInKilobytes": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'maxMessageSizeInKilobytes')]" - }, - "requiresDuplicateDetection": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'requiresDuplicateDetection')]" - }, - "roleAssignments": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'roleAssignments')]" - }, - "status": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'status')]" - }, - "supportOrdering": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'supportOrdering')]" - }, - "subscriptions": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'subscriptions')]" - }, - "maxSizeInMegabytes": { - "value": "[tryGet(coalesce(parameters('topics'), createArray())[copyIndex()], 'maxSizeInMegabytes')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "782028791267114581" - }, - "name": "Service Bus Namespace Topic", - "description": "This module deploys a Service Bus Namespace Topic.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - }, - "subscriptionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the service bus namespace topic subscription." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the syubscription is automatically deleted. The minimum duration is 5 minutes." - } - }, - "clientAffineProperties": { - "type": "object", - "properties": { - "clientId": { - "type": "string", - "metadata": { - "description": "Required. Indicates the Client ID of the application that created the client-affine subscription." - } - }, - "isDurable": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is durable or not." - } - }, - "isShared": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. For client-affine subscriptions, this value indicates whether the subscription is shared or not." - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. The properties that are associated with a subscription that is client-affine." - } - }, - "deadLetteringOnMessageExpiration": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "deadLetteringOnFilterEvaluationExceptions": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "enableBatchedOperations": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether server-side batched operations are enabled." - } - }, - "forwardDeadLetteredMessagesTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "forwardTo": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "isClientAffine": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "lockDuration": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." - } - }, - "maxDeliveryCount": { - "type": "int", - "nullable": true, - "metadata": { - "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." - } - }, - "requiresSession": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "status": { - "type": "string", - "allowedValues": [ - "Active", - "Creating", - "Deleting", - "Disabled", - "ReceiveDisabled", - "Renaming", - "Restoring", - "SendDisabled", - "Unknown" - ], - "nullable": true, - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "namespaceName": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace for the Service Bus Topic. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "minLength": 1, - "maxLength": 260, - "metadata": { - "description": "Required. Name of the Service Bus Topic." - } - }, - "maxSizeInMegabytes": { - "type": "int", - "defaultValue": 1024, - "metadata": { - "description": "Optional. The maximum size of the topic in megabytes, which is the size of memory allocated for the topic. Default is 1024." - } - }, - "requiresDuplicateDetection": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. A value indicating if this topic requires duplicate detection." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "defaultValue": "P14D", - "metadata": { - "description": "Optional. ISO 8601 default message timespan to live value. This is the duration after which the message expires, starting from when the message is sent to Service Bus. This is the default value used when TimeToLive is not set on a message itself." - } - }, - "enableBatchedOperations": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Value that indicates whether server-side batched operations are enabled." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "defaultValue": "PT10M", - "metadata": { - "description": "Optional. ISO 8601 timeSpan structure that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "maxMessageSizeInKilobytes": { - "type": "int", - "defaultValue": 1024, - "metadata": { - "description": "Optional. Maximum size (in KB) of the message payload that can be accepted by the topic. This property is only used in Premium today and default is 1024. This property is only used if the `service-bus/namespace` sku is Premium." - } - }, - "supportOrdering": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. Value that indicates whether the topic supports ordering." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the topic is automatically deleted. The minimum duration is 5 minutes." - } - }, - "status": { - "type": "string", - "defaultValue": "Active", - "allowedValues": [ - "Active", - "Disabled", - "Restoring", - "SendDisabled", - "ReceiveDisabled", - "Creating", - "Deleting", - "Renaming", - "Unknown" - ], - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity. - Active, Disabled, Restoring, SendDisabled, ReceiveDisabled, Creating, Deleting, Renaming, Unknown." - } - }, - "enablePartitioning": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether the topic is to be partitioned across multiple message brokers." - } - }, - "enableExpress": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether Express Entities are enabled. An express topic holds a message in memory temporarily before writing it to persistent storage. This property is only used if the `service-bus/namespace` sku is Premium." - } - }, - "authorizationRules": { - "type": "array", - "defaultValue": [ - { - "name": "RootManageSharedAccessKey", - "properties": { - "rights": [ - "Listen", - "Manage", - "Send" - ] - } - } - ], - "metadata": { - "description": "Optional. Authorization Rules for the Service Bus Topic." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "subscriptions": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "Optional. The subscriptions of the topic." - } - } - }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" - } - ], - "builtInRoleNames": { - "Azure Service Bus Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '090c5cfd-751d-490a-894a-3ce6f1109419')]", - "Azure Service Bus Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0')]", - "Azure Service Bus Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '69a216fc-b8fb-44d8-bc22-1f3c2cd27a39')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" - } - }, - "resources": { - "namespace": { - "existing": true, - "type": "Microsoft.ServiceBus/namespaces", - "apiVersion": "2022-10-01-preview", - "name": "[parameters('namespaceName')]" - }, - "topic": { - "type": "Microsoft.ServiceBus/namespaces/topics", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", - "properties": "[union(createObject('autoDeleteOnIdle', parameters('autoDeleteOnIdle'), 'defaultMessageTimeToLive', parameters('defaultMessageTimeToLive'), 'duplicateDetectionHistoryTimeWindow', parameters('duplicateDetectionHistoryTimeWindow'), 'enableBatchedOperations', parameters('enableBatchedOperations'), 'enablePartitioning', parameters('enablePartitioning'), 'requiresDuplicateDetection', parameters('requiresDuplicateDetection'), 'status', parameters('status'), 'supportOrdering', parameters('supportOrdering'), 'maxSizeInMegabytes', parameters('maxSizeInMegabytes')), if(equals(reference('namespace', '2022-10-01-preview', 'full').sku.name, 'Premium'), createObject('enableExpress', parameters('enableExpress'), 'maxMessageSizeInKilobytes', parameters('maxMessageSizeInKilobytes')), createObject()))]", - "dependsOn": [ - "namespace" - ] - }, - "topic_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/topics/{1}', parameters('namespaceName'), parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "topic" - ] - }, - "topic_roleAssignments": { - "copy": { - "name": "topic_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ServiceBus/namespaces/{0}/topics/{1}', parameters('namespaceName'), parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ServiceBus/namespaces/topics', parameters('namespaceName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", - "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "topic" - ] - }, - "topic_authorizationRules": { - "copy": { - "name": "topic_authorizationRules", - "count": "[length(parameters('authorizationRules'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "namespaceName": { - "value": "[parameters('namespaceName')]" - }, - "topicName": { - "value": "[parameters('name')]" - }, - "name": { - "value": "[parameters('authorizationRules')[copyIndex()].name]" - }, - "rights": "[if(contains(parameters('authorizationRules')[copyIndex()], 'rights'), createObject('value', parameters('authorizationRules')[copyIndex()].rights), createObject('value', createArray()))]" - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "6843568331497160185" - }, - "name": "Service Bus Namespace Topic Authorization Rules", - "description": "This module deploys a Service Bus Namespace Topic Authorization Rule.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the service bus namespace topic." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." - } - }, - "topicName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace Topic. Required if the template is used in a standalone deployment." - } - }, - "rights": { - "type": "array", - "defaultValue": [], - "allowedValues": [ - "Listen", - "Manage", - "Send" - ], - "metadata": { - "description": "Optional. The rights associated with the rule." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/topics/authorizationRules", - "apiVersion": "2022-10-01-preview", - "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('topicName'), parameters('name'))]", - "properties": { - "rights": "[parameters('rights')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the authorization rule." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The Resource ID of the authorization rule." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/authorizationRules', parameters('namespaceName'), parameters('topicName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the authorization rule was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "topic" - ] - }, - "topic_subscription": { - "copy": { - "name": "topic_subscription", - "count": "[length(coalesce(parameters('subscriptions'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-subscription-{1}', deployment().name, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[coalesce(parameters('subscriptions'), createArray())[copyIndex()].name]" - }, - "namespaceName": { - "value": "[parameters('namespaceName')]" - }, - "topicName": { - "value": "[parameters('name')]" - }, - "autoDeleteOnIdle": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'autoDeleteOnIdle'), 'PT1H')]" - }, - "defaultMessageTimeToLive": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'defaultMessageTimeToLive'), 'P14D')]" - }, - "duplicateDetectionHistoryTimeWindow": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'duplicateDetectionHistoryTimeWindow'), 'PT10M')]" - }, - "enableBatchedOperations": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'enableBatchedOperations'), true())]" - }, - "clientAffineProperties": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'clientAffineProperties'), createObject())]" - }, - "deadLetteringOnFilterEvaluationExceptions": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'deadLetteringOnFilterEvaluationExceptions'), true())]" - }, - "deadLetteringOnMessageExpiration": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'deadLetteringOnMessageExpiration'), false())]" - }, - "forwardDeadLetteredMessagesTo": { - "value": "[tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'forwardDeadLetteredMessagesTo')]" - }, - "forwardTo": { - "value": "[tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'forwardTo')]" - }, - "isClientAffine": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'isClientAffine'), false())]" - }, - "lockDuration": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'lockDuration'), 'PT1M')]" - }, - "maxDeliveryCount": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'maxDeliveryCount'), 10)]" - }, - "requiresSession": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'requiresSession'), false())]" - }, - "status": { - "value": "[coalesce(tryGet(coalesce(parameters('subscriptions'), createArray())[copyIndex()], 'status'), 'Active')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "13559505347925945415" - }, - "name": "Service Bus Namespace Topic Subscription", - "description": "This module deploys a Service Bus Namespace Topic Subscription.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the service bus namespace topic subscription." - } - }, - "namespaceName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace. Required if the template is used in a standalone deployment." - } - }, - "topicName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent Service Bus Namespace Topic. Required if the template is used in a standalone deployment." - } - }, - "autoDeleteOnIdle": { - "type": "string", - "defaultValue": "PT1H", - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the subscription is automatically deleted. The minimum duration is 5 minutes." - } - }, - "clientAffineProperties": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Optional. The properties that are associated with a subscription that is client-affine." - } - }, - "deadLetteringOnFilterEvaluationExceptions": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "deadLetteringOnMessageExpiration": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether a subscription has dead letter support when a message expires." - } - }, - "defaultMessageTimeToLive": { - "type": "string", - "defaultValue": "P10675199DT2H48M5.4775807S", - "metadata": { - "description": "Optional. ISO 8601 timespan idle interval after which the message expires. The minimum duration is 5 minutes." - } - }, - "duplicateDetectionHistoryTimeWindow": { - "type": "string", - "defaultValue": "PT10M", - "metadata": { - "description": "Optional. ISO 8601 timespan that defines the duration of the duplicate detection history. The default value is 10 minutes." - } - }, - "enableBatchedOperations": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. A value that indicates whether server-side batched operations are enabled." - } - }, - "forwardDeadLetteredMessagesTo": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "forwardTo": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The name of the recipient entity to which all the messages sent to the subscription are forwarded to." - } - }, - "isClientAffine": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "lockDuration": { - "type": "string", - "defaultValue": "PT1M", - "metadata": { - "description": "Optional. ISO 8601 timespan duration of a peek-lock; that is, the amount of time that the message is locked for other receivers. The maximum value for LockDuration is 5 minutes; the default value is 1 minute." - } - }, - "maxDeliveryCount": { - "type": "int", - "defaultValue": 10, - "metadata": { - "description": "Optional. Number of maximum deliveries. A message is automatically deadlettered after this number of deliveries. Default value is 10." - } - }, - "requiresSession": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Optional. A value that indicates whether the subscription supports the concept of session." - } - }, - "status": { - "type": "string", - "defaultValue": "Active", - "allowedValues": [ - "Active", - "Creating", - "Deleting", - "Disabled", - "ReceiveDisabled", - "Renaming", - "Restoring", - "SendDisabled", - "Unknown" - ], - "metadata": { - "description": "Optional. Enumerates the possible values for the status of a messaging entity." - } - } - }, - "resources": [ - { - "type": "Microsoft.ServiceBus/namespaces/topics/subscriptions", - "apiVersion": "2021-11-01", - "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('topicName'), parameters('name'))]", - "properties": { - "autoDeleteOnIdle": "[parameters('autoDeleteOnIdle')]", - "clientAffineProperties": "[parameters('clientAffineProperties')]", - "deadLetteringOnFilterEvaluationExceptions": "[parameters('deadLetteringOnFilterEvaluationExceptions')]", - "deadLetteringOnMessageExpiration": "[parameters('deadLetteringOnMessageExpiration')]", - "defaultMessageTimeToLive": "[parameters('defaultMessageTimeToLive')]", - "duplicateDetectionHistoryTimeWindow": "[parameters('duplicateDetectionHistoryTimeWindow')]", - "enableBatchedOperations": "[parameters('enableBatchedOperations')]", - "forwardDeadLetteredMessagesTo": "[parameters('forwardDeadLetteredMessagesTo')]", - "forwardTo": "[if(not(empty(parameters('forwardTo'))), parameters('forwardTo'), null())]", - "isClientAffine": "[parameters('isClientAffine')]", - "lockDuration": "[parameters('lockDuration')]", - "maxDeliveryCount": "[parameters('maxDeliveryCount')]", - "requiresSession": "[parameters('requiresSession')]", - "status": "[parameters('status')]" - } - } - ], - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the topic subscription." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The Resource ID of the topic subscription." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics/subscriptions', parameters('namespaceName'), parameters('topicName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Resource Group the topic subscription was created in." - }, - "value": "[resourceGroup().name]" - } - } - } - }, - "dependsOn": [ - "namespace", - "topic" - ] - } + "value": "[uniqueString(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), parameters('partitionName'), subscription().id, resourceGroup().id)]" + } + } + ], + "outputs": { + "keyVaultName": { + "type": "string", + "value": "[parameters('keyVaultName')]" + } + } + } + }, + "dependsOn": [ + "[format('partitonNamespace[{0}]', copyIndex())]" + ] + } + }, + "outputs": { + "partitionStorageNames": { + "type": "array", + "items": { + "type": "string" + }, + "copy": { + "count": "[length(parameters('partitions'))]", + "input": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" + } + }, + "partitionServiceBusNames": { + "type": "array", + "items": { + "type": "string" + }, + "copy": { + "count": "[length(parameters('partitions'))]", + "input": "[reference(format('partitonNamespace[{0}]', copyIndex())).outputs.name.value]" + } + } + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Resources/deployments', 'common-blade')]", + "[resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name))]", + "[resourceId('Microsoft.Resources/deployments', 'network-blade')]", + "[resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "service-blade", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "bladeConfig": { + "value": { + "sectionName": "serviceblade", + "displayName": "Service Resources" + } + }, + "tags": { + "value": { + "id": "[variables('rg_unique_id')]" + } + }, + "location": { + "value": "[parameters('location')]" + }, + "enableTelemetry": { + "value": "[variables('enableTelemetry')]" + }, + "osduVersion": "[if(equals(parameters('clusterSoftware').osduVersion, ''), createObject('value', 'master'), createObject('value', parameters('clusterSoftware').osduVersion))]", + "enableSoftwareLoad": "[if(equals(parameters('clusterSoftware').enable, 'false'), createObject('value', false()), createObject('value', true()))]", + "enableOsduCore": "[if(equals(parameters('clusterSoftware').osduCore, 'false'), createObject('value', false()), createObject('value', true()))]", + "enableOsdureference": "[if(equals(parameters('clusterSoftware').osduReference, 'false'), createObject('value', false()), createObject('value', true()))]", + "enableNodeAutoProvisioning": "[if(equals(parameters('clusterConfiguration').enableNodeAutoProvisioning, 'false'), createObject('value', false()), createObject('value', true()))]", + "enablePrivateCluster": "[if(equals(parameters('clusterConfiguration').enablePrivateCluster, 'true'), createObject('value', true()), createObject('value', false()))]", + "enableExperimental": "[if(equals(parameters('experimentalSoftware').enable, 'true'), createObject('value', true()), createObject('value', false()))]", + "enableAdminUI": "[if(equals(parameters('experimentalSoftware').adminUI, 'true'), createObject('value', true()), createObject('value', false()))]", + "emailAddress": { + "value": "[parameters('emailAddress')]" + }, + "applicationClientId": { + "value": "[parameters('applicationClientId')]" + }, + "applicationClientPrincipalOid": { + "value": "[parameters('applicationClientPrincipalOid')]" + }, + "workspaceResourceId": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.resourceId.value]" + }, + "identityId": "[if(variables('enableVnetInjection'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.networkConfiguration.value.identityId), createObject('value', reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.resourceId.value))]", + "managedIdentityName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" + }, + "kvName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultName.value]" + }, + "kvUri": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultUri.value]" + }, + "storageName": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.storageAccountName.value]" + }, + "partitionStorageNames": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionStorageNames.value]" + }, + "partitionServiceBusNames": { + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionServiceBusNames.value]" + }, + "aksSubnetId": "[if(variables('enableVnetInjection'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value), createObject('value', ''))]", + "podSubnetId": "[if(and(variables('enableVnetInjection'), parameters('enablePodSubnet')), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.podSubnetId.value), createObject('value', ''))]", + "vmSize": { + "value": "[parameters('customVMSize')]" + }, + "clusterIngress": "[if(equals(parameters('ingressType'), ''), createObject('value', 'External'), createObject('value', parameters('ingressType')))]", + "serviceCidr": "[if(equals(parameters('clusterNetwork').serviceCidr, ''), createObject('value', '172.16.0.0/16'), createObject('value', parameters('clusterNetwork').serviceCidr))]", + "dnsServiceIP": "[if(equals(parameters('clusterNetwork').dnsServiceIP, ''), createObject('value', '172.16.0.10'), createObject('value', parameters('clusterNetwork').vnet))]", + "softwareBranch": { + "value": "[parameters('clusterSoftware').branch]" + }, + "softwareRepository": { + "value": "[parameters('clusterSoftware').repository]" + }, + "softwareTag": { + "value": "[parameters('clusterSoftware').tag]" + }, + "appSettings": { + "value": [ + { + "name": "Settings:StorageAccountName", + "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionStorageNames.value[0]]", + "contentType": "text/plain", + "label": "configmap-devsample" + }, + { + "name": "client_id", + "value": "[parameters('applicationClientId')]", + "contentType": "text/plain", + "label": "configmap-services" + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "17516859332590438736" + } + }, + "definitions": { + "bladeSettings": { + "type": "object", + "properties": { + "sectionName": { + "type": "string", + "metadata": { + "description": "The name of the section name" + } + }, + "displayName": { + "type": "string", + "metadata": { + "description": "The display name of the section" + } + } + } + }, + "appConfigItem": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "The App Configuration Key" + } + }, + "value": { + "type": "string", + "metadata": { + "description": "The App Configuration Value" + } + }, + "contentType": { + "type": "string", + "metadata": { + "description": "The App Configuration Content Type" + } + }, + "label": { + "type": "string", + "metadata": { + "description": "The App Configuration Label" + } + } + } + } + }, + "parameters": { + "bladeConfig": { + "$ref": "#/definitions/bladeSettings", + "metadata": { + "description": "The configuration for the blade section." + } + }, + "location": { + "type": "string", + "metadata": { + "description": "The location of resources to deploy" + } + }, + "tags": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "The tags to apply to the resources" + } + }, + "enableTelemetry": { + "type": "bool", + "metadata": { + "description": "Feature Flag to Enable Telemetry" + } + }, + "workspaceResourceId": { + "type": "string", + "metadata": { + "description": "The workspace resource Id for diagnostics" + } + }, + "vmSize": { + "type": "string", + "metadata": { + "description": "A Custom VM Size for Internal Pool" + } + }, + "kvName": { + "type": "string", + "metadata": { + "description": "The name of the Key Vault where the secret exists" + } + }, + "kvUri": { + "type": "string", + "metadata": { + "description": "The Uri of the Key Vault where the secret exists" + } + }, + "storageName": { + "type": "string", + "metadata": { + "description": "The name of the Storage Account" + } + }, + "emailAddress": { + "type": "string", + "metadata": { + "description": "Specify the User Email." + } + }, + "applicationClientId": { + "type": "string", + "metadata": { + "description": "Specify the AD Application Client Id." + } + }, + "applicationClientPrincipalOid": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Specify the AD Application Principal Id." + } + }, + "softwareRepository": { + "type": "string", + "metadata": { + "description": "Software GIT Repository URL" + } + }, + "softwareBranch": { + "type": "string", + "metadata": { + "description": "Software GIT Repository Branch" + } + }, + "softwareTag": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Software GIT Repository Tag" + } + }, + "clusterIngress": { + "type": "string", + "defaultValue": "External", + "allowedValues": [ + "Internal", + "External", + "Both", + "" + ], + "metadata": { + "description": "The Cluster Ingress Mode" + } + }, + "enableSoftwareLoad": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Load Software." + } + }, + "enableExperimental": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Load Experimental Software." + } + }, + "enableOsduCore": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Load OSDU Core." + } + }, + "enableOsdureference": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Load OSDU Reference." + } + }, + "enableAdminUI": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Load Admin UI." + } + }, + "osduVersion": { + "type": "string", + "defaultValue": "master", + "allowedValues": [ + "release-0-24", + "release-0-25", + "release-0-26", + "release-0-27", + "master" + ], + "metadata": { + "description": "Specify the OSDU version." + } + }, + "serviceCidr": { + "type": "string", + "minLength": 9, + "maxLength": 18, + "metadata": { + "description": "The address range to use for services" + } + }, + "dnsServiceIP": { + "type": "string", + "minLength": 7, + "maxLength": 15, + "metadata": { + "description": "The IP address to reserve for DNS" + } + }, + "aksSubnetId": { + "type": "string", + "metadata": { + "description": "The id of the subnet to deploy the AKS nodes" + } + }, + "podSubnetId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The id of the subnet to deploy AKS pods" + } + }, + "managedIdentityName": { + "type": "string", + "metadata": { + "description": "The managed identity name for deployment scripts" + } + }, + "identityId": { + "type": "string", + "metadata": { + "description": "The user managed identity for the cluster." + } + }, + "partitionStorageNames": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The name of the partition storage accounts" + } + }, + "partitionServiceBusNames": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The name of the partition service bus namespaces" + } + }, + "sourceHost": { + "type": "string", + "defaultValue": "azureBlob", + "allowedValues": [ + "azureBlob", + "gitRepository" + ], + "metadata": { + "description": "Flux source location for software definition." + } + }, + "appSettings": { + "type": "array", + "items": { + "$ref": "#/definitions/appConfigItem" + } + }, + "dateStamp": { + "type": "string", + "defaultValue": "[utcNow()]" + }, + "enableNodeAutoProvisioning": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Enable Node Auto Provisioning" + } + }, + "enablePrivateCluster": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Feature Flag to Enable Private Cluster" + } + } + }, + "variables": { + "copy": [ + { + "name": "partitionBusSettings", + "count": "[length(parameters('partitionServiceBusNames'))]", + "input": { + "name": "[format('partition_servicebus_name_{0}', copyIndex('partitionBusSettings'))]", + "value": "[parameters('partitionServiceBusNames')[copyIndex('partitionBusSettings')]]", + "contentType": "text/plain", + "label": "configmap-services" + } + }, + { + "name": "partitionStorageSettings", + "count": "[length(parameters('partitionStorageNames'))]", + "input": { + "name": "[format('partition_storage_name_{0}', copyIndex('partitionStorageSettings'))]", + "value": "[parameters('partitionStorageNames')[copyIndex('partitionStorageSettings')]]", + "contentType": "text/plain", + "label": "configmap-services" + } + } + ], + "$fxv#0": { + "release": "v0.39.0" + }, + "version": "[variables('$fxv#0')]", + "serviceLayerConfig": { + "registry": { + "sku": "Basic" + }, + "cluster": { + "tier": "Standard", + "aksVersion": "1.30", + "meshVersion": "asm-1-22", + "vmSize": "Standard_D4pds_v5", + "poolSize": "Standard_D2pds_v5", + "defaultSize": "Standard_D4s_v5" + }, + "gitops": { + "name": "flux-system", + "url": "[if(equals(parameters('softwareRepository'), ''), 'https://github.com/azure/osdu-developer', parameters('softwareRepository'))]", + "branch": "[if(equals(parameters('softwareBranch'), ''), '', parameters('softwareBranch'))]", + "tag": "[if(and(equals(parameters('softwareTag'), ''), equals(parameters('softwareBranch'), '')), variables('version').release, parameters('softwareTag'))]", + "components": "./stamp/components", + "applications": "./stamp/applications", + "experimental": "./stamp/experimental", + "enablePrivateSoftware": "[equals(parameters('sourceHost'), 'azureBlob')]" + } + }, + "federatedIdentityCredentials": [ + { + "name": "federated-ns_default", + "subject": "system:serviceaccount:default:workload-identity-sa" + }, + { + "name": "federated-ns_osdu-core", + "subject": "system:serviceaccount:osdu-core:workload-identity-sa" + }, + { + "name": "federated-ns_airflow", + "subject": "system:serviceaccount:airflow:workload-identity-sa" + }, + { + "name": "federated-ns_postgresql", + "subject": "system:serviceaccount:postgresql:workload-identity-sa" + }, + { + "name": "federated-ns_azappconfig-system", + "subject": "system:serviceaccount:azappconfig-system:az-appconfig-k8s-provider" + }, + { + "name": "federated-ns_osdu-system", + "subject": "system:serviceaccount:osdu-system:workload-identity-sa" + }, + { + "name": "federated-ns_elastic-search", + "subject": "system:serviceaccount:elastic-search:workload-identity-sa" + }, + { + "name": "federated-ns_osdu-auth", + "subject": "system:serviceaccount:osdu-auth:workload-identity-sa" + }, + { + "name": "federated-ns_osdu-reference", + "subject": "system:serviceaccount:osdu-reference:workload-identity-sa" + }, + { + "name": "federated-ns_osdu-experimental", + "subject": "system:serviceaccount:osdu-experimental:workload-identity-sa" + } + ], + "common_helm_values": [ + { + "name": "AZURE_ISTIOAUTH_ENABLED", + "value": "true", + "contentType": "text/plain", + "label": "configmap-common-values" + }, + { + "name": "AZURE_PAAS_PODIDENTITY_ISENABLED", + "value": "false", + "contentType": "text/plain", + "label": "configmap-common-values" + }, + { + "name": "ACCEPT_HTTP", + "value": "true", + "contentType": "text/plain", + "label": "configmap-common-values" + }, + { + "name": "SERVER_PORT", + "value": "80", + "contentType": "text/plain", + "label": "configmap-common-values" + } + ], + "osdu_applications": [ + { + "name": "osduCoreEnabled", + "value": "[toLower(string(parameters('enableOsduCore')))]", + "contentType": "text/plain", + "label": "configmap-osdu-applications" + }, + { + "name": "osduReferenceEnabled", + "value": "[toLower(string(parameters('enableOsdureference')))]", + "contentType": "text/plain", + "label": "configmap-osdu-applications" + }, + { + "name": "adminUIEnabled", + "value": "[toLower(string(parameters('enableAdminUI')))]", + "contentType": "text/plain", + "label": "configmap-osdu-applications" + }, + { + "name": "osduVersion", + "value": "[toLower(string(parameters('osduVersion')))]", + "contentType": "text/plain", + "label": "configmap-osdu-applications" + } + ], + "configMaps": { + "appConfigTemplate": "values.yaml: |\n serviceAccount:\n create: false\n name: \"workload-identity-sa\"\n azure:\n tenantId: {0}\n clientId: {1}\n configEndpoint: {2}\n keyvaultUri: {3}\n keyvaultName: {4}\n appId: {5}\n appOid: {6}\n ingress:\n internalGateway:\n enabled: {7}\n externalGateway:\n enabled: {8}\n " + } + }, + "resources": { + "appIdentity": { + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "name": "[parameters('managedIdentityName')]" + }, + "keyVault": { + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-07-01", + "name": "[parameters('kvName')]" + }, + "keySecret": { + "type": "Microsoft.KeyVault/vaults/secrets", + "apiVersion": "2023-07-01", + "name": "[format('{0}/{1}', parameters('kvName'), 'app-dev-sp-username')]", + "properties": { + "value": "[parameters('applicationClientId')]" + }, + "dependsOn": [ + "keyVault" + ] + }, + "registry": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-container-registry', parameters('bladeConfig').sectionName)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[format('{0}{1}', replace(parameters('bladeConfig').sectionName, '-', ''), uniqueString(resourceGroup().id, parameters('bladeConfig').sectionName))]" + }, + "location": { + "value": "[parameters('location')]" + }, + "tags": { + "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" + }, + "enableTelemetry": { + "value": "[parameters('enableTelemetry')]" + }, + "diagnosticSettings": { + "value": [ + { + "workspaceResourceId": "[parameters('workspaceResourceId')]" + } + ] + }, + "acrSku": { + "value": "[variables('serviceLayerConfig').registry.sku]" + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" + ] + } + }, + "roleAssignments": { + "value": [ + { + "principalId": "[reference('appIdentity').principalId]", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "AcrPull" + } + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14346813384269118868" + }, + "name": "Azure Container Registries (ACR)", + "description": "This module deploys an Azure Container Registry (ACR).", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed topic." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed topic." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces/topics', parameters('namespaceName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed topic." - }, - "value": "[resourceGroup().name]" - } + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." } } }, - "dependsOn": [ - "serviceBusNamespace" - ] + "nullable": true }, - "serviceBusNamespace_privateEndpoints": { - "copy": { - "name": "serviceBusNamespace_privateEndpoints", - "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-serviceBusNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", + "lockType": { + "type": "object", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex()))]" - }, - "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')))))), createObject('value', null()))]", - "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.ServiceBus/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", - "subnetResourceId": { - "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" - }, - "enableTelemetry": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" - }, - "location": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" - }, - "lock": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" - }, - "privateDnsZoneGroup": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" - }, - "roleAssignments": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" - }, - "tags": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" - }, - "customDnsConfigs": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } }, - "ipConfigurations": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } }, - "applicationSecurityGroupResourceIds": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } }, - "customNetworkInterfaceName": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1277254088602407590" - }, - "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } }, - "definitions": { - "privateDnsZoneGroupType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the Private DNS Zone Group." - } - }, - "privateDnsZoneGroupConfigs": { - "type": "array", - "items": { - "$ref": "#/definitions/privateDnsZoneGroupConfigType" - }, - "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." - } - } - } - }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true - }, - "lockType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } - } - }, - "nullable": true - }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } - } - } - }, - "nullable": true - }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } - } - } - }, - "nullable": true - }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } - } - }, - "nullable": true + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "privateDnsZoneGroupConfigType": { + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { "type": "object", "properties": { - "name": { + "fqdn": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group config." + "description": "Required. Fqdn that resolves to private endpoint ip address." } }, - "privateDnsZoneResourceId": { - "type": "string", + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The resource id of the private DNS zone." + "description": "Required. A list of private ip addresses of the private endpoint." } } - }, - "metadata": { - "__bicep_imported_from!": { - "sourceTemplate": "private-dns-zone-group/main.bicep" - } - } - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the private endpoint resource to create." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "nullable": true, - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "privateDnsZoneGroup": { - "$ref": "#/definitions/privateDnsZoneGroupType", - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone group to configure for the private endpoint." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all Resources." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. The lock settings of the service." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } - }, - "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", - "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." - } - }, - "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", - "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } - } - }, - "variables": { - "copy": [ - { - "name": "formattedRoleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", - "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" - } - ], - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." } }, - "resources": { - "avmTelemetry": { - "condition": "[parameters('enableTelemetry')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [], - "outputs": { - "telemetry": { - "type": "String", - "value": "For more information, see https://aka.ms/avm/TelemetryInfo" - } - } - } - } - }, - "privateEndpoint": { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-11-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "copy": [ - { - "name": "applicationSecurityGroups", - "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", - "input": { - "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" - } - } - ], - "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", - "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", - "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", - "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", - "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - } - }, - "privateEndpoint_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", - "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" - }, - "dependsOn": [ - "privateEndpoint" - ] - }, - "privateEndpoint_roleAssignments": { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", - "properties": { - "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", - "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" - }, - "dependsOn": [ - "privateEndpoint" - ] - }, - "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" - }, - "privateEndpointName": { - "value": "[parameters('name')]" - }, - "privateDnsZoneConfigs": { - "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." } }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5805178546717255803" - }, - "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" - }, - "definitions": { - "privateDnsZoneGroupConfigType": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private DNS zone group config." - } - }, - "privateDnsZoneResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of the private DNS zone." - } - } - }, - "metadata": { - "__bicep_export!": true - } - } - }, - "parameters": { - "privateEndpointName": { + "properties": { + "type": "object", + "properties": { + "groupId": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." } }, - "privateDnsZoneConfigs": { - "type": "array", - "items": { - "$ref": "#/definitions/privateDnsZoneGroupConfigType" - }, - "minLength": 1, - "maxLength": 5, + "memberName": { + "type": "string", "metadata": { - "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." } }, - "name": { + "privateIPAddress": { "type": "string", - "defaultValue": "default", "metadata": { - "description": "Optional. The name of the private DNS zone group." - } - } - }, - "variables": { - "copy": [ - { - "name": "privateDnsZoneConfigsVar", - "count": "[length(parameters('privateDnsZoneConfigs'))]", - "input": { - "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", - "properties": { - "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" - } - } + "description": "Required. A private ip address obtained from the private endpoint's subnet." } - ] - }, - "resources": { - "privateEndpoint": { - "existing": true, - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-11-01", - "name": "[parameters('privateEndpointName')]" - }, - "privateDnsZoneGroup": { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-11-01", - "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", - "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] } }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint DNS zone group." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint DNS zone group." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint DNS zone group was deployed into." - }, - "value": "[resourceGroup().name]" - } + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." } } - }, - "dependsOn": [ - "privateEndpoint" - ] + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." } }, - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint." - }, - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" - }, - "customDnsConfig": { - "$ref": "#/definitions/customDnsConfigType", - "metadata": { - "description": "The custom DNS configurations of the private endpoint." - }, - "value": "[reference('privateEndpoint').customDnsConfigs]" - }, - "networkInterfaceIds": { - "type": "array", - "metadata": { - "description": "The IDs of the network interfaces associated with the private endpoint." - }, - "value": "[reference('privateEndpoint').networkInterfaces]" + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "groupId": { - "type": "string", - "metadata": { - "description": "The group Id for the private endpoint Group." - }, - "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "manualPrivateLinkServiceConnections": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Manual PrivateLink Service Connections." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." } } } }, - "dependsOn": [ - "serviceBusNamespace" - ] - } - }, - "outputs": { - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the deployed service bus namespace." - }, - "value": "[resourceId('Microsoft.ServiceBus/namespaces', parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group of the deployed service bus namespace." - }, - "value": "[resourceGroup().name]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the deployed service bus namespace." - }, - "value": "[parameters('name')]" - }, - "systemAssignedMIPrincipalId": { - "type": "string", - "metadata": { - "description": "The principal ID of the system assigned identity." - }, - "value": "[coalesce(tryGet(tryGet(reference('serviceBusNamespace', '2022-10-01-preview', 'full'), 'identity'), 'principalId'), '')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('serviceBusNamespace', '2022-10-01-preview', 'full').location]" + "nullable": true }, - "privateEndpoints": { + "diagnosticSettingType": { "type": "array", - "metadata": { - "description": "The private endpoints of the service bus namespace." - }, - "copy": { - "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", - "input": { - "name": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", - "resourceId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", - "groupId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", - "customDnsConfig": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", - "networkInterfaceIds": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" - } - } - } - } - } - } - }, - "blobUpload": { - "copy": { - "name": "blobUpload", - "count": "[length(parameters('partitions'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-storage-blob-upload-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "storageAccountName": { - "value": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "useExistingManagedIdentity": { - "value": true - }, - "managedIdentityName": { - "value": "[parameters('managedIdentityName')]" - }, - "existingManagedIdentitySubId": { - "value": "[subscription().subscriptionId]" - }, - "existingManagedIdentityResourceGroupName": { - "value": "[resourceGroup().name]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1648875899693105966" - }, - "name": "Blob Upload", - "description": "This module uploads a file to a blob storage account", - "owner": "azure-global-energy" - }, - "parameters": { - "storageAccountName": { - "type": "string", - "defaultValue": "[uniqueString(resourceGroup().id, deployment().name, 'blob')]", - "metadata": { - "description": "Desired name of the storage account" - } - }, - "containerName": { - "type": "string", - "defaultValue": "legal-service-azure-configuration", - "metadata": { - "description": "Name of the blob container" - } - }, - "filename": { - "type": "string", - "defaultValue": "Legal_COO.json", - "metadata": { - "description": "Name of the blob as it is stored in the blob container" - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "The location of the Storage Account and where to deploy the module resources to" - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "How the deployment script should be forced to execute" - } - }, - "rbacRoleNeeded": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Azure RoleId that are required for the DeploymentScript resource to upload blobs" - } - }, - "useExistingManagedIdentity": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Does the Managed Identity already exists, or should be created" - } - }, - "managedIdentityName": { - "type": "string", - "defaultValue": "[format('id-storage-blob-{0}', parameters('location'))]", - "metadata": { - "description": "Name of the Managed Identity resource" - } - }, - "existingManagedIdentitySubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]", - "metadata": { - "description": "For an existing Managed Identity, the Subscription Id it is located in" - } - }, - "existingManagedIdentityResourceGroupName": { - "type": "string", - "defaultValue": "[resourceGroup().name]", - "metadata": { - "description": "For an existing Managed Identity, the Resource Group it is located in" - } - }, - "initialScriptDelay": { - "type": "string", - "defaultValue": "30s", - "metadata": { - "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" - } - }, - "cleanupPreference": { - "type": "string", - "defaultValue": "OnSuccess", - "allowedValues": [ - "OnSuccess", - "OnExpiration", - "Always" - ], - "metadata": { - "description": "When the script resource is cleaned up" - } - } - }, - "variables": { - "$fxv#0": "[{\n \"name\": \"Andorra\",\n \"alpha2\": \"AD\",\n \"numeric\": 16,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Arab Emirates\",\n \"alpha2\": \"AE\",\n \"numeric\": 784,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Afghanistan\",\n \"alpha2\": \"AF\",\n \"numeric\": 4,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Antigua and Barbuda\",\n \"alpha2\": \"AG\",\n \"numeric\": 28,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Anguilla\",\n \"alpha2\": \"AI\",\n \"numeric\": 660,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Albania\",\n \"alpha2\": \"AL\",\n \"numeric\": 8,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Armenia\",\n \"alpha2\": \"AM\",\n \"numeric\": 51,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Netherlands Antilles\",\n \"alpha2\": \"AN\",\n \"numeric\": 530,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Angola\",\n \"alpha2\": \"AO\",\n \"numeric\": 24,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Antarctica\",\n \"alpha2\": \"AQ\",\n \"numeric\": 10,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Argentina\",\n \"alpha2\": \"AR\",\n \"numeric\": 32,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"American Samoa\",\n \"alpha2\": \"AS\",\n \"numeric\": 16,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Austria\",\n \"alpha2\": \"AT\",\n \"numeric\": 40,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Australia\",\n \"alpha2\": \"AU\",\n \"numeric\": 36,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Aruba\",\n \"alpha2\": \"AW\",\n \"numeric\": 533,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Aland Islands\",\n \"alpha2\": \"AX\",\n \"numeric\": 248,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Azerbaijan\",\n \"alpha2\": \"AZ\",\n \"numeric\": 31,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Bosnia and Herzegovina\",\n \"alpha2\": \"BA\",\n \"numeric\": 70,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Barbados\",\n \"alpha2\": \"BB\",\n \"numeric\": 52,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bangladesh\",\n \"alpha2\": \"BD\",\n \"numeric\": 50,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Belgium\",\n \"alpha2\": \"BE\",\n \"numeric\": 56,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Burkina Faso\",\n \"alpha2\": \"BF\",\n \"numeric\": 854,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bulgaria\",\n \"alpha2\": \"BG\",\n \"numeric\": 100,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bahrain\",\n \"alpha2\": \"BH\",\n \"numeric\": 48,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Burundi\",\n \"alpha2\": \"BI\",\n \"numeric\": 108,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Benin\",\n \"alpha2\": \"BJ\",\n \"numeric\": 204,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Barthelemy\",\n \"alpha2\": \"BL\",\n \"numeric\": 652,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bermuda\",\n \"alpha2\": \"BM\",\n \"numeric\": 60,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Brunei Darussalam\",\n \"alpha2\": \"BN\",\n \"numeric\": 96,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bolivia\",\n \"alpha2\": \"BO\",\n \"numeric\": 68,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Brazil\",\n \"alpha2\": \"BR\",\n \"numeric\": 76,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bahamas\",\n \"alpha2\": \"BS\",\n \"numeric\": 44,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bhutan\",\n \"alpha2\": \"BT\",\n \"numeric\": 64,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Bouvet Island\",\n \"alpha2\": \"BV\",\n \"numeric\": 74,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Botswana\",\n \"alpha2\": \"BW\",\n \"numeric\": 72,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Belarus\",\n \"alpha2\": \"BY\",\n \"numeric\": 112,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Belize\",\n \"alpha2\": \"BZ\",\n \"numeric\": 84,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Canada\",\n \"alpha2\": \"CA\",\n \"numeric\": 124,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cocos Islands\",\n \"alpha2\": \"CC\",\n \"numeric\": 166,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"The Democratic Republic of the Congo\",\n \"alpha2\": \"CD\",\n \"numeric\": 180,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Central African Republic\",\n \"alpha2\": \"CF\",\n \"numeric\": 140,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Congo\",\n \"alpha2\": \"CG\",\n \"numeric\": 178,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Switzerland\",\n \"alpha2\": \"CH\",\n \"numeric\": 756,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cote d'Ivoire\",\n \"alpha2\": \"CI\",\n \"numeric\": 384,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cook Islands\",\n \"alpha2\": \"CK\",\n \"numeric\": 184,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Chile\",\n \"alpha2\": \"CL\",\n \"numeric\": 152,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cameroon\",\n \"alpha2\": \"CM\",\n \"numeric\": 120,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"China\",\n \"alpha2\": \"CN\",\n \"numeric\": 156,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Colombia\",\n \"alpha2\": \"CO\",\n \"numeric\": 170,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Costa Rica\",\n \"alpha2\": \"CR\",\n \"numeric\": 188,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cuba\",\n \"alpha2\": \"CU\",\n \"numeric\": 192,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Cape Verde\",\n \"alpha2\": \"CV\",\n \"numeric\": 132,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Christmas Island\",\n \"alpha2\": \"CX\",\n \"numeric\": 162,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cyprus\",\n \"alpha2\": \"CY\",\n \"numeric\": 196,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Czech Republic\",\n \"alpha2\": \"CZ\",\n \"numeric\": 203,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Germany\",\n \"alpha2\": \"DE\",\n \"numeric\": 276,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Djibouti\",\n \"alpha2\": \"DJ\",\n \"numeric\": 262,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Denmark\",\n \"alpha2\": \"DK\",\n \"numeric\": 208,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Dominica\",\n \"alpha2\": \"DM\",\n \"numeric\": 212,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Dominican Republic\",\n \"alpha2\": \"DO\",\n \"numeric\": 214,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Algeria\",\n \"alpha2\": \"DZ\",\n \"numeric\": 12,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ecuador\",\n \"alpha2\": \"EC\",\n \"numeric\": 218,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Estonia\",\n \"alpha2\": \"EE\",\n \"numeric\": 233,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Egypt\",\n \"alpha2\": \"EG\",\n \"numeric\": 818,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Western Sahara\",\n \"alpha2\": \"EH\",\n \"numeric\": 732,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Eritrea\",\n \"alpha2\": \"ER\",\n \"numeric\": 232,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Spain\",\n \"alpha2\": \"ES\",\n \"numeric\": 724,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ethiopia\",\n \"alpha2\": \"ET\",\n \"numeric\": 231,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Finland\",\n \"alpha2\": \"FI\",\n \"numeric\": 246,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Fiji\",\n \"alpha2\": \"FJ\",\n \"numeric\": 242,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Falkland Islands\",\n \"alpha2\": \"FK\",\n \"numeric\": 238,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Federated States of Micronesia\",\n \"alpha2\": \"FM\",\n \"numeric\": 583,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Faroe Islands\",\n \"alpha2\": \"FO\",\n \"numeric\": 234,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"France\",\n \"alpha2\": \"FR\",\n \"numeric\": 250,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gabon\",\n \"alpha2\": \"GA\",\n \"numeric\": 266,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Kingdom\",\n \"alpha2\": \"GB\",\n \"numeric\": 826,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Grenada\",\n \"alpha2\": \"GD\",\n \"numeric\": 308,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Georgia\",\n \"alpha2\": \"GE\",\n \"numeric\": 268,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"French Guiana\",\n \"alpha2\": \"GF\",\n \"numeric\": 254,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guernsey\",\n \"alpha2\": \"GG\",\n \"numeric\": 831,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ghana\",\n \"alpha2\": \"GH\",\n \"numeric\": 288,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gibraltar\",\n \"alpha2\": \"GI\",\n \"numeric\": 292,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Greenland\",\n \"alpha2\": \"GL\",\n \"numeric\": 304,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Gambia\",\n \"alpha2\": \"GM\",\n \"numeric\": 270,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guinea\",\n \"alpha2\": \"GN\",\n \"numeric\": 324,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guadeloupe\",\n \"alpha2\": \"GP\",\n \"numeric\": 312,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Equatorial Guinea\",\n \"alpha2\": \"GQ\",\n \"numeric\": 226,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Greece\",\n \"alpha2\": \"GR\",\n \"numeric\": 300,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"South Georgia and the South Sandwich Islands\",\n \"alpha2\": \"GS\",\n \"numeric\": 239,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guatemala\",\n \"alpha2\": \"GT\",\n \"numeric\": 320,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guam\",\n \"alpha2\": \"GU\",\n \"numeric\": 316,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guinea-Bissau\",\n \"alpha2\": \"GW\",\n \"numeric\": 624,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Guyana\",\n \"alpha2\": \"GY\",\n \"numeric\": 328,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Hong Kong\",\n \"alpha2\": \"HK\",\n \"numeric\": 344,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Heard Island and McDonald Islands\",\n \"alpha2\": \"HM\",\n \"numeric\": 334,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Honduras\",\n \"alpha2\": \"HN\",\n \"numeric\": 340,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Croatia\",\n \"alpha2\": \"HR\",\n \"numeric\": 191,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Haiti\",\n \"alpha2\": \"HT\",\n \"numeric\": 332,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Hungary\",\n \"alpha2\": \"HU\",\n \"numeric\": 348,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Indonesia\",\n \"alpha2\": \"ID\",\n \"numeric\": 360,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Ireland\",\n \"alpha2\": \"IE\",\n \"numeric\": 372,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Israel\",\n \"alpha2\": \"IL\",\n \"numeric\": 376,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Isle of Man\",\n \"alpha2\": \"IM\",\n \"numeric\": 833,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"India\",\n \"alpha2\": \"IN\",\n \"numeric\": 356,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"British Indian Ocean Territory\",\n \"alpha2\": \"IO\",\n \"numeric\": 86,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Iraq\",\n \"alpha2\": \"IQ\",\n \"numeric\": 368,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Islamic Republic of Iran\",\n \"alpha2\": \"IR\",\n \"numeric\": 364,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Iceland\",\n \"alpha2\": \"IS\",\n \"numeric\": 352,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Italy\",\n \"alpha2\": \"IT\",\n \"numeric\": 380,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jersey\",\n \"alpha2\": \"JE\",\n \"numeric\": 832,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jamaica\",\n \"alpha2\": \"JM\",\n \"numeric\": 388,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Jordan\",\n \"alpha2\": \"JO\",\n \"numeric\": 400,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Japan\",\n \"alpha2\": \"JP\",\n \"numeric\": 392,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kenya\",\n \"alpha2\": \"KE\",\n \"numeric\": 404,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kyrgyzstan\",\n \"alpha2\": \"KG\",\n \"numeric\": 417,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Cambodia\",\n \"alpha2\": \"KH\",\n \"numeric\": 116,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kiribati\",\n \"alpha2\": \"KI\",\n \"numeric\": 296,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Comoros\",\n \"alpha2\": \"KM\",\n \"numeric\": 174,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Kitts and Nevis\",\n \"alpha2\": \"KN\",\n \"numeric\": 659,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Democratic People's Republic of Korea\",\n \"alpha2\": \"KP\",\n \"numeric\": 408,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Republic of Korea\",\n \"alpha2\": \"KR\",\n \"numeric\": 410,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kuwait\",\n \"alpha2\": \"KW\",\n \"numeric\": 414,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Cayman Islands\",\n \"alpha2\": \"KY\",\n \"numeric\": 136,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Kazakhstan\",\n \"alpha2\": \"KZ\",\n \"numeric\": 398,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lao People's Democratic Republic\",\n \"alpha2\": \"LA\",\n \"numeric\": 418,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lebanon\",\n \"alpha2\": \"LB\",\n \"numeric\": 422,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Lucia\",\n \"alpha2\": \"LC\",\n \"numeric\": 662,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Liechtenstein\",\n \"alpha2\": \"LI\",\n \"numeric\": 438,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sri Lanka\",\n \"alpha2\": \"LK\",\n \"numeric\": 144,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Liberia\",\n \"alpha2\": \"LR\",\n \"numeric\": 430,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lesotho\",\n \"alpha2\": \"LS\",\n \"numeric\": 426,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Lithuania\",\n \"alpha2\": \"LT\",\n \"numeric\": 440,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Luxembourg\",\n \"alpha2\": \"LU\",\n \"numeric\": 442,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Latvia\",\n \"alpha2\": \"LV\",\n \"numeric\": 428,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Libya\",\n \"alpha2\": \"LY\",\n \"numeric\": 434,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Morocco\",\n \"alpha2\": \"MA\",\n \"numeric\": 504,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Monaco\",\n \"alpha2\": \"MC\",\n \"numeric\": 492,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Republic of Moldova\",\n \"alpha2\": \"MD\",\n \"numeric\": 498,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Montenegro\",\n \"alpha2\": \"ME\",\n \"numeric\": 499,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Martin\",\n \"alpha2\": \"MF\",\n \"numeric\": 663,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Madagascar\",\n \"alpha2\": \"MG\",\n \"numeric\": 450,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Marshall Islands\",\n \"alpha2\": \"MH\",\n \"numeric\": 584,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"The former Yugoslav Republic of Macedonia\",\n \"alpha2\": \"MK\",\n \"numeric\": 807,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mali\",\n \"alpha2\": \"ML\",\n \"numeric\": 466,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Myanmar\",\n \"alpha2\": \"MM\",\n \"numeric\": 104,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mongolia\",\n \"alpha2\": \"MN\",\n \"numeric\": 496,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Macao\",\n \"alpha2\": \"MO\",\n \"numeric\": 446,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Northern Mariana Islands\",\n \"alpha2\": \"MP\",\n \"numeric\": 580,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Martinique\",\n \"alpha2\": \"MQ\",\n \"numeric\": 474,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mauritania\",\n \"alpha2\": \"MR\",\n \"numeric\": 478,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Montserrat\",\n \"alpha2\": \"MS\",\n \"numeric\": 500,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Malta\",\n \"alpha2\": \"MT\",\n \"numeric\": 470,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mauritius\",\n \"alpha2\": \"MU\",\n \"numeric\": 480,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Maldives\",\n \"alpha2\": \"MV\",\n \"numeric\": 462,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Malawi\",\n \"alpha2\": \"MW\",\n \"numeric\": 454,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mexico\",\n \"alpha2\": \"MX\",\n \"numeric\": 484,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Malaysia\",\n \"alpha2\": \"MY\",\n \"numeric\": 458,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Mozambique\",\n \"alpha2\": \"MZ\",\n \"numeric\": 508,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Namibia\",\n \"alpha2\": \"NA\",\n \"numeric\": 516,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"New Caledonia\",\n \"alpha2\": \"NC\",\n \"numeric\": 540,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Niger\",\n \"alpha2\": \"NE\",\n \"numeric\": 562,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Norfolk Island\",\n \"alpha2\": \"NF\",\n \"numeric\": 574,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nigeria\",\n \"alpha2\": \"NG\",\n \"numeric\": 566,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nicaragua\",\n \"alpha2\": \"NI\",\n \"numeric\": 558,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Netherlands\",\n \"alpha2\": \"NL\",\n \"numeric\": 528,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Norway\",\n \"alpha2\": \"NO\",\n \"numeric\": 578,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nepal\",\n \"alpha2\": \"NP\",\n \"numeric\": 524,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Nauru\",\n \"alpha2\": \"NR\",\n \"numeric\": 520,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Niue\",\n \"alpha2\": \"NU\",\n \"numeric\": 570,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"New Zealand\",\n \"alpha2\": \"NZ\",\n \"numeric\": 554,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Oman\",\n \"alpha2\": \"OM\",\n \"numeric\": 512,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Panama\",\n \"alpha2\": \"PA\",\n \"numeric\": 591,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Peru\",\n \"alpha2\": \"PE\",\n \"numeric\": 604,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"French Polynesia\",\n \"alpha2\": \"PF\",\n \"numeric\": 258,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Papua New Guinea\",\n \"alpha2\": \"PG\",\n \"numeric\": 598,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Philippines\",\n \"alpha2\": \"PH\",\n \"numeric\": 608,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Pakistan\",\n \"alpha2\": \"PK\",\n \"numeric\": 586,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Poland\",\n \"alpha2\": \"PL\",\n \"numeric\": 616,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Pierre and Miquelon\",\n \"alpha2\": \"PM\",\n \"numeric\": 666,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Pitcairn\",\n \"alpha2\": \"PN\",\n \"numeric\": 612,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Puerto Rico\",\n \"alpha2\": \"PR\",\n \"numeric\": 630,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Palestinian Territory\",\n \"alpha2\": \"PS\",\n \"numeric\": 275,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Portugal\",\n \"alpha2\": \"PT\",\n \"numeric\": 620,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Palau\",\n \"alpha2\": \"PW\",\n \"numeric\": 585,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Paraguay\",\n \"alpha2\": \"PY\",\n \"numeric\": 600,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Qatar\",\n \"alpha2\": \"QA\",\n \"numeric\": 634,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Reunion\",\n \"alpha2\": \"RE\",\n \"numeric\": 638,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Romania\",\n \"alpha2\": \"RO\",\n \"numeric\": 642,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Serbia\",\n \"alpha2\": \"RS\",\n \"numeric\": 688,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Russian Federation\",\n \"alpha2\": \"RU\",\n \"numeric\": 643,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Rwanda\",\n \"alpha2\": \"RW\",\n \"numeric\": 646,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saudi Arabia\",\n \"alpha2\": \"SA\",\n \"numeric\": 682,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Solomon Islands\",\n \"alpha2\": \"SB\",\n \"numeric\": 90,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Seychelles\",\n \"alpha2\": \"SC\",\n \"numeric\": 690,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sudan\",\n \"alpha2\": \"SD\",\n \"numeric\": 729,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Sweden\",\n \"alpha2\": \"SE\",\n \"numeric\": 752,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Singapore\",\n \"alpha2\": \"SG\",\n \"numeric\": 702,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Helena\",\n \"alpha2\": \"SH\",\n \"numeric\": 654,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Slovenia\",\n \"alpha2\": \"SI\",\n \"numeric\": 705,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Svalbard and Jan Mayen\",\n \"alpha2\": \"SJ\",\n \"numeric\": 744,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Slovakia\",\n \"alpha2\": \"SK\",\n \"numeric\": 703,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Sierra Leone\",\n \"alpha2\": \"SL\",\n \"numeric\": 694,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"San Marino\",\n \"alpha2\": \"SM\",\n \"numeric\": 674,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Senegal\",\n \"alpha2\": \"SN\",\n \"numeric\": 686,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Somalia\",\n \"alpha2\": \"SO\",\n \"numeric\": 706,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Suriname\",\n \"alpha2\": \"SR\",\n \"numeric\": 740,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"South Sudan\",\n \"alpha2\": \"SS\",\n \"numeric\": 728,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Sao Tome and Principe\",\n \"alpha2\": \"ST\",\n \"numeric\": 678,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"El Salvador\",\n \"alpha2\": \"SV\",\n \"numeric\": 222,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Syrian Arab Republic\",\n \"alpha2\": \"SY\",\n \"numeric\": 760,\n \"residencyRisk\": \"Embargoed\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Swaziland\",\n \"alpha2\": \"SZ\",\n \"numeric\": 748,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turks and Caicos Islands\",\n \"alpha2\": \"TC\",\n \"numeric\": 796,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Chad\",\n \"alpha2\": \"TD\",\n \"numeric\": 148,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Togo\",\n \"alpha2\": \"TG\",\n \"numeric\": 768,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Thailand\",\n \"alpha2\": \"TH\",\n \"numeric\": 764,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tajikistan\",\n \"alpha2\": \"TJ\",\n \"numeric\": 762,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tokelau\",\n \"alpha2\": \"TK\",\n \"numeric\": 772,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Timor-Leste\",\n \"alpha2\": \"TL\",\n \"numeric\": 626,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turkmenistan\",\n \"alpha2\": \"TM\",\n \"numeric\": 795,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tunisia\",\n \"alpha2\": \"TN\",\n \"numeric\": 788,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tonga\",\n \"alpha2\": \"TO\",\n \"numeric\": 776,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Turkey\",\n \"alpha2\": \"TR\",\n \"numeric\": 792,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Trinidad and Tobago\",\n \"alpha2\": \"TT\",\n \"numeric\": 780,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Tuvalu\",\n \"alpha2\": \"TV\",\n \"numeric\": 798,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Taiwan, Province of China\",\n \"alpha2\": \"TW\",\n \"numeric\": 158,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United Republic of Tanzania\",\n \"alpha2\": \"TZ\",\n \"numeric\": 834,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Ukraine\",\n \"alpha2\": \"UA\",\n \"numeric\": 804,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Uganda\",\n \"alpha2\": \"UG\",\n \"numeric\": 800,\n \"residencyRisk\": \"Not assigned\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United States Minor Outlying Islands\",\n \"alpha2\": \"UM\",\n \"numeric\": 581,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"United States\",\n \"alpha2\": \"US\",\n \"numeric\": 840,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Uruguay\",\n \"alpha2\": \"UY\",\n \"numeric\": 858,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"Uzbekistan\",\n \"alpha2\": \"UZ\",\n \"numeric\": 860,\n \"residencyRisk\": \"No restriction\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Saint Vincent and the Grenadines\",\n \"alpha2\": \"VC\",\n \"numeric\": 670,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Venezuela\",\n \"alpha2\": \"VE\",\n \"numeric\": 862,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"British Virgin Islands\",\n \"alpha2\": \"VG\",\n \"numeric\": 92,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Virgin Islands, U.S.\",\n \"alpha2\": \"VI\",\n \"numeric\": 850,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Vietnam\",\n \"alpha2\": \"VN\",\n \"numeric\": 704,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Vanuatu\",\n \"alpha2\": \"VU\",\n \"numeric\": 548,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Wallis and Futuna\",\n \"alpha2\": \"WF\",\n \"numeric\": 876,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Samoa\",\n \"alpha2\": \"WS\",\n \"numeric\": 882,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Yemen\",\n \"alpha2\": \"YE\",\n \"numeric\": 887,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": []\n}, {\n \"name\": \"South Africa\",\n \"alpha2\": \"ZA\",\n \"numeric\": 710,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Zambia\",\n \"alpha2\": \"ZM\",\n \"numeric\": 894,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Zimbabwe\",\n \"alpha2\": \"ZW\",\n \"numeric\": 716,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}, {\n \"name\": \"Default\",\n \"alpha2\": \"XX\",\n \"numeric\": 999,\n \"residencyRisk\": \"Default\",\n \"typesNotApplyDataResidency\": [\"Transferred Data\"]\n}\n]\n", - "$fxv#1": "#!/bin/bash\nset -e\n\necho \"Waiting on Identity RBAC replication ($initialDelay)\"\nsleep $initialDelay\n\n# Installing curl\napk add --no-cache curl\n\necho \"$CONTENT\" > ${FILE_NAME}\n\n# Upload the blob, overwriting if it exists\naz storage blob upload -f ${FILE_NAME} -c ${CONTAINER} -n ${FILE_NAME} --overwrite\necho \"Blob ${CONTAINER} uploaded to container ${CONTAINER}, overwriting if it existed.\"" - }, - "resources": [ - { - "condition": "[not(parameters('useExistingManagedIdentity'))]", - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "name": "[parameters('managedIdentityName')]", - "location": "[parameters('location')]" - }, - { - "condition": "[not(empty(parameters('rbacRoleNeeded')))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]", - "name": "[guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRoleNeeded'))]", - "principalId": "[if(parameters('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId)]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" - ] - }, - { - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2023-08-01", - "name": "[format('script-{0}-{1}', parameters('storageAccountName'), replace(replace(parameters('filename'), ':', ''), '/', '-'))]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} - } - }, - "kind": "AzureCLI", - "properties": { - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "azCliVersion": "2.63.0", - "timeout": "PT30M", - "retentionInterval": "PT1H", - "environmentVariables": [ - { - "name": "AZURE_STORAGE_ACCOUNT", - "value": "[parameters('storageAccountName')]" + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } }, - { - "name": "AZURE_STORAGE_KEY", - "value": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2023-04-01').keys[0].value]" + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } }, - { - "name": "CONTENT", - "value": "[variables('$fxv#0')]" + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } }, - { - "name": "FILE_NAME", - "value": "[parameters('filename')]" + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } }, - { - "name": "CONTAINER", - "value": "[parameters('containerName')]" + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } }, - { - "name": "initialDelay", - "value": "[parameters('initialScriptDelay')]" + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } } - ], - "scriptContent": "[variables('$fxv#1')]", - "cleanupPreference": "[parameters('cleanupPreference')]" + } }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", - "[extensionResourceId(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), parameters('rbacRoleNeeded'), if(parameters('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))))]" - ] - } - ] - } - }, - "dependsOn": [ - "[format('partitionStorage[{0}]', copyIndex())]" - ] - }, - "partitionSecrets": { - "copy": { - "name": "partitionSecrets", - "count": "[length(parameters('partitions'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-secrets-{1}', parameters('bladeConfig').sectionName, copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[parameters('kvName')]" - }, - "partitionName": { - "value": "[parameters('partitions')[copyIndex()].name]" - }, - "serviceBusName": { - "value": "[reference(format('partitonNamespace[{0}]', copyIndex())).outputs.name.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3333956665359119971" + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true } }, "parameters": { - "keyVaultName": { - "type": "string", - "metadata": { - "description": "The name of the parent key vault." - } - }, - "partitionName": { - "type": "string", - "metadata": { - "description": "The name of the partition." - } - }, - "serviceBusName": { + "name": { "type": "string", - "metadata": { - "description": "The name of the service bus." - } - } - }, - "variables": { - "serviceBusEndpoint": "[format('{0}/AuthorizationRules/RootManageSharedAccessKey', resourceId('Microsoft.ServiceBus/namespaces', parameters('serviceBusName')))]" - }, - "resources": [ - { - "condition": "[not(equals(parameters('serviceBusName'), 'null'))]", - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-sb-connection', parameters('partitionName')))]", - "properties": { - "value": "[listKeys(variables('serviceBusEndpoint'), '2022-10-01-preview').primaryConnectionString]" + "minLength": 5, + "maxLength": 50, + "metadata": { + "description": "Required. Name of your Azure Container Registry." } }, - { - "condition": "[not(equals(parameters('serviceBusName'), 'null'))]", - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-sb-namespace', parameters('partitionName')))]", - "properties": { - "value": "[parameters('serviceBusName')]" + "acrAdminUserEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable admin user that have push / pull permission to the registry." } }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-endpoint', parameters('partitionName')))]", - "properties": { - "value": "http://elasticsearch-es-http.elastic-search:9200" + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." } }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-username', parameters('partitionName')))]", - "properties": { - "value": "elastic-user" + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." } }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-password', parameters('partitionName')))]", - "properties": { - "value": "[substring(uniqueString(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), parameters('partitionName'), resourceGroup().id), 0, 8)]" + "acrSku": { + "type": "string", + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Tier of your Azure container registry." } }, - { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('keyVaultName'), format('{0}-elastic-key', parameters('partitionName')))]", - "properties": { - "value": "[uniqueString(resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')), parameters('partitionName'), subscription().id, resourceGroup().id)]" - } - } - ], - "outputs": { - "keyVaultName": { - "type": "string", - "value": "[parameters('keyVaultName')]" - } - } - } - }, - "dependsOn": [ - "[format('partitonNamespace[{0}]', copyIndex())]" - ] - } - }, - "outputs": { - "partitionStorageNames": { - "type": "array", - "items": { - "type": "string" - }, - "copy": { - "count": "[length(parameters('partitions'))]", - "input": "[reference(format('partitionStorage[{0}]', copyIndex())).outputs.name.value]" - } - }, - "partitionServiceBusNames": { - "type": "array", - "items": { - "type": "string" - }, - "copy": { - "count": "[length(parameters('partitions'))]", - "input": "[reference(format('partitonNamespace[{0}]', copyIndex())).outputs.name.value]" - } - } - } - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Resources/deployments', 'common-blade')]", - "[resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name))]", - "[resourceId('Microsoft.Resources/deployments', 'network-blade')]", - "[resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "service-blade", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "bladeConfig": { - "value": { - "sectionName": "serviceblade", - "displayName": "Service Resources" - } - }, - "tags": { - "value": { - "id": "[variables('rg_unique_id')]" - } - }, - "location": { - "value": "[parameters('location')]" - }, - "enableTelemetry": { - "value": "[variables('enableTelemetry')]" - }, - "osduVersion": "[if(equals(parameters('clusterSoftware').osduVersion, ''), createObject('value', 'master'), createObject('value', parameters('clusterSoftware').osduVersion))]", - "enableSoftwareLoad": "[if(equals(parameters('clusterSoftware').enable, 'false'), createObject('value', false()), createObject('value', true()))]", - "enableOsduCore": "[if(equals(parameters('clusterSoftware').osduCore, 'false'), createObject('value', false()), createObject('value', true()))]", - "enableOsdureference": "[if(equals(parameters('clusterSoftware').osduReference, 'false'), createObject('value', false()), createObject('value', true()))]", - "enableExperimental": "[if(equals(parameters('experimentalSoftware').enable, 'true'), createObject('value', true()), createObject('value', false()))]", - "enableAdminUI": "[if(equals(parameters('experimentalSoftware').adminUI, 'true'), createObject('value', true()), createObject('value', false()))]", - "emailAddress": { - "value": "[parameters('emailAddress')]" - }, - "applicationClientId": { - "value": "[parameters('applicationClientId')]" - }, - "applicationClientPrincipalOid": { - "value": "[parameters('applicationClientPrincipalOid')]" - }, - "workspaceResourceId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-log-analytics', variables('configuration').name)), '2022-09-01').outputs.resourceId.value]" - }, - "identityId": "[if(variables('enableVnetInjection'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.networkConfiguration.value.identityId), createObject('value', reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.resourceId.value))]", - "managedIdentityName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', format('{0}-user-managed-identity', variables('configuration').name)), '2022-09-01').outputs.name.value]" - }, - "kvName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultName.value]" - }, - "kvUri": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.keyvaultUri.value]" - }, - "storageName": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'common-blade'), '2022-09-01').outputs.storageAccountName.value]" - }, - "partitionStorageNames": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionStorageNames.value]" - }, - "partitionServiceBusNames": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionServiceBusNames.value]" - }, - "aksSubnetId": { - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.aksSubnetId.value]" - }, - "podSubnetId": "[if(parameters('enablePodSubnet'), createObject('value', reference(resourceId('Microsoft.Resources/deployments', 'network-blade'), '2022-09-01').outputs.podSubnetId.value), createObject('value', ''))]", - "customVMSize": { - "value": "[parameters('customVMSize')]" - }, - "clusterSize": "[if(parameters('enableBurstable'), createObject('value', 'Burstable'), createObject('value', 'Standard'))]", - "clusterAdminIds": { - "value": "[parameters('clusterAdminIds')]" - }, - "clusterIngress": "[if(equals(parameters('ingressType'), ''), createObject('value', 'External'), createObject('value', parameters('ingressType')))]", - "serviceCidr": "[if(equals(parameters('clusterNetwork').serviceCidr, ''), createObject('value', '172.16.0.0/16'), createObject('value', parameters('clusterNetwork').serviceCidr))]", - "dnsServiceIP": "[if(equals(parameters('clusterNetwork').dnsServiceIP, ''), createObject('value', '172.16.0.10'), createObject('value', parameters('clusterNetwork').v))]", - "networkPlugin": "[if(parameters('enablePodSubnet'), createObject('value', 'azure'), createObject('value', parameters('clusterNetworkPlugin')))]", - "softwareBranch": { - "value": "[parameters('clusterSoftware').branch]" - }, - "softwareRepository": { - "value": "[parameters('clusterSoftware').repository]" - }, - "softwareTag": { - "value": "[parameters('clusterSoftware').tag]" - }, - "appSettings": { - "value": [ - { - "name": "Settings:StorageAccountName", - "value": "[reference(resourceId('Microsoft.Resources/deployments', 'partition-blade'), '2022-09-01').outputs.partitionStorageNames.value[0]]", - "contentType": "text/plain", - "label": "configmap-devsample" - }, - { - "name": "client_id", - "value": "[parameters('applicationClientId')]", - "contentType": "text/plain", - "label": "configmap-services" - } - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2775664166627701019" - } - }, - "definitions": { - "bladeSettings": { - "type": "object", - "properties": { - "sectionName": { - "type": "string", - "metadata": { - "description": "The name of the section name" - } - }, - "displayName": { - "type": "string", - "metadata": { - "description": "The display name of the section" - } - } - } - }, - "appConfigItem": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "The App Configuration Key" - } - }, - "value": { - "type": "string", - "metadata": { - "description": "The App Configuration Value" - } - }, - "contentType": { - "type": "string", - "metadata": { - "description": "The App Configuration Content Type" - } - }, - "label": { - "type": "string", - "metadata": { - "description": "The App Configuration Label" - } - } - } - } - }, - "parameters": { - "bladeConfig": { - "$ref": "#/definitions/bladeSettings", - "metadata": { - "description": "The configuration for the blade section." - } - }, - "location": { - "type": "string", - "metadata": { - "description": "The location of resources to deploy" - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "The tags to apply to the resources" - } - }, - "enableTelemetry": { - "type": "bool", - "metadata": { - "description": "Feature Flag to Enable Telemetry" - } - }, - "workspaceResourceId": { - "type": "string", - "metadata": { - "description": "The workspace resource Id for diagnostics" - } - }, - "networkPlugin": { - "type": "string" - }, - "clusterSize": { - "type": "string", - "metadata": { - "description": "The size of the solution" - } - }, - "customVMSize": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Override the default server type." - } - }, - "kvName": { - "type": "string", - "metadata": { - "description": "The name of the Key Vault where the secret exists" - } - }, - "kvUri": { - "type": "string", - "metadata": { - "description": "The Uri of the Key Vault where the secret exists" - } - }, - "storageName": { - "type": "string", - "metadata": { - "description": "The name of the Storage Account" - } - }, - "emailAddress": { - "type": "string", - "metadata": { - "description": "Specify the User Email." - } - }, - "applicationClientId": { - "type": "string", - "metadata": { - "description": "Specify the AD Application Client Id." - } - }, - "applicationClientPrincipalOid": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Specify the AD Application Principal Id." - } - }, - "softwareRepository": { - "type": "string", - "metadata": { - "description": "Software GIT Repository URL" - } - }, - "softwareBranch": { - "type": "string", - "metadata": { - "description": "Software GIT Repository Branch" - } - }, - "softwareTag": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Software GIT Repository Tag" - } - }, - "clusterIngress": { - "type": "string", - "defaultValue": "External", - "allowedValues": [ - "Internal", - "External", - "Both", - "" - ], - "metadata": { - "description": "The Cluster Ingress Mode" - } - }, - "enableSoftwareLoad": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Feature Flag to Load Software." - } - }, - "enableExperimental": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Feature Flag to Load Experimental Software." - } - }, - "enableOsduCore": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Feature Flag to Load OSDU Core." - } - }, - "enableOsdureference": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Feature Flag to Load OSDU Reference." - } - }, - "enableAdminUI": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Feature Flag to Load Admin UI." - } - }, - "osduVersion": { - "type": "string", - "defaultValue": "master", - "allowedValues": [ - "release-0-24", - "release-0-25", - "release-0-26", - "release-0-27", - "master" - ], - "metadata": { - "description": "Specify the OSDU version." - } - }, - "clusterAdminIds": { - "type": "array", - "metadata": { - "description": "Optional: Specify the AD Users and/or Groups that can manage the cluster." - } - }, - "serviceCidr": { - "type": "string", - "minLength": 9, - "maxLength": 18, - "metadata": { - "description": "The address range to use for services" - } - }, - "dnsServiceIP": { - "type": "string", - "minLength": 7, - "maxLength": 15, - "metadata": { - "description": "The IP address to reserve for DNS" - } - }, - "aksSubnetId": { - "type": "string" - }, - "podSubnetId": { - "type": "string", - "defaultValue": "" - }, - "managedIdentityName": { - "type": "string", - "metadata": { - "description": "The managed identity name for deployment scripts" - } - }, - "identityId": { - "type": "string", - "metadata": { - "description": "The user managed identity for the cluster." - } - }, - "partitionStorageNames": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "The name of the partition storage accounts" - } - }, - "partitionServiceBusNames": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "The name of the partition service bus namespaces" - } - }, - "enableMonitoring": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Feature Flag to Enable Managed Observability." - } - }, - "appSettings": { - "type": "array", - "items": { - "$ref": "#/definitions/appConfigItem" - } - }, - "dateStamp": { - "type": "string", - "defaultValue": "[utcNow()]" - } - }, - "variables": { - "copy": [ - { - "name": "partitionBusSettings", - "count": "[length(parameters('partitionServiceBusNames'))]", - "input": { - "name": "[format('partition_servicebus_name_{0}', copyIndex('partitionBusSettings'))]", - "value": "[parameters('partitionServiceBusNames')[copyIndex('partitionBusSettings')]]", - "contentType": "text/plain", - "label": "configmap-services" - } - }, - { - "name": "partitionStorageSettings", - "count": "[length(parameters('partitionStorageNames'))]", - "input": { - "name": "[format('partition_storage_name_{0}', copyIndex('partitionStorageSettings'))]", - "value": "[parameters('partitionStorageNames')[copyIndex('partitionStorageSettings')]]", - "contentType": "text/plain", - "label": "configmap-services" + "exportPolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the export policy is enabled or not." + } + }, + "quarantinePolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the quarantine policy is enabled or not." + } + }, + "trustPolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the trust policy is enabled or not." + } + }, + "retentionPolicyStatus": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the retention policy is enabled or not." + } + }, + "retentionPolicyDays": { + "type": "int", + "defaultValue": 15, + "metadata": { + "description": "Optional. The number of days to retain an untagged manifest after which it gets purged." + } + }, + "azureADAuthenticationAsArmPolicyStatus": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled." + } + }, + "softDeletePolicyStatus": { + "type": "string", + "defaultValue": "disabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. Soft Delete policy status. Default is disabled." + } + }, + "softDeletePolicyDays": { + "type": "int", + "defaultValue": 7, + "metadata": { + "description": "Optional. The number of days after which a soft-deleted item is permanently deleted." + } + }, + "dataEndpointEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable a single data endpoint per region for serving data. Not relevant in case of disabled public access. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "publicNetworkAccess": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkRuleSetIpRules are not set. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "networkRuleBypassOptions": { + "type": "string", + "defaultValue": "AzureServices", + "allowedValues": [ + "AzureServices", + "None" + ], + "metadata": { + "description": "Optional. Whether to allow trusted Azure services to access a network restricted registry." + } + }, + "networkRuleSetDefaultAction": { + "type": "string", + "defaultValue": "Deny", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Optional. The default action of allow or deny when no other rules match." + } + }, + "networkRuleSetIpRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The IP ACL rules. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. Note, requires the 'acrSku' to be 'Premium'." + } + }, + "zoneRedundancy": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Whether or not zone redundancy is enabled for this container registry." + } + }, + "replications": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. All replications to create." + } + }, + "webhooks": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. All webhooks to create." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "anonymousPullEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enables registry-wide pull from unauthenticated clients. It's in preview and available in the Standard and Premium service tiers." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "cacheRules": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Array of Cache Rules. Note: This is a preview feature ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache#cache-for-acr-preview))." + } + } + }, + "variables": { + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", + "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6cef56e8-d556-48e5-a04f-b8e64114680f')]", + "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", + "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", + "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", + "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.containerregistry-registry.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "registry": { + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "identity": "[variables('identity')]", + "tags": "[parameters('tags')]", + "sku": { + "name": "[parameters('acrSku')]" + }, + "properties": { + "anonymousPullEnabled": "[parameters('anonymousPullEnabled')]", + "adminUserEnabled": "[parameters('acrAdminUserEnabled')]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('status', 'enabled', 'keyVaultProperties', createObject('identity', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyIdentifier', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), reference('cMKKeyVault::cMKKey').keyUriWithVersion))), null())]", + "policies": { + "azureADAuthenticationAsArmPolicy": { + "status": "[parameters('azureADAuthenticationAsArmPolicyStatus')]" + }, + "exportPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('status', parameters('exportPolicyStatus')), null())]", + "quarantinePolicy": { + "status": "[parameters('quarantinePolicyStatus')]" + }, + "trustPolicy": { + "type": "Notary", + "status": "[parameters('trustPolicyStatus')]" + }, + "retentionPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('days', parameters('retentionPolicyDays'), 'status', parameters('retentionPolicyStatus')), null())]", + "softDeletePolicy": { + "retentionDays": "[parameters('softDeletePolicyDays')]", + "status": "[parameters('softDeletePolicyStatus')]" + } + }, + "dataEndpointEnabled": "[parameters('dataEndpointEnabled')]", + "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSetIpRules'))), 'Disabled', null()))]", + "networkRuleBypassOptions": "[parameters('networkRuleBypassOptions')]", + "networkRuleSet": "[if(not(empty(parameters('networkRuleSetIpRules'))), createObject('defaultAction', parameters('networkRuleSetDefaultAction'), 'ipRules', parameters('networkRuleSetIpRules')), null())]", + "zoneRedundancy": "[if(equals(parameters('acrSku'), 'Premium'), parameters('zoneRedundancy'), null())]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "registry_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_diagnosticSettings": { + "copy": { + "name": "registry_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_roleAssignments": { + "copy": { + "name": "registry_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "registry" + ] + }, + "registry_replications": { + "copy": { + "name": "registry_replications", + "count": "[length(coalesce(parameters('replications'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Replication-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].name]" + }, + "registryName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].location]" + }, + "regionEndpointEnabled": { + "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'regionEndpointEnabled')]" + }, + "zoneRedundancy": { + "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'zoneRedundancy')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10714256463183699741" + }, + "name": "Azure Container Registry (ACR) Replications", + "description": "This module deploys an Azure Container Registry (ACR) Replication.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the replication." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "regionEndpointEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether the replication regional endpoint is enabled. Requests will not be routed to a replication whose regional endpoint is disabled, however its data will continue to be synced with other replications." + } + }, + "zoneRedundancy": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "Disabled", + "Enabled" + ], + "metadata": { + "description": "Optional. Whether or not zone redundancy is enabled for this container registry." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "replication": { + "type": "Microsoft.ContainerRegistry/registries/replications", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "regionEndpointEnabled": "[parameters('regionEndpointEnabled')]", + "zoneRedundancy": "[parameters('zoneRedundancy')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the replication." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the replication." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/replications', parameters('registryName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the replication was created in." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('replication', '2023-06-01-preview', 'full').location]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_cacheRules": { + "copy": { + "name": "registry_cacheRules", + "count": "[length(coalesce(parameters('cacheRules'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Cache-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "registryName": { + "value": "[parameters('name')]" + }, + "sourceRepository": { + "value": "[coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository]" + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'name'), replace(replace(coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository, '/', '-'), '.', '-'))]" + }, + "targetRepository": { + "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'targetRepository'), coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository)]" + }, + "credentialSetResourceId": { + "value": "[tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'credentialSetResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "6942960102258463312" + }, + "name": "Container Registries Cache", + "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache)).", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Required. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-')]", + "metadata": { + "description": "Optional. The name of the cache rule. Will be dereived from the source repository name if not defined." + } + }, + "sourceRepository": { + "type": "string", + "metadata": { + "description": "Required. Source repository pulled from upstream." + } + }, + "targetRepository": { + "type": "string", + "defaultValue": "[parameters('sourceRepository')]", + "metadata": { + "description": "Optional. Target repository specified in docker pull command. E.g.: docker pull myregistry.azurecr.io/{targetRepository}:{tag}." + } + }, + "credentialSetResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the credential store which is associated with the cache rule." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "cacheRule": { + "type": "Microsoft.ContainerRegistry/registries/cacheRules", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "properties": { + "sourceRepository": "[parameters('sourceRepository')]", + "targetRepository": "[parameters('targetRepository')]", + "credentialSetResourceId": "[parameters('credentialSetResourceId')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The Name of the Cache Rule." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Cache Rule." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Cache Rule." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/cacheRules', parameters('registryName'), parameters('name'))]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_webhooks": { + "copy": { + "name": "registry_webhooks", + "count": "[length(coalesce(parameters('webhooks'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Registry-Webhook-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].name]" + }, + "registryName": { + "value": "[parameters('name')]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'location'), parameters('location'))]" + }, + "action": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'action'), createArray('chart_delete', 'chart_push', 'delete', 'push', 'quarantine'))]" + }, + "customHeaders": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'customHeaders')]" + }, + "scope": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'scope')]" + }, + "status": { + "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'status')]" + }, + "serviceUri": { + "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].serviceUri]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "3986666280667981658" + }, + "name": "Azure Container Registry (ACR) Webhooks", + "description": "This module deploys an Azure Container Registry (ACR) Webhook.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "registryName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "defaultValue": "[format('{0}webhook', parameters('registryName'))]", + "minLength": 5, + "maxLength": 50, + "metadata": { + "description": "Optional. The name of the registry webhook." + } + }, + "serviceUri": { + "type": "string", + "metadata": { + "description": "Required. The service URI for the webhook to post notifications." + } + }, + "status": { + "type": "string", + "defaultValue": "enabled", + "allowedValues": [ + "disabled", + "enabled" + ], + "metadata": { + "description": "Optional. The status of the webhook at the time the operation was called." + } + }, + "action": { + "type": "array", + "defaultValue": [ + "chart_delete", + "chart_push", + "delete", + "push", + "quarantine" + ], + "metadata": { + "description": "Optional. The list of actions that trigger the webhook to post notifications." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "customHeaders": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Custom headers that will be added to the webhook notifications." + } + }, + "scope": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The scope of repositories where the event can be triggered. For example, 'foo:*' means events for all tags under repository 'foo'. 'foo:bar' means events for 'foo:bar' only. 'foo' is equivalent to 'foo:latest'. Empty means all events." + } + } + }, + "resources": { + "registry": { + "existing": true, + "type": "Microsoft.ContainerRegistry/registries", + "apiVersion": "2023-06-01-preview", + "name": "[parameters('registryName')]" + }, + "webhook": { + "type": "Microsoft.ContainerRegistry/registries/webhooks", + "apiVersion": "2023-06-01-preview", + "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "actions": "[parameters('action')]", + "customHeaders": "[parameters('customHeaders')]", + "scope": "[parameters('scope')]", + "serviceUri": "[parameters('serviceUri')]", + "status": "[parameters('status')]" + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the webhook." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries/webhooks', parameters('registryName'), parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the webhook." + }, + "value": "[parameters('name')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Azure container registry." + }, + "value": "[resourceGroup().name]" + }, + "actions": { + "type": "array", + "metadata": { + "description": "The actions of the webhook." + }, + "value": "[reference('webhook').actions]" + }, + "status": { + "type": "string", + "metadata": { + "description": "The status of the webhook." + }, + "value": "[reference('webhook').status]" + }, + "provistioningState": { + "type": "string", + "metadata": { + "description": "The provisioning state of the webhook." + }, + "value": "[reference('webhook').provisioningState]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('webhook', '2023-06-01-preview', 'full').location]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + }, + "registry_privateEndpoints": { + "copy": { + "name": "registry_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-registry-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateLinkServiceConnections": { + "value": [ + { + "name": "[parameters('name')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]", + "groupIds": [ + "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry')]" + ] + } + } + ] + }, + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry'), copyIndex()))]" + }, + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "manualPrivateLinkServiceConnections": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "2821141217598568122" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "18168683629401652671" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + } + } + } + }, + "dependsOn": [ + "registry" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The Name of the Azure container registry." + }, + "value": "[parameters('name')]" + }, + "loginServer": { + "type": "string", + "metadata": { + "description": "The reference to the Azure container registry." + }, + "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2019-05-01').loginServer]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the Azure container registry." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Azure container registry." + }, + "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('registry', '2023-06-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('registry', '2023-06-01-preview', 'full').location]" + } + } } - } - ], - "$fxv#0": { - "release": "v0.38.0" - }, - "version": "[variables('$fxv#0')]", - "serviceLayerConfig": { - "registry": { - "sku": "Basic" - }, - "cluster": { - "aksVersion": "1.30", - "meshVersion": "asm-1-22", - "networkPlugin": "[parameters('networkPlugin')]" - }, - "gitops": { - "name": "flux-system", - "url": "[if(equals(parameters('softwareRepository'), ''), 'https://github.com/azure/osdu-developer', parameters('softwareRepository'))]", - "branch": "[if(equals(parameters('softwareBranch'), ''), '', parameters('softwareBranch'))]", - "tag": "[if(and(equals(parameters('softwareTag'), ''), equals(parameters('softwareBranch'), '')), variables('version').release, parameters('softwareTag'))]", - "components": "./stamp/components", - "applications": "./stamp/applications", - "experimental": "./stamp/experimental" - } - }, - "elasticPoolPresets": { - "Burstable": { - "vmSize": "Standard_B4ms" - }, - "Standard": { - "vmSize": "Standard_D4s_v5" - } - }, - "federatedIdentityCredentials": [ - { - "name": "federated-ns_default", - "subject": "system:serviceaccount:default:workload-identity-sa" - }, - { - "name": "federated-ns_osdu-core", - "subject": "system:serviceaccount:osdu-core:workload-identity-sa" - }, - { - "name": "federated-ns_airflow", - "subject": "system:serviceaccount:airflow:workload-identity-sa" - }, - { - "name": "federated-ns_postgresql", - "subject": "system:serviceaccount:postgresql:workload-identity-sa" - }, - { - "name": "federated-ns_azappconfig-system", - "subject": "system:serviceaccount:azappconfig-system:az-appconfig-k8s-provider" - }, - { - "name": "federated-ns_osdu-system", - "subject": "system:serviceaccount:osdu-system:workload-identity-sa" - }, - { - "name": "federated-ns_elastic-search", - "subject": "system:serviceaccount:elastic-search:workload-identity-sa" - }, - { - "name": "federated-ns_osdu-auth", - "subject": "system:serviceaccount:osdu-auth:workload-identity-sa" - }, - { - "name": "federated-ns_osdu-reference", - "subject": "system:serviceaccount:osdu-reference:workload-identity-sa" - }, - { - "name": "federated-ns_osdu-experimental", - "subject": "system:serviceaccount:osdu-experimental:workload-identity-sa" - } - ], - "common_helm_values": [ - { - "name": "AZURE_ISTIOAUTH_ENABLED", - "value": "true", - "contentType": "text/plain", - "label": "configmap-common-values" - }, - { - "name": "AZURE_PAAS_PODIDENTITY_ISENABLED", - "value": "false", - "contentType": "text/plain", - "label": "configmap-common-values" - }, - { - "name": "ACCEPT_HTTP", - "value": "true", - "contentType": "text/plain", - "label": "configmap-common-values" - }, - { - "name": "SERVER_PORT", - "value": "80", - "contentType": "text/plain", - "label": "configmap-common-values" - } - ], - "osdu_applications": [ - { - "name": "osduCoreEnabled", - "value": "[toLower(string(parameters('enableOsduCore')))]", - "contentType": "text/plain", - "label": "configmap-osdu-applications" - }, - { - "name": "osduReferenceEnabled", - "value": "[toLower(string(parameters('enableOsdureference')))]", - "contentType": "text/plain", - "label": "configmap-osdu-applications" - }, - { - "name": "adminUIEnabled", - "value": "[toLower(string(parameters('enableAdminUI')))]", - "contentType": "text/plain", - "label": "configmap-osdu-applications" - }, - { - "name": "osduVersion", - "value": "[toLower(string(parameters('osduVersion')))]", - "contentType": "text/plain", - "label": "configmap-osdu-applications" - } - ], - "configMaps": { - "appConfigTemplate": "values.yaml: |\n serviceAccount:\n create: false\n name: \"workload-identity-sa\"\n azure:\n tenantId: {0}\n clientId: {1}\n configEndpoint: {2}\n keyvaultUri: {3}\n keyvaultName: {4}\n appId: {5}\n appOid: {6}\n ingress:\n internalGateway:\n enabled: {7}\n externalGateway:\n enabled: {8}\n " - }, - "name": "[format('amw{0}{1}', replace(parameters('bladeConfig').sectionName, '-', ''), uniqueString(resourceGroup().id, parameters('bladeConfig').sectionName))]" - }, - "resources": { - "appIdentity": { - "existing": true, - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "name": "[parameters('managedIdentityName')]" - }, - "keyVault": { - "existing": true, - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2023-07-01", - "name": "[parameters('kvName')]" - }, - "keySecret": { - "type": "Microsoft.KeyVault/vaults/secrets", - "apiVersion": "2023-07-01", - "name": "[format('{0}/{1}', parameters('kvName'), 'app-dev-sp-username')]", - "properties": { - "value": "[parameters('applicationClientId')]" }, "dependsOn": [ - "keyVault" + "appIdentity" ] }, - "registry": { + "cluster": { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-container-registry', parameters('bladeConfig').sectionName)]", + "name": "[format('{0}-aks-cluster', parameters('bladeConfig').sectionName)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -29874,6 +29924,12 @@ "location": { "value": "[parameters('location')]" }, + "skuTier": { + "value": "[variables('serviceLayerConfig').cluster.tier]" + }, + "kubernetesVersion": { + "value": "[variables('serviceLayerConfig').cluster.aksVersion]" + }, "tags": { "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" }, @@ -29887,23 +29943,267 @@ } ] }, - "acrSku": { - "value": "[variables('serviceLayerConfig').registry.sku]" + "roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Azure Kubernetes Service RBAC Cluster Admin", + "principalId": "[reference('appIdentity').principalId]", + "principalType": "ServicePrincipal" + }, + { + "roleDefinitionIdOrName": "Kubernetes Agentless Operator", + "principalId": "[reference('appIdentity').principalId]", + "principalType": "ServicePrincipal" + } + ] + }, + "aksServicePrincipalProfile": { + "value": { + "clientId": "msi" + } }, "managedIdentities": { "value": { - "systemAssigned": true, - "userAssignedResourceIds": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" + "systemAssigned": false, + "userAssignedResourcesIds": [ + "[parameters('identityId')]" ] } }, - "roleAssignments": { + "networkPlugin": { + "value": "azure" + }, + "networkPluginMode": "[if(empty(parameters('podSubnetId')), createObject('value', 'overlay'), createObject('value', null()))]", + "networkDataplane": { + "value": "cilium" + }, + "publicNetworkAccess": { + "value": "Enabled" + }, + "outboundType": "[if(empty(parameters('aksSubnetId')), createObject('value', 'managedNATGateway'), createObject('value', 'loadBalancer'))]", + "enablePrivateCluster": { + "value": "[parameters('enablePrivateCluster')]" + }, + "disableLocalAccounts": { + "value": true + }, + "enableRBAC": { + "value": true + }, + "aadProfileManaged": { + "value": true + }, + "nodeResourceGroupLockDown": { + "value": true + }, + "enableAzureDefender": { + "value": true + }, + "enableContainerInsights": { + "value": true + }, + "monitoringWorkspaceId": { + "value": "[parameters('workspaceResourceId')]" + }, + "enableAzureMonitorProfileMetrics": { + "value": true + }, + "costAnalysisEnabled": { + "value": true + }, + "webApplicationRoutingEnabled": { + "value": false + }, + "openServiceMeshEnabled": { + "value": false + }, + "serviceCidr": { + "value": "[parameters('serviceCidr')]" + }, + "dnsServiceIP": { + "value": "[parameters('dnsServiceIP')]" + }, + "enableStorageProfileDiskCSIDriver": { + "value": true + }, + "enableStorageProfileFileCSIDriver": { + "value": true + }, + "enableStorageProfileSnapshotController": { + "value": true + }, + "enableStorageProfileBlobCSIDriver": { + "value": true + }, + "enableKeyvaultSecretsProvider": { + "value": true + }, + "enableSecretRotation": { + "value": true + }, + "enableImageCleaner": { + "value": true + }, + "imageCleanerIntervalHours": { + "value": 24 + }, + "enableOidcIssuerProfile": { + "value": true + }, + "enableWorkloadIdentity": { + "value": true + }, + "azurePolicyEnabled": { + "value": true + }, + "omsAgentEnabled": { + "value": true + }, + "vpaAddon": { + "value": true + }, + "kedaAddon": { + "value": true + }, + "enableNodeAutoProvisioning": { + "value": "[parameters('enableNodeAutoProvisioning')]" + }, + "maintenanceConfiguration": { + "value": { + "maintenanceWindow": { + "schedule": { + "daily": null, + "weekly": { + "intervalWeeks": 1, + "dayOfWeek": "Sunday" + }, + "absoluteMonthly": null, + "relativeMonthly": null + }, + "durationHours": 4, + "utcOffset": "+00:00", + "startDate": "2024-10-01", + "startTime": "00:00" + } + } + }, + "primaryAgentPoolProfile": { "value": [ { - "principalId": "[reference('appIdentity').principalId]", - "principalType": "ServicePrincipal", - "roleDefinitionIdOrName": "AcrPull" + "name": "system", + "mode": "System", + "vmSize": "[if(empty(parameters('vmSize')), variables('serviceLayerConfig').cluster.vmSize, parameters('vmSize'))]", + "enableAutoScaling": "[not(parameters('enableNodeAutoProvisioning'))]", + "count": "[if(parameters('enableNodeAutoProvisioning'), 2, null())]", + "minCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 2)]", + "maxCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 6)]", + "securityProfile": { + "sshAccess": "Disabled" + }, + "osType": "Linux", + "osSKU": "AzureLinux", + "availabilityZones": [ + "1", + "2", + "3" + ], + "vnetSubnetID": "[if(not(empty(parameters('aksSubnetId'))), parameters('aksSubnetId'), null())]", + "podSubnetId": "[if(not(empty(parameters('podSubnetId'))), parameters('podSubnetId'), null())]", + "nodeTaints": [ + "CriticalAddonsOnly=true:NoSchedule" + ] + } + ] + }, + "agentPools": { + "value": [ + { + "name": "default", + "mode": "User", + "vmSize": "[if(empty(parameters('vmSize')), variables('serviceLayerConfig').cluster.defaultSize, parameters('vmSize'))]", + "enableAutoScaling": "[not(parameters('enableNodeAutoProvisioning'))]", + "count": "[if(parameters('enableNodeAutoProvisioning'), 4, null())]", + "minCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 4)]", + "maxCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 20)]", + "sshAccess": "Disabled", + "osType": "Linux", + "osSku": "AzureLinux", + "availabilityZones": [ + "1", + "2", + "3" + ], + "vnetSubnetID": "[if(not(empty(parameters('aksSubnetId'))), parameters('aksSubnetId'), null())]", + "podSubnetId": "[if(not(empty(parameters('podSubnetId'))), parameters('podSubnetId'), null())]" + }, + { + "name": "poolz1", + "mode": "User", + "vmSize": "[if(empty(parameters('vmSize')), variables('serviceLayerConfig').cluster.poolSize, parameters('vmSize'))]", + "enableAutoScaling": "[not(parameters('enableNodeAutoProvisioning'))]", + "minCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 1)]", + "maxCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 3)]", + "count": "[if(parameters('enableNodeAutoProvisioning'), 1, null())]", + "sshAccess": "Disabled", + "osType": "Linux", + "osSku": "AzureLinux", + "availabilityZones": [ + "1" + ], + "vnetSubnetID": "[parameters('aksSubnetId')]", + "podSubnetId": "[parameters('podSubnetId')]", + "nodeTaints": [ + "app=cluster:NoSchedule" + ], + "nodeLabels": { + "app": "cluster" + } + }, + { + "name": "poolz2", + "mode": "User", + "vmSize": "[if(empty(parameters('vmSize')), variables('serviceLayerConfig').cluster.poolSize, parameters('vmSize'))]", + "enableAutoScaling": "[not(parameters('enableNodeAutoProvisioning'))]", + "minCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 1)]", + "maxCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 3)]", + "count": "[if(parameters('enableNodeAutoProvisioning'), 1, null())]", + "sshAccess": "Disabled", + "osType": "Linux", + "osSku": "AzureLinux", + "availabilityZones": [ + "2" + ], + "vnetSubnetID": "[parameters('aksSubnetId')]", + "podSubnetId": "[parameters('podSubnetId')]", + "nodeTaints": [ + "app=cluster:NoSchedule" + ], + "nodeLabels": { + "app": "cluster" + } + }, + { + "name": "poolz3", + "mode": "User", + "vmSize": "[if(empty(parameters('vmSize')), variables('serviceLayerConfig').cluster.poolSize, parameters('vmSize'))]", + "enableAutoScaling": "[not(parameters('enableNodeAutoProvisioning'))]", + "minCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 1)]", + "maxCount": "[if(parameters('enableNodeAutoProvisioning'), null(), 3)]", + "count": "[if(parameters('enableNodeAutoProvisioning'), 1, null())]", + "sshAccess": "Disabled", + "osType": "Linux", + "osSku": "AzureLinux", + "availabilityZones": [ + "3" + ], + "vnetSubnetID": "[parameters('aksSubnetId')]", + "podSubnetId": "[parameters('podSubnetId')]", + "nodeTaints": [ + "app=cluster:NoSchedule" + ], + "nodeLabels": { + "app": "cluster" + } } ] } @@ -29915,14 +30215,330 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "14346813384269118868" + "version": "0.30.23.60470", + "templateHash": "3032066175464562397" + }, + "name": "Azure Kubernetes Service (AKS) Managed Clusters", + "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster." + }, + "definitions": { + "agentPoolType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The name of the agent pool." + } + }, + "availabilityZones": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The availability zones of the agent pool." + } + }, + "count": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The number of agents (VMs) to host docker containers. Allowed values must be in the range of 1 to 100 (inclusive)." + } + }, + "sourceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The source resource ID to create the agent pool from." + } + }, + "enableAutoScaling": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable auto-scaling for the agent pool." + } + }, + "enableEncryptionAtHost": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable encryption at host for the agent pool." + } + }, + "enableFIPS": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable FIPS for the agent pool." + } + }, + "enableNodePublicIP": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable node public IP for the agent pool." + } + }, + "enableUltraSSD": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable Ultra SSD for the agent pool." + } + }, + "gpuInstanceProfile": { + "type": "string", + "allowedValues": [ + "MIG1g", + "MIG2g", + "MIG3g", + "MIG4g", + "MIG7g" + ], + "nullable": true, + "metadata": { + "description": "Optional. The GPU instance profile of the agent pool." + } + }, + "kubeletDiskType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The kubelet disk type of the agent pool." + } + }, + "maxCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum number of agents (VMs) to host docker containers. Allowed values must be in the range of 1 to 100 (inclusive)." + } + }, + "minCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The minimum number of agents (VMs) to host docker containers. Allowed values must be in the range of 1 to 100 (inclusive)." + } + }, + "maxPods": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum number of pods that can run on a node." + } + }, + "minPods": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The minimum number of pods that can run on a node." + } + }, + "mode": { + "type": "string", + "allowedValues": [ + "System", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The mode of the agent pool." + } + }, + "nodeLabels": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The node labels of the agent pool." + } + }, + "nodePublicIpPrefixId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The node public IP prefix ID of the agent pool." + } + }, + "nodeTaints": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The node taints of the agent pool." + } + }, + "orchestratorVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Kubernetes version of the agent pool." + } + }, + "osDiskSizeGB": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The OS disk size in GB of the agent pool." + } + }, + "osDiskType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The OS disk type of the agent pool." + } + }, + "osSku": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The OS SKU of the agent pool." + } + }, + "osType": { + "type": "string", + "allowedValues": [ + "Linux", + "Windows" + ], + "nullable": true, + "metadata": { + "description": "Optional. The OS type of the agent pool." + } + }, + "podSubnetId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The pod subnet ID of the agent pool." + } + }, + "proximityPlacementGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The proximity placement group resource ID of the agent pool." + } + }, + "scaleDownMode": { + "type": "string", + "allowedValues": [ + "Deallocate", + "Delete" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scale down mode of the agent pool." + } + }, + "scaleSetEvictionPolicy": { + "type": "string", + "allowedValues": [ + "Deallocate", + "Delete" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scale set eviction policy of the agent pool." + } + }, + "scaleSetPriority": { + "type": "string", + "allowedValues": [ + "Low", + "Regular", + "Spot" + ], + "nullable": true, + "metadata": { + "description": "Optional. The scale set priority of the agent pool." + } + }, + "spotMaxPrice": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The spot max price of the agent pool." + } + }, + "sshAccess": { + "type": "string", + "allowedValues": [ + "Disabled", + "LocalUser" + ], + "nullable": true, + "metadata": { + "description": "Optional. Whether to enable SSH access to the nodes." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The tags of the agent pool." + } + }, + "type": { + "type": "string", + "allowedValues": [ + "AvailabilitySet", + "VirtualMachineScaleSets" + ], + "nullable": true, + "metadata": { + "description": "Optional. The type of the agent pool." + } + }, + "maxSurge": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The maximum number of nodes that can be created during an upgrade." + } + }, + "vmSize": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The VM size of the agent pool." + } + }, + "vnetSubnetID": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The VNet subnet ID of the agent pool." + } + }, + "workloadRuntime": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The workload runtime of the agent pool." + } + }, + "enableDefaultTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. The enable default telemetry of the agent pool." + } + } + } + }, + "nullable": true }, - "name": "Azure Container Registries (ACR)", - "description": "This module deploys an Azure Container Registry (ACR).", - "owner": "Azure/module-maintainers" - }, - "definitions": { "managedIdentitiesType": { "type": "object", "properties": { @@ -29933,7 +30549,7 @@ "description": "Optional. Enables system assigned managed identity on the resource." } }, - "userAssignedResourceIds": { + "userAssignedResourcesIds": { "type": "array", "items": { "type": "string" @@ -29976,6 +30592,13 @@ "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -30037,181 +30660,6 @@ }, "nullable": true }, - "privateEndpointType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private endpoint." - } - }, - "location": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The location to deploy the private endpoint to." - } - }, - "service": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "privateDnsZoneGroupName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." - } - }, - "privateDnsZoneResourceIds": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." - } - }, - "customDnsConfigs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint ip address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private ip addresses of the private endpoint." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "ipConfigurations": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private ip address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. Specify the type of lock." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } - }, - "manualPrivateLinkServiceConnections": { - "type": "array", - "nullable": true, - "metadata": { - "description": "Optional. Manual PrivateLink Service Connections." - } - }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } - } - } - }, - "nullable": true - }, "diagnosticSettingType": { "type": "array", "items": { @@ -30332,236 +30780,872 @@ }, "nullable": true }, - "customerManagedKeyType": { - "type": "object", - "properties": { - "keyVaultResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." - } - }, - "keyName": { - "type": "string", - "metadata": { - "description": "Required. The name of the customer managed key to use for encryption." - } - }, - "keyVersion": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." - } - }, - "userAssignedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." - } - } - }, - "nullable": true - } - }, - "parameters": { - "name": { + "fluxConfigurationProtectedSettingsType": { + "type": "object", + "properties": { + "sshPrivateKey": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The SSH private key to use for Git authentication." + } + } + }, + "nullable": true + }, + "extensionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The name of the extension." + } + }, + "releaseNamespace": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Namespace where the extension Release must be placed." + } + }, + "targetNamespace": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Namespace where the extension will be created for an Namespace scoped extension." + } + }, + "releaseTrain": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The release train of the extension." + } + }, + "configurationProtectedSettings": { + "$ref": "#/definitions/fluxConfigurationProtectedSettingsType", + "nullable": true, + "metadata": { + "description": "Optional. The configuration protected settings of the extension." + } + }, + "configurationSettings": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. The configuration settings of the extension." + } + }, + "version": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the extension." + } + }, + "configurations": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The flux configurations of the extension." + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "keyVaultNetworkAccess": { + "type": "string", + "allowedValues": [ + "Private", + "Public" + ], + "metadata": { + "description": "Required. Network access of key vault. The possible values are Public and Private. Public means the key vault allows public access from all networks. Private means the key vault disables public access and enables private link. The default value is Public." + } + } + }, + "nullable": true + }, + "maintenanceConfigurationType": { + "type": "object", + "properties": { + "maintenanceWindow": { + "type": "object", + "metadata": { + "description": "Required. Maintenance window for the maintenance configuration." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Specifies the name of the AKS cluster." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Specifies the location of AKS cluster. It picks up Resource Group's location by default." + } + }, + "dnsPrefix": { + "type": "string", + "defaultValue": "[parameters('name')]", + "metadata": { + "description": "Optional. Specifies the DNS prefix specified when creating the managed cluster." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource. Only one type of identity is supported: system-assigned or user-assigned, but not both." + } + }, + "networkDataplane": { + "type": "string", + "nullable": true, + "allowedValues": [ + "azure", + "cilium" + ], + "metadata": { + "description": "Optional. Network dataplane used in the Kubernetes cluster. Not compatible with kubenet network plugin." + } + }, + "networkPlugin": { + "type": "string", + "nullable": true, + "allowedValues": [ + "azure", + "kubenet" + ], + "metadata": { + "description": "Optional. Specifies the network plugin used for building Kubernetes network." + } + }, + "networkPluginMode": { + "type": "string", + "nullable": true, + "allowedValues": [ + "overlay" + ], + "metadata": { + "description": "Optional. Network plugin mode used for building the Kubernetes network. Not compatible with kubenet network plugin." + } + }, + "networkPolicy": { + "type": "string", + "nullable": true, + "allowedValues": [ + "azure", + "calico" + ], + "metadata": { + "description": "Optional. Specifies the network policy used for building Kubernetes network. - calico or azure." + } + }, + "podCidr": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the CIDR notation IP range from which to assign pod IPs when kubenet is used." + } + }, + "serviceCidr": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A CIDR notation IP range from which to assign service cluster IPs. It must not overlap with any Subnet IP ranges." + } + }, + "dnsServiceIP": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr." + } + }, + "loadBalancerSku": { + "type": "string", + "defaultValue": "standard", + "allowedValues": [ + "basic", + "standard" + ], + "metadata": { + "description": "Optional. Specifies the sku of the load balancer used by the virtual machine scale sets used by nodepools." + } + }, + "managedOutboundIPCount": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Outbound IP Count for the Load balancer." + } + }, + "outboundIPResourceIds": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. Outbound IP Resource IDs." + } + }, + "backendPoolType": { + "type": "string", + "defaultValue": "NodeIPConfiguration", + "allowedValues": [ + "NodeIP", + "NodeIPConfiguration" + ], + "metadata": { + "description": "Optional. The type of the managed inbound Load Balancer BackendPool." + } + }, + "outboundType": { + "type": "string", + "defaultValue": "loadBalancer", + "allowedValues": [ + "loadBalancer", + "userDefinedRouting", + "managedNATGateway", + "userAssignedNATGateway" + ], + "metadata": { + "description": "Optional. Specifies outbound (egress) routing method." + } + }, + "skuTier": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Free", + "Premium", + "Standard" + ], + "metadata": { + "description": "Optional. Tier of a managed cluster SKU." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Base", + "allowedValues": [ + "Base", + "Automatic" + ], + "metadata": { + "description": "Optional. AKS Name." + } + }, + "kubernetesVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Version of Kubernetes specified when creating the managed cluster." + } + }, + "adminUsername": { + "type": "string", + "defaultValue": "azureuser", + "metadata": { + "description": "Optional. Specifies the administrator username of Linux virtual machines." + } + }, + "sshPublicKey": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the SSH RSA public key string for the Linux nodes." + } + }, + "aksServicePrincipalProfile": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Conditional. Information about a service principal identity for the cluster to use for manipulating Azure APIs. Required if no managed identities are assigned to the cluster." + } + }, + "aadProfileClientAppID": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The client AAD application ID." + } + }, + "aadProfileServerAppID": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The server AAD application ID." + } + }, + "aadProfileServerAppSecret": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The server AAD application secret." + } + }, + "aadProfileTenantId": { "type": "string", - "minLength": 5, - "maxLength": 50, + "defaultValue": "[subscription().tenantId]", "metadata": { - "description": "Required. Name of your Azure Container Registry." + "description": "Optional. Specifies the tenant ID of the Azure Active Directory used by the AKS cluster for authentication." } }, - "acrAdminUserEnabled": { + "aadProfileAdminGroupObjectIDs": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Specifies the AAD group object IDs that will have admin role of the cluster." + } + }, + "aadProfileManaged": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether to enable managed AAD integration." + } + }, + "enableRBAC": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Whether to enable Kubernetes Role-Based Access Control." + } + }, + "aadProfileEnableAzureRBAC": { + "type": "bool", + "defaultValue": "[parameters('enableRBAC')]", + "metadata": { + "description": "Optional. Specifies whether to enable Azure RBAC for Kubernetes authorization." + } + }, + "disableLocalAccounts": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Enable admin user that have push / pull permission to the registry." + "description": "Optional. If set to true, getting static credentials will be disabled for this cluster. This must only be used on Managed Clusters that are AAD enabled." } }, - "location": { + "nodeResourceGroup": { "type": "string", - "defaultValue": "[resourceGroup().location]", + "defaultValue": "[format('{0}_aks_{1}_nodes', resourceGroup().name, parameters('name'))]", "metadata": { - "description": "Optional. Location for all resources." + "description": "Optional. Name of the resource group containing agent pool nodes." } }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "nodeResourceGroupLockDown": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "Optional. If set to true, the node resource group will be locked down to prevent accidental deletion." } }, - "acrSku": { + "authorizedIPRanges": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. IP ranges are specified in CIDR format, e.g. 137.117.106.88/29. This feature is not compatible with clusters that use Public IP Per Node, or clusters that are using a Basic Load Balancer." + } + }, + "disableRunCommand": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to disable run command for the cluster or not." + } + }, + "publicNetworkAccess": { "type": "string", - "defaultValue": "Basic", + "defaultValue": "Disabled", "allowedValues": [ - "Basic", - "Premium", - "Standard" + "Enabled", + "Disabled", + "SecuredByPerimeter" ], "metadata": { - "description": "Optional. Tier of your Azure container registry." + "description": "Optional. Allow or deny public network access for AKS." } }, - "exportPolicyStatus": { + "enablePrivateCluster": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether to create the cluster as a private cluster or not." + } + }, + "enablePrivateClusterPublicFQDN": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to create additional public FQDN for private cluster or not." + } + }, + "privateDNSZone": { "type": "string", - "defaultValue": "disabled", - "allowedValues": [ - "disabled", - "enabled" - ], + "nullable": true, "metadata": { - "description": "Optional. The value that indicates whether the export policy is enabled or not." + "description": "Optional. Private DNS Zone configuration. Set to 'system' and AKS will create a private DNS zone in the node resource group. Set to '' to disable private DNS Zone creation and use public DNS. Supply the resource ID here of an existing Private DNS zone to use an existing zone." } }, - "quarantinePolicyStatus": { + "primaryAgentPoolProfile": { + "type": "array", + "metadata": { + "description": "Required. Properties of the primary agent pool." + } + }, + "agentPools": { + "$ref": "#/definitions/agentPoolType", + "metadata": { + "description": "Optional. Define one or more secondary/additional agent pools." + } + }, + "maintenanceConfiguration": { + "$ref": "#/definitions/maintenanceConfigurationType", + "metadata": { + "description": "Optional. Whether or not to use AKS Automatic mode." + } + }, + "costAnalysisEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the cost analysis add-on is enabled or not. If Enabled `enableStorageProfileDiskCSIDriver` is set to true as it is needed." + } + }, + "httpApplicationRoutingEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the httpApplicationRouting add-on is enabled or not." + } + }, + "webApplicationRoutingEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the webApplicationRoutingEnabled add-on is enabled or not." + } + }, + "dnsZoneResourceId": { "type": "string", - "defaultValue": "disabled", - "allowedValues": [ - "disabled", - "enabled" - ], + "nullable": true, "metadata": { - "description": "Optional. The value that indicates whether the quarantine policy is enabled or not." + "description": "Optional. Specifies the resource ID of connected DNS zone. It will be ignored if `webApplicationRoutingEnabled` is set to `false`." } }, - "trustPolicyStatus": { + "enableDnsZoneContributorRoleAssignment": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether assing the DNS zone contributor role to the cluster service principal. It will be ignored if `webApplicationRoutingEnabled` is set to `false` or `dnsZoneResourceId` not provided." + } + }, + "ingressApplicationGatewayEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the ingressApplicationGateway (AGIC) add-on is enabled or not." + } + }, + "appGatewayResourceId": { "type": "string", - "defaultValue": "disabled", - "allowedValues": [ - "disabled", - "enabled" - ], + "nullable": true, "metadata": { - "description": "Optional. The value that indicates whether the trust policy is enabled or not." + "description": "Conditional. Specifies the resource ID of connected application gateway. Required if `ingressApplicationGatewayEnabled` is set to `true`." } }, - "retentionPolicyStatus": { + "aciConnectorLinuxEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the aciConnectorLinux add-on is enabled or not." + } + }, + "azurePolicyEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether the azurepolicy add-on is enabled or not. For security reasons, this setting should be enabled." + } + }, + "openServiceMeshEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the openServiceMesh add-on is enabled or not." + } + }, + "istioServiceMeshEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the istioServiceMesh add-on is enabled or not." + } + }, + "istioIngressGatewayEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Specifies whether the Istio Ingress Gateway is enabled or not." + } + }, + "istioIngressGatewayType": { "type": "string", - "defaultValue": "enabled", + "defaultValue": "External", "allowedValues": [ - "disabled", - "enabled" + "Internal", + "External" ], "metadata": { - "description": "Optional. The value that indicates whether the retention policy is enabled or not." + "description": "Specifies the type of the Istio Ingress Gateway." } }, - "retentionPolicyDays": { - "type": "int", - "defaultValue": 15, + "istioRevision": { + "type": "string", + "defaultValue": "asm-1-23", "metadata": { - "description": "Optional. The number of days to retain an untagged manifest after which it gets purged." + "description": "Optional. Specifies the Istio revision to use." } }, - "azureADAuthenticationAsArmPolicyStatus": { + "azurePolicyVersion": { "type": "string", - "defaultValue": "enabled", - "allowedValues": [ - "disabled", - "enabled" - ], + "defaultValue": "v2", "metadata": { - "description": "Optional. The value that indicates whether the policy for using ARM audience token for a container registr is enabled or not. Default is enabled." + "description": "Optional. Specifies the azure policy version to use." } }, - "softDeletePolicyStatus": { + "kubeDashboardEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the kubeDashboard add-on is enabled or not." + } + }, + "enableKeyvaultSecretsProvider": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the KeyvaultSecretsProvider add-on is enabled or not." + } + }, + "enableSecretRotation": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Specifies whether the KeyvaultSecretsProvider add-on uses secret rotation." + } + }, + "autoScalerProfileScanInterval": { "type": "string", - "defaultValue": "disabled", - "allowedValues": [ - "disabled", - "enabled" - ], + "defaultValue": "10s", "metadata": { - "description": "Optional. Soft Delete policy status. Default is disabled." + "description": "Optional. Specifies the scan interval of the auto-scaler of the AKS cluster." } }, - "softDeletePolicyDays": { - "type": "int", - "defaultValue": 7, + "autoScalerProfileScaleDownDelayAfterAdd": { + "type": "string", + "defaultValue": "10m", "metadata": { - "description": "Optional. The number of days after which a soft-deleted item is permanently deleted." + "description": "Optional. Specifies the scale down delay after add of the auto-scaler of the AKS cluster." } }, - "dataEndpointEnabled": { + "autoScalerProfileScaleDownDelayAfterDelete": { + "type": "string", + "defaultValue": "20s", + "metadata": { + "description": "Optional. Specifies the scale down delay after delete of the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileScaleDownDelayAfterFailure": { + "type": "string", + "defaultValue": "3m", + "metadata": { + "description": "Optional. Specifies scale down delay after failure of the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileScaleDownUnneededTime": { + "type": "string", + "defaultValue": "10m", + "metadata": { + "description": "Optional. Specifies the scale down unneeded time of the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileScaleDownUnreadyTime": { + "type": "string", + "defaultValue": "20m", + "metadata": { + "description": "Optional. Specifies the scale down unready time of the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileUtilizationThreshold": { + "type": "string", + "defaultValue": "0.5", + "metadata": { + "description": "Optional. Specifies the utilization threshold of the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileMaxGracefulTerminationSec": { + "type": "string", + "defaultValue": "600", + "metadata": { + "description": "Optional. Specifies the max graceful termination time interval in seconds for the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileBalanceSimilarNodeGroups": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Enable a single data endpoint per region for serving data. Not relevant in case of disabled public access. Note, requires the 'acrSku' to be 'Premium'." + "description": "Optional. Specifies the balance of similar node groups for the auto-scaler of the AKS cluster." } }, - "publicNetworkAccess": { + "autoScalerProfileExpander": { "type": "string", - "nullable": true, + "defaultValue": "random", "allowedValues": [ - "Enabled", - "Disabled" + "least-waste", + "most-pods", + "priority", + "random" ], "metadata": { - "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set and networkRuleSetIpRules are not set. Note, requires the 'acrSku' to be 'Premium'." + "description": "Optional. Specifies the expand strategy for the auto-scaler of the AKS cluster." } }, - "networkRuleBypassOptions": { + "autoScalerProfileMaxEmptyBulkDelete": { "type": "string", - "defaultValue": "AzureServices", - "allowedValues": [ - "AzureServices", - "None" - ], + "defaultValue": "10", "metadata": { - "description": "Optional. Whether to allow trusted Azure services to access a network restricted registry." + "description": "Optional. Specifies the maximum empty bulk delete for the auto-scaler of the AKS cluster." } }, - "networkRuleSetDefaultAction": { + "autoScalerProfileMaxNodeProvisionTime": { "type": "string", - "defaultValue": "Deny", + "defaultValue": "15m", + "metadata": { + "description": "Optional. Specifies the maximum node provisioning time for the auto-scaler of the AKS cluster. Values must be an integer followed by an \"m\". No unit of time other than minutes (m) is supported." + } + }, + "autoScalerProfileMaxTotalUnreadyPercentage": { + "type": "string", + "defaultValue": "45", + "metadata": { + "description": "Optional. Specifies the mximum total unready percentage for the auto-scaler of the AKS cluster. The maximum is 100 and the minimum is 0." + } + }, + "autoScalerProfileNewPodScaleUpDelay": { + "type": "string", + "defaultValue": "0s", + "metadata": { + "description": "Optional. For scenarios like burst/batch scale where you do not want CA to act before the kubernetes scheduler could schedule all the pods, you can tell CA to ignore unscheduled pods before they are a certain age. Values must be an integer followed by a unit (\"s\" for seconds, \"m\" for minutes, \"h\" for hours, etc)." + } + }, + "autoScalerProfileOkTotalUnreadyCount": { + "type": "string", + "defaultValue": "3", + "metadata": { + "description": "Optional. Specifies the OK total unready count for the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileSkipNodesWithLocalStorage": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if nodes with local storage should be skipped for the auto-scaler of the AKS cluster." + } + }, + "autoScalerProfileSkipNodesWithSystemPods": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies if nodes with system pods should be skipped for the auto-scaler of the AKS cluster." + } + }, + "autoUpgradeProfileUpgradeChannel": { + "type": "string", + "defaultValue": "stable", "allowedValues": [ - "Allow", - "Deny" + "node-image", + "none", + "patch", + "rapid", + "stable" ], "metadata": { - "description": "Optional. The default action of allow or deny when no other rules match." + "description": "Optional. Auto-upgrade channel on the AKS cluster." } }, - "networkRuleSetIpRules": { + "podIdentityProfileAllowNetworkPluginKubenet": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Running in Kubenet is disabled by default due to the security related nature of AAD Pod Identity and the risks of IP spoofing." + } + }, + "podIdentityProfileEnable": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the pod identity addon is enabled." + } + }, + "podIdentityProfileUserAssignedIdentities": { "type": "array", "nullable": true, "metadata": { - "description": "Optional. The IP ACL rules. Note, requires the 'acrSku' to be 'Premium'." + "description": "Optional. The pod identities to use in the cluster." } }, - "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "podIdentityProfileUserAssignedIdentityExceptions": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. Note, requires the 'acrSku' to be 'Premium'." + "description": "Optional. The pod identity exceptions to allow." } }, - "zoneRedundancy": { + "enableOidcIssuerProfile": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the The OIDC issuer profile of the Managed Cluster is enabled." + } + }, + "enableWorkloadIdentity": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable Workload Identity. Requires OIDC issuer profile to be enabled." + } + }, + "enableAzureDefender": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable Azure Defender." + } + }, + "enableImageCleaner": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable Image Cleaner for Kubernetes." + } + }, + "imageCleanerIntervalHours": { + "type": "int", + "defaultValue": 24, + "minValue": 24, + "metadata": { + "description": "Optional. The interval in hours Image Cleaner will run. The maximum value is three months." + } + }, + "enablePodSecurityPolicy": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable Kubernetes pod security policy. Requires enabling the pod security policy feature flag on the subscription." + } + }, + "enableStorageProfileBlobCSIDriver": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the AzureBlob CSI Driver for the storage profile is enabled." + } + }, + "enableStorageProfileDiskCSIDriver": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the AzureDisk CSI Driver for the storage profile is enabled." + } + }, + "enableStorageProfileFileCSIDriver": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the AzureFile CSI Driver for the storage profile is enabled." + } + }, + "enableStorageProfileSnapshotController": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether the snapshot controller for the storage profile is enabled." + } + }, + "supportPlan": { "type": "string", - "defaultValue": "Disabled", + "defaultValue": "KubernetesOfficial", "allowedValues": [ - "Disabled", - "Enabled" + "AKSLongTermSupport", + "KubernetesOfficial" ], "metadata": { - "description": "Optional. Whether or not zone redundancy is enabled for this container registry." + "description": "Optional. The support plan for the Managed Cluster." } }, - "replications": { - "type": "array", - "nullable": true, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", "metadata": { - "description": "Optional. All replications to create." + "description": "Optional. The diagnostic settings of the service." } }, - "webhooks": { - "type": "array", + "omsAgentEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Specifies whether the OMS agent is enabled." + } + }, + "monitoringWorkspaceId": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. All webhooks to create." + "description": "Optional. Resource ID of the monitoring log analytics workspace." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." } }, "lock": { @@ -30570,37 +31654,52 @@ "description": "Optional. The lock settings of the service." } }, - "managedIdentities": { - "$ref": "#/definitions/managedIdentitiesType", + "tags": { + "type": "object", + "nullable": true, "metadata": { - "description": "Optional. The managed identity definition for this resource." + "description": "Optional. Tags of the resource." } }, - "tags": { + "diskEncryptionSetResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the disc encryption set to apply to the cluster. For security reasons, this value should be provided." + } + }, + "fluxExtension": { + "$ref": "#/definitions/extensionType", + "metadata": { + "description": "Optional. Settings and configurations for the flux extension." + } + }, + "httpProxyConfig": { "type": "object", "nullable": true, "metadata": { - "description": "Optional. Tags of the resource." + "description": "Optional. Configurations for provisioning the cluster with HTTP proxy servers." } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, + "identityProfile": { + "type": "object", + "nullable": true, "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "description": "Optional. Identities associated with the cluster." } }, - "diagnosticSettings": { - "$ref": "#/definitions/diagnosticSettingType", + "kedaAddon": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Optional. The diagnostic settings of the service." + "description": "Optional. Enables Kubernetes Event-driven Autoscaling (KEDA)." } }, - "anonymousPullEnabled": { + "vpaAddon": { "type": "bool", "defaultValue": false, "metadata": { - "description": "Optional. Enables registry-wide pull from unauthenticated clients. It's in preview and available in the Standard and Premium service tiers." + "description": "Optional. Whether to enable VPA add-on in cluster. Default value is false." } }, "customerManagedKey": { @@ -30609,25 +31708,89 @@ "description": "Optional. The customer managed key definition." } }, - "cacheRules": { - "type": "array", - "nullable": true, + "enableAzureMonitorProfileMetrics": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "Optional. Array of Cache Rules. Note: This is a preview feature ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache#cache-for-acr-preview))." + "description": "Optional. Whether the metric state of the kubenetes cluster is enabled." + } + }, + "enableContainerInsights": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates if Azure Monitor Container Insights Logs Addon is enabled." + } + }, + "disableCustomMetrics": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether custom metrics collection has to be disabled or not. If not specified the default is false. No custom metrics will be emitted if this field is false but the container insights enabled field is false." + } + }, + "disablePrometheusMetricsScraping": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Indicates whether prometheus metrics scraping is disabled or not. If not specified the default is false. No prometheus metrics will be emitted if this field is false but the container insights enabled field is false." + } + }, + "syslogPort": { + "type": "int", + "defaultValue": 28330, + "metadata": { + "description": "Optional. The syslog host port. If not specified, the default port is 28330." + } + }, + "metricLabelsAllowlist": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. A comma-separated list of kubernetes cluster metrics labels." + } + }, + "metricAnnotationsAllowList": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. A comma-separated list of Kubernetes cluster metrics annotations." + } + }, + "enableNodeAutoProvisioning": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable node auto-provisioning." } } }, "variables": { - "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", - "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned,UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), 'SystemAssigned', if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null())), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", "builtInRoleNames": { - "AcrDelete": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c2f4ef07-c644-48eb-af81-4b1b4947fb11')]", - "AcrImageSigner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6cef56e8-d556-48e5-a04f-b8e64114680f')]", - "AcrPull": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", - "AcrPush": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8311e382-0749-4cb8-b61a-304f252e45ec')]", - "AcrQuarantineReader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'cdda3590-29a3-44f6-95f2-9f980659eb04')]", - "AcrQuarantineWriter": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c8d4ff99-41c3-41a8-9f60-21dfdad59608')]", + "Azure Kubernetes Fleet Manager Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '63bb64ad-9799-4770-b5c3-24ed299a07bf')]", + "Azure Kubernetes Fleet Manager RBAC Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '434fb43a-c01c-447e-9f67-c3ad923cfaba')]", + "Azure Kubernetes Fleet Manager RBAC Cluster Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ab4d3d-a1bf-4477-8ad9-8359bc988f69')]", + "Azure Kubernetes Fleet Manager RBAC Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '30b27cfc-9c84-438e-b0ce-70e35255df80')]", + "Azure Kubernetes Fleet Manager RBAC Writer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5af6afb3-c06c-4fa4-8848-71a8aee05683')]", + "Azure Kubernetes Service Cluster Admin Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0ab0b1a8-8aac-4efd-b8c2-3ee1fb270be8')]", + "Azure Kubernetes Service Cluster Monitoring User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1afdec4b-e479-420e-99e7-f82237c7c5e6')]", + "Azure Kubernetes Service Cluster User Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4abbcc35-e782-43d8-92c5-2d3f1bd2253f')]", + "Azure Kubernetes Service Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'ed7f3fbd-7b88-4dd4-9017-9adb7ce333f8')]", + "Azure Kubernetes Service RBAC Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3498e952-d568-435e-9b2c-8d77e338d7f7')]", + "Azure Kubernetes Service RBAC Cluster Admin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b')]", + "Azure Kubernetes Service RBAC Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f6c6a51-bcf8-42ba-9220-52d62157d7db')]", + "Azure Kubernetes Service RBAC Writer": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a7ffa36f-339b-4b5c-8bdf-e2c188b2c0eb')]", "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Kubernetes Agentless Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'd5a2ae44-610b-4500-93be-660a0c5f5ca6')]", "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", @@ -30650,8 +31813,8 @@ "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.containerregistry-registry.{0}.{1}', replace('0.1.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.containerservice-managedcluster.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -30676,80 +31839,196 @@ "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" }, - "cMKUserAssignedIdentity": { - "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", - "existing": true, - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", - "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", - "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" - }, - "registry": { - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2023-06-01-preview", + "managedCluster": { + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2024-04-02-preview", "name": "[parameters('name')]", "location": "[parameters('location')]", - "identity": "[variables('identity')]", "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", "sku": { - "name": "[parameters('acrSku')]" - }, - "properties": { - "anonymousPullEnabled": "[parameters('anonymousPullEnabled')]", - "adminUserEnabled": "[parameters('acrAdminUserEnabled')]", - "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('status', 'enabled', 'keyVaultProperties', createObject('identity', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyIdentifier', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), format('{0}/{1}', reference('cMKKeyVault::cMKKey').keyUri, parameters('customerManagedKey').keyVersion), reference('cMKKeyVault::cMKKey').keyUriWithVersion))), null())]", - "policies": { - "azureADAuthenticationAsArmPolicy": { - "status": "[parameters('azureADAuthenticationAsArmPolicyStatus')]" + "name": "[parameters('skuName')]", + "tier": "[parameters('skuTier')]" + }, + "properties": { + "httpProxyConfig": "[parameters('httpProxyConfig')]", + "identityProfile": "[parameters('identityProfile')]", + "diskEncryptionSetID": "[parameters('diskEncryptionSetResourceId')]", + "kubernetesVersion": "[parameters('kubernetesVersion')]", + "dnsPrefix": "[parameters('dnsPrefix')]", + "agentPoolProfiles": "[parameters('primaryAgentPoolProfile')]", + "linuxProfile": "[if(not(empty(parameters('sshPublicKey'))), createObject('adminUsername', parameters('adminUsername'), 'ssh', createObject('publicKeys', createArray(createObject('keyData', coalesce(parameters('sshPublicKey'), ''))))), null())]", + "servicePrincipalProfile": "[parameters('aksServicePrincipalProfile')]", + "metricsProfile": { + "costAnalysis": { + "enabled": "[if(equals(parameters('skuTier'), 'free'), false(), parameters('costAnalysisEnabled'))]" + } + }, + "ingressProfile": { + "webAppRouting": { + "enabled": "[parameters('webApplicationRoutingEnabled')]", + "dnsZoneResourceIds": "[if(not(empty(parameters('dnsZoneResourceId'))), createArray(parameters('dnsZoneResourceId')), null())]" + } + }, + "addonProfiles": { + "httpApplicationRouting": { + "enabled": "[parameters('httpApplicationRoutingEnabled')]" }, - "exportPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('status', parameters('exportPolicyStatus')), null())]", - "quarantinePolicy": { - "status": "[parameters('quarantinePolicyStatus')]" + "ingressApplicationGateway": { + "enabled": "[and(parameters('ingressApplicationGatewayEnabled'), not(empty(parameters('appGatewayResourceId'))))]", + "config": "[if(and(parameters('ingressApplicationGatewayEnabled'), not(empty(parameters('appGatewayResourceId')))), createObject('applicationGatewayId', parameters('appGatewayResourceId'), 'effectiveApplicationGatewayId', parameters('appGatewayResourceId')), null())]" }, - "trustPolicy": { - "type": "Notary", - "status": "[parameters('trustPolicyStatus')]" + "omsagent": { + "enabled": "[and(parameters('omsAgentEnabled'), not(empty(parameters('monitoringWorkspaceId'))))]", + "config": "[if(and(parameters('omsAgentEnabled'), not(empty(parameters('monitoringWorkspaceId')))), createObject('logAnalyticsWorkspaceResourceID', parameters('monitoringWorkspaceId')), null())]" }, - "retentionPolicy": "[if(equals(parameters('acrSku'), 'Premium'), createObject('days', parameters('retentionPolicyDays'), 'status', parameters('retentionPolicyStatus')), null())]", - "softDeletePolicy": { - "retentionDays": "[parameters('softDeletePolicyDays')]", - "status": "[parameters('softDeletePolicyStatus')]" + "aciConnectorLinux": { + "enabled": "[parameters('aciConnectorLinuxEnabled')]" + }, + "azurepolicy": { + "enabled": "[parameters('azurePolicyEnabled')]", + "config": "[if(parameters('azurePolicyEnabled'), createObject('version', parameters('azurePolicyVersion')), null())]" + }, + "openServiceMesh": { + "enabled": "[parameters('openServiceMeshEnabled')]", + "config": "[if(parameters('openServiceMeshEnabled'), createObject(), null())]" + }, + "kubeDashboard": { + "enabled": "[parameters('kubeDashboardEnabled')]" + }, + "azureKeyvaultSecretsProvider": { + "enabled": "[parameters('enableKeyvaultSecretsProvider')]", + "config": "[if(parameters('enableKeyvaultSecretsProvider'), createObject('enableSecretRotation', toLower(string(parameters('enableSecretRotation')))), null())]" } }, - "dataEndpointEnabled": "[parameters('dataEndpointEnabled')]", - "publicNetworkAccess": "[if(not(empty(parameters('publicNetworkAccess'))), parameters('publicNetworkAccess'), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSetIpRules'))), 'Disabled', null()))]", - "networkRuleBypassOptions": "[parameters('networkRuleBypassOptions')]", - "networkRuleSet": "[if(not(empty(parameters('networkRuleSetIpRules'))), createObject('defaultAction', parameters('networkRuleSetDefaultAction'), 'ipRules', parameters('networkRuleSetIpRules')), null())]", - "zoneRedundancy": "[if(equals(parameters('acrSku'), 'Premium'), parameters('zoneRedundancy'), null())]" - }, - "dependsOn": [ - "cMKKeyVault", - "cMKUserAssignedIdentity" - ] + "oidcIssuerProfile": "[if(parameters('enableOidcIssuerProfile'), createObject('enabled', parameters('enableOidcIssuerProfile')), null())]", + "enableRBAC": "[parameters('enableRBAC')]", + "disableLocalAccounts": "[parameters('disableLocalAccounts')]", + "nodeResourceGroup": "[parameters('nodeResourceGroup')]", + "nodeResourceGroupProfile": { + "restrictionLevel": "[if(parameters('nodeResourceGroupLockDown'), 'ReadOnly', 'Unrestricted')]" + }, + "enablePodSecurityPolicy": "[parameters('enablePodSecurityPolicy')]", + "workloadAutoScalerProfile": { + "keda": { + "enabled": "[parameters('kedaAddon')]" + }, + "verticalPodAutoscaler": { + "enabled": "[parameters('vpaAddon')]" + } + }, + "networkProfile": { + "networkDataplane": "[parameters('networkDataplane')]", + "networkPlugin": "[parameters('networkPlugin')]", + "networkPluginMode": "[parameters('networkPluginMode')]", + "networkPolicy": "[parameters('networkPolicy')]", + "podCidr": "[parameters('podCidr')]", + "serviceCidr": "[parameters('serviceCidr')]", + "dnsServiceIP": "[parameters('dnsServiceIP')]", + "outboundType": "[parameters('outboundType')]", + "loadBalancerSku": "[parameters('loadBalancerSku')]", + "loadBalancerProfile": { + "managedOutboundIPs": "[if(not(equals(parameters('managedOutboundIPCount'), 0)), createObject('count', parameters('managedOutboundIPCount')), null())]", + "outboundIPs": "[if(not(empty(parameters('outboundIPResourceIds'))), createObject('publicIPs', map(parameters('outboundIPResourceIds'), lambda('id', createObject('id', lambdaVariables('id'))))), null())]", + "effectiveOutboundIPs": [], + "backendPoolType": "[parameters('backendPoolType')]" + } + }, + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "aadProfile": { + "clientAppID": "[parameters('aadProfileClientAppID')]", + "serverAppID": "[parameters('aadProfileServerAppID')]", + "serverAppSecret": "[parameters('aadProfileServerAppSecret')]", + "managed": "[parameters('aadProfileManaged')]", + "enableAzureRBAC": "[parameters('aadProfileEnableAzureRBAC')]", + "adminGroupObjectIDs": "[parameters('aadProfileAdminGroupObjectIDs')]", + "tenantID": "[parameters('aadProfileTenantId')]" + }, + "autoScalerProfile": { + "balance-similar-node-groups": "[toLower(string(parameters('autoScalerProfileBalanceSimilarNodeGroups')))]", + "expander": "[parameters('autoScalerProfileExpander')]", + "max-empty-bulk-delete": "[parameters('autoScalerProfileMaxEmptyBulkDelete')]", + "max-graceful-termination-sec": "[parameters('autoScalerProfileMaxGracefulTerminationSec')]", + "max-node-provision-time": "[parameters('autoScalerProfileMaxNodeProvisionTime')]", + "max-total-unready-percentage": "[parameters('autoScalerProfileMaxTotalUnreadyPercentage')]", + "new-pod-scale-up-delay": "[parameters('autoScalerProfileNewPodScaleUpDelay')]", + "ok-total-unready-count": "[parameters('autoScalerProfileOkTotalUnreadyCount')]", + "scale-down-delay-after-add": "[parameters('autoScalerProfileScaleDownDelayAfterAdd')]", + "scale-down-delay-after-delete": "[parameters('autoScalerProfileScaleDownDelayAfterDelete')]", + "scale-down-delay-after-failure": "[parameters('autoScalerProfileScaleDownDelayAfterFailure')]", + "scale-down-unneeded-time": "[parameters('autoScalerProfileScaleDownUnneededTime')]", + "scale-down-unready-time": "[parameters('autoScalerProfileScaleDownUnreadyTime')]", + "scale-down-utilization-threshold": "[parameters('autoScalerProfileUtilizationThreshold')]", + "scan-interval": "[parameters('autoScalerProfileScanInterval')]", + "skip-nodes-with-local-storage": "[toLower(string(parameters('autoScalerProfileSkipNodesWithLocalStorage')))]", + "skip-nodes-with-system-pods": "[toLower(string(parameters('autoScalerProfileSkipNodesWithSystemPods')))]" + }, + "autoUpgradeProfile": { + "upgradeChannel": "[parameters('autoUpgradeProfileUpgradeChannel')]" + }, + "apiServerAccessProfile": { + "authorizedIPRanges": "[parameters('authorizedIPRanges')]", + "disableRunCommand": "[parameters('disableRunCommand')]", + "enablePrivateCluster": "[parameters('enablePrivateCluster')]", + "enablePrivateClusterPublicFQDN": "[parameters('enablePrivateClusterPublicFQDN')]", + "privateDNSZone": "[parameters('privateDNSZone')]" + }, + "azureMonitorProfile": { + "containerInsights": "[if(parameters('enableContainerInsights'), createObject('enabled', parameters('enableContainerInsights'), 'logAnalyticsWorkspaceResourceId', if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), null()), 'disableCustomMetrics', parameters('disableCustomMetrics'), 'disablePrometheusMetricsScraping', parameters('disablePrometheusMetricsScraping'), 'syslogPort', parameters('syslogPort')), null())]", + "metrics": "[if(parameters('enableAzureMonitorProfileMetrics'), createObject('enabled', parameters('enableAzureMonitorProfileMetrics'), 'kubeStateMetrics', createObject('metricLabelsAllowlist', parameters('metricLabelsAllowlist'), 'metricAnnotationsAllowList', parameters('metricAnnotationsAllowList'))), null())]" + }, + "podIdentityProfile": { + "allowNetworkPluginKubenet": "[parameters('podIdentityProfileAllowNetworkPluginKubenet')]", + "enabled": "[parameters('podIdentityProfileEnable')]", + "userAssignedIdentities": "[parameters('podIdentityProfileUserAssignedIdentities')]", + "userAssignedIdentityExceptions": "[parameters('podIdentityProfileUserAssignedIdentityExceptions')]" + }, + "securityProfile": { + "defender": "[if(parameters('enableAzureDefender'), createObject('securityMonitoring', createObject('enabled', parameters('enableAzureDefender')), 'logAnalyticsWorkspaceResourceId', parameters('monitoringWorkspaceId')), null())]", + "workloadIdentity": "[if(parameters('enableWorkloadIdentity'), createObject('enabled', parameters('enableWorkloadIdentity')), null())]", + "imageCleaner": "[if(parameters('enableImageCleaner'), createObject('enabled', parameters('enableImageCleaner'), 'intervalHours', parameters('imageCleanerIntervalHours')), null())]" + }, + "serviceMeshProfile": "[if(parameters('istioServiceMeshEnabled'), createObject('istio', createObject('components', createObject('ingressGateways', if(parameters('istioIngressGatewayEnabled'), createArray(createObject('enabled', true(), 'mode', parameters('istioIngressGatewayType'))), null())), 'revisions', createArray(parameters('istioRevision'))), 'mode', 'Istio'), null())]", + "storageProfile": { + "blobCSIDriver": { + "enabled": "[parameters('enableStorageProfileBlobCSIDriver')]" + }, + "diskCSIDriver": { + "enabled": "[if(and(equals(parameters('costAnalysisEnabled'), true()), not(equals(parameters('skuTier'), 'free'))), true(), parameters('enableStorageProfileDiskCSIDriver'))]" + }, + "fileCSIDriver": { + "enabled": "[parameters('enableStorageProfileFileCSIDriver')]" + }, + "snapshotController": { + "enabled": "[parameters('enableStorageProfileSnapshotController')]" + } + }, + "supportPlan": "[parameters('supportPlan')]", + "nodeProvisioningProfile": "[if(parameters('enableNodeAutoProvisioning'), createObject('mode', 'Auto'), null())]" + } }, - "registry_lock": { + "managedCluster_lock": { "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('name'))]", "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "registry" + "managedCluster" ] }, - "registry_diagnosticSettings": { + "managedCluster_diagnosticSettings": { "copy": { - "name": "registry_diagnosticSettings", + "name": "managedCluster_diagnosticSettings", "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" }, "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('name'))]", "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", "properties": { "copy": [ @@ -30780,592 +32059,269 @@ "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" }, "dependsOn": [ - "registry" + "managedCluster" ] }, - "registry_roleAssignments": { + "managedCluster_roleAssignments": { "copy": { - "name": "registry_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "name": "managedCluster_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" }, "type": "Microsoft.Authorization/roleAssignments", "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerRegistry/registries/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ - "registry" + "managedCluster" ] }, - "registry_replications": { - "copy": { - "name": "registry_replications", - "count": "[length(coalesce(parameters('replications'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Registry-Replication-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": { - "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].name]" - }, - "registryName": { - "value": "[parameters('name')]" - }, - "location": { - "value": "[coalesce(parameters('replications'), createArray())[copyIndex()].location]" - }, - "regionEndpointEnabled": { - "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'regionEndpointEnabled')]" - }, - "zoneRedundancy": { - "value": "[tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'zoneRedundancy')]" - }, - "tags": { - "value": "[coalesce(tryGet(coalesce(parameters('replications'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "10714256463183699741" - }, - "name": "Azure Container Registry (ACR) Replications", - "description": "This module deploys an Azure Container Registry (ACR) Replication.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "registryName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the replication." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "regionEndpointEnabled": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Optional. Specifies whether the replication regional endpoint is enabled. Requests will not be routed to a replication whose regional endpoint is disabled, however its data will continue to be synced with other replications." - } - }, - "zoneRedundancy": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "Optional. Whether or not zone redundancy is enabled for this container registry." - } - } - }, - "resources": { - "registry": { - "existing": true, - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2023-06-01-preview", - "name": "[parameters('registryName')]" - }, - "replication": { - "type": "Microsoft.ContainerRegistry/registries/replications", - "apiVersion": "2023-06-01-preview", - "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "regionEndpointEnabled": "[parameters('regionEndpointEnabled')]", - "zoneRedundancy": "[parameters('zoneRedundancy')]" - }, - "dependsOn": [ - "registry" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The name of the replication." - }, - "value": "[parameters('name')]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the replication." - }, - "value": "[resourceId('Microsoft.ContainerRegistry/registries/replications', parameters('registryName'), parameters('name'))]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the resource group the replication was created in." - }, - "value": "[resourceGroup().name]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('replication', '2023-06-01-preview', 'full').location]" - } - } - } - }, - "dependsOn": [ - "registry" - ] + "dnsZone": { + "condition": "[and(and(equals(parameters('enableDnsZoneContributorRoleAssignment'), true()), not(equals(parameters('dnsZoneResourceId'), null()))), parameters('webApplicationRoutingEnabled'))]", + "existing": true, + "type": "Microsoft.Network/dnsZones", + "apiVersion": "2018-05-01", + "name": "[last(split(if(not(empty(parameters('dnsZoneResourceId'))), parameters('dnsZoneResourceId'), '/dummmyZone'), '/'))]" }, - "registry_cacheRules": { - "copy": { - "name": "registry_cacheRules", - "count": "[length(coalesce(parameters('cacheRules'), createArray()))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-Registry-Cache-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "dnsZone_roleAssignment": { + "condition": "[and(and(equals(parameters('enableDnsZoneContributorRoleAssignment'), true()), not(equals(parameters('dnsZoneResourceId'), null()))), parameters('webApplicationRoutingEnabled'))]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/dnsZones/{0}', last(split(if(not(empty(parameters('dnsZoneResourceId'))), parameters('dnsZoneResourceId'), '/dummmyZone'), '/')))]", + "name": "[guid(resourceId('Microsoft.Network/dnsZones', last(split(if(not(empty(parameters('dnsZoneResourceId'))), parameters('dnsZoneResourceId'), '/dummmyZone'), '/'))), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314'), 'DNS Zone Contributor')]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "registryName": { - "value": "[parameters('name')]" - }, - "sourceRepository": { - "value": "[coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository]" - }, - "name": { - "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'name'), replace(replace(coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository, '/', '-'), '.', '-'))]" - }, - "targetRepository": { - "value": "[coalesce(tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'targetRepository'), coalesce(parameters('cacheRules'), createArray())[copyIndex()].sourceRepository)]" - }, - "credentialSetResourceId": { - "value": "[tryGet(coalesce(parameters('cacheRules'), createArray())[copyIndex()], 'credentialSetResourceId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "6942960102258463312" - }, - "name": "Container Registries Cache", - "description": "Cache for Azure Container Registry (Preview) feature allows users to cache container images in a private container registry. Cache for ACR, is a preview feature available in Basic, Standard, and Premium service tiers ([ref](https://learn.microsoft.com/en-us/azure/container-registry/tutorial-registry-cache)).", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "registryName": { - "type": "string", - "metadata": { - "description": "Required. The name of the parent registry. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "defaultValue": "[replace(replace(parameters('sourceRepository'), '/', '-'), '.', '-')]", - "metadata": { - "description": "Optional. The name of the cache rule. Will be dereived from the source repository name if not defined." - } - }, - "sourceRepository": { - "type": "string", - "metadata": { - "description": "Required. Source repository pulled from upstream." - } - }, - "targetRepository": { - "type": "string", - "defaultValue": "[parameters('sourceRepository')]", - "metadata": { - "description": "Optional. Target repository specified in docker pull command. E.g.: docker pull myregistry.azurecr.io/{targetRepository}:{tag}." - } - }, - "credentialSetResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The resource ID of the credential store which is associated with the cache rule." - } - } - }, - "resources": { - "registry": { - "existing": true, - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2023-06-01-preview", - "name": "[parameters('registryName')]" - }, - "cacheRule": { - "type": "Microsoft.ContainerRegistry/registries/cacheRules", - "apiVersion": "2023-06-01-preview", - "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", - "properties": { - "sourceRepository": "[parameters('sourceRepository')]", - "targetRepository": "[parameters('targetRepository')]", - "credentialSetResourceId": "[parameters('credentialSetResourceId')]" - }, - "dependsOn": [ - "registry" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The Name of the Cache Rule." - }, - "value": "[parameters('name')]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Cache Rule." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Cache Rule." - }, - "value": "[resourceId('Microsoft.ContainerRegistry/registries/cacheRules', parameters('registryName'), parameters('name'))]" - } - } - } + "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "principalId": "[reference('managedCluster').ingressProfile.webAppRouting.identity.objectId]", + "principalType": "ServicePrincipal" }, "dependsOn": [ - "registry" + "dnsZone", + "managedCluster" ] }, - "registry_webhooks": { - "copy": { - "name": "registry_webhooks", - "count": "[length(coalesce(parameters('webhooks'), createArray()))]" - }, + "managedCluster_maintenanceConfigurations": { + "condition": "[not(empty(parameters('maintenanceConfiguration')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Registry-Webhook-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-ManagedCluster-MaintenanceConfigurations', uniqueString(deployment().name, parameters('location')))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "name": { - "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].name]" + "maintenanceWindow": { + "value": "[parameters('maintenanceConfiguration').maintenanceWindow]" }, - "registryName": { + "managedClusterName": { "value": "[parameters('name')]" - }, - "location": { - "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'location'), parameters('location'))]" - }, - "action": { - "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'action'), createArray('chart_delete', 'chart_push', 'delete', 'push', 'quarantine'))]" - }, - "customHeaders": { - "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'customHeaders')]" - }, - "scope": { - "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'scope')]" - }, - "status": { - "value": "[tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'status')]" - }, - "serviceUri": { - "value": "[coalesce(parameters('webhooks'), createArray())[copyIndex()].serviceUri]" - }, - "tags": { - "value": "[coalesce(tryGet(coalesce(parameters('webhooks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" } }, "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "languageVersion": "2.0", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "3986666280667981658" - }, - "name": "Azure Container Registry (ACR) Webhooks", - "description": "This module deploys an Azure Container Registry (ACR) Webhook.", - "owner": "Azure/module-maintainers" - }, - "parameters": { - "registryName": { - "type": "string", - "metadata": { - "description": "Conditional. The name of the parent registry. Required if the template is used in a standalone deployment." - } - }, - "name": { - "type": "string", - "defaultValue": "[format('{0}webhook', parameters('registryName'))]", - "minLength": 5, - "maxLength": 50, - "metadata": { - "description": "Optional. The name of the registry webhook." - } - }, - "serviceUri": { - "type": "string", - "metadata": { - "description": "Required. The service URI for the webhook to post notifications." - } - }, - "status": { - "type": "string", - "defaultValue": "enabled", - "allowedValues": [ - "disabled", - "enabled" - ], - "metadata": { - "description": "Optional. The status of the webhook at the time the operation was called." - } - }, - "action": { - "type": "array", - "defaultValue": [ - "chart_delete", - "chart_push", - "delete", - "push", - "quarantine" - ], - "metadata": { - "description": "Optional. The list of actions that trigger the webhook to post notifications." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Optional. Location for all resources." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags of the resource." - } - }, - "customHeaders": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Custom headers that will be added to the webhook notifications." - } - }, - "scope": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The scope of repositories where the event can be triggered. For example, 'foo:*' means events for all tags under repository 'foo'. 'foo:bar' means events for 'foo:bar' only. 'foo' is equivalent to 'foo:latest'. Empty means all events." - } - } - }, - "resources": { - "registry": { - "existing": true, - "type": "Microsoft.ContainerRegistry/registries", - "apiVersion": "2023-06-01-preview", - "name": "[parameters('registryName')]" - }, - "webhook": { - "type": "Microsoft.ContainerRegistry/registries/webhooks", - "apiVersion": "2023-06-01-preview", - "name": "[format('{0}/{1}', parameters('registryName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "actions": "[parameters('action')]", - "customHeaders": "[parameters('customHeaders')]", - "scope": "[parameters('scope')]", - "serviceUri": "[parameters('serviceUri')]", - "status": "[parameters('status')]" - }, - "dependsOn": [ - "registry" - ] - } + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "2505380725266419010" + }, + "name": "Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations", + "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Maintenance Configurations.", + "owner": "Azure/module-maintainers" }, - "outputs": { - "resourceId": { - "type": "string", + "parameters": { + "maintenanceWindow": { + "type": "object", "metadata": { - "description": "The resource ID of the webhook." - }, - "value": "[resourceId('Microsoft.ContainerRegistry/registries/webhooks', parameters('registryName'), parameters('name'))]" + "description": "Required. Maintenance window for the maintenance configuration." + } }, - "name": { + "managedClusterName": { "type": "string", "metadata": { - "description": "The name of the webhook." - }, - "value": "[parameters('name')]" + "description": "Conditional. The name of the parent managed cluster. Required if the template is used in a standalone deployment." + } }, - "resourceGroupName": { + "name": { "type": "string", + "defaultValue": "aksManagedAutoUpgradeSchedule", "metadata": { - "description": "The name of the Azure container registry." - }, - "value": "[resourceGroup().name]" - }, - "actions": { - "type": "array", - "metadata": { - "description": "The actions of the webhook." - }, - "value": "[reference('webhook').actions]" - }, - "status": { + "description": "Optional. Name of the maintenance configuration." + } + } + }, + "resources": [ + { + "type": "Microsoft.ContainerService/managedClusters/maintenanceConfigurations", + "apiVersion": "2023-10-01", + "name": "[format('{0}/{1}', parameters('managedClusterName'), parameters('name'))]", + "properties": { + "maintenanceWindow": "[parameters('maintenanceWindow')]" + } + } + ], + "outputs": { + "name": { "type": "string", "metadata": { - "description": "The status of the webhook." + "description": "The name of the maintenance configuration." }, - "value": "[reference('webhook').status]" + "value": "[parameters('name')]" }, - "provistioningState": { + "resourceId": { "type": "string", "metadata": { - "description": "The provisioning state of the webhook." + "description": "The resource ID of the maintenance configuration." }, - "value": "[reference('webhook').provisioningState]" + "value": "[resourceId('Microsoft.ContainerService/managedClusters/maintenanceConfigurations', parameters('managedClusterName'), parameters('name'))]" }, - "location": { + "resourceGroupName": { "type": "string", "metadata": { - "description": "The location the resource was deployed into." + "description": "The resource group the agent pool was deployed into." }, - "value": "[reference('webhook', '2023-06-01-preview', 'full').location]" + "value": "[resourceGroup().name]" } } } }, "dependsOn": [ - "registry" + "managedCluster" ] }, - "registry_privateEndpoints": { + "managedCluster_agentPools": { "copy": { - "name": "registry_privateEndpoints", - "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + "name": "managedCluster_agentPools", + "count": "[length(coalesce(parameters('agentPools'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-registry-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-ManagedCluster-AgentPool-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "privateLinkServiceConnections": { - "value": [ - { - "name": "[parameters('name')]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]", - "groupIds": [ - "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry')]" - ] - } - } - ] + "managedClusterName": { + "value": "[parameters('name')]" }, "name": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'registry'), copyIndex()))]" + "value": "[coalesce(parameters('agentPools'), createArray())[copyIndex()].name]" }, - "subnetResourceId": { - "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + "availabilityZones": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'availabilityZones')]" }, - "enableTelemetry": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + "count": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'count')]" }, - "location": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + "sourceResourceId": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'sourceResourceId')]" }, - "lock": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + "enableAutoScaling": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'enableAutoScaling')]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + "enableEncryptionAtHost": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'enableEncryptionAtHost')]" }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "enableFIPS": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'enableFIPS')]" }, - "roleAssignments": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + "enableNodePublicIP": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'enableNodePublicIP')]" + }, + "enableUltraSSD": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'enableUltraSSD')]" + }, + "gpuInstanceProfile": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'gpuInstanceProfile')]" + }, + "kubeletDiskType": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'kubeletDiskType')]" + }, + "maxCount": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'maxCount')]" + }, + "maxPods": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'maxPods')]" + }, + "minCount": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'minCount')]" + }, + "mode": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'mode')]" + }, + "nodeLabels": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'nodeLabels')]" + }, + "nodePublicIpPrefixId": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'nodePublicIpPrefixId')]" + }, + "nodeTaints": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'nodeTaints')]" + }, + "orchestratorVersion": { + "value": "[coalesce(tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'orchestratorVersion'), parameters('kubernetesVersion'))]" + }, + "osDiskSizeGB": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'osDiskSizeGB')]" + }, + "osDiskType": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'osDiskType')]" + }, + "osSku": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'osSku')]" + }, + "osType": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'osType')]" + }, + "podSubnetId": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'podSubnetId')]" + }, + "proximityPlacementGroupResourceId": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'proximityPlacementGroupResourceId')]" + }, + "scaleDownMode": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'scaleDownMode')]" + }, + "scaleSetEvictionPolicy": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'scaleSetEvictionPolicy')]" + }, + "scaleSetPriority": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'scaleSetPriority')]" + }, + "spotMaxPrice": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'spotMaxPrice')]" + }, + "sshAccess": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'sshAccess')]" }, "tags": { - "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + "value": "[coalesce(tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" }, - "manualPrivateLinkServiceConnections": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections')]" + "type": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'type')]" }, - "customDnsConfigs": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + "maxSurge": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'maxSurge')]" }, - "ipConfigurations": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + "vmSize": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'vmSize')]" }, - "applicationSecurityGroupResourceIds": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + "vnetSubnetId": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'vnetSubnetId')]" }, - "customNetworkInterfaceName": { - "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + "workloadRuntime": { + "value": "[tryGet(coalesce(parameters('agentPools'), createArray())[copyIndex()], 'workloadRuntime')]" } }, "template": { @@ -31375,373 +32331,546 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.23.1.45101", - "templateHash": "2821141217598568122" + "version": "0.30.23.60470", + "templateHash": "2322172072513651380" }, - "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", + "name": "Azure Kubernetes Service (AKS) Managed Cluster Agent Pools", + "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster Agent Pool.", "owner": "Azure/module-maintainers" }, - "definitions": { - "roleAssignmentType": { + "parameters": { + "managedClusterName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent managed cluster. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the agent pool." + } + }, + "availabilityZones": { "type": "array", - "items": { - "type": "object", - "properties": { - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } - } - } - }, - "nullable": true + "nullable": true, + "metadata": { + "description": "Optional. The list of Availability zones to use for nodes. This can only be specified if the AgentPoolType property is \"VirtualMachineScaleSets\"." + } }, - "lockType": { + "count": { + "type": "int", + "defaultValue": 1, + "minValue": 0, + "maxValue": 1000, + "metadata": { + "description": "Optional. Desired Number of agents (VMs) specified to host docker containers. Allowed values must be in the range of 0 to 1000 (inclusive) for user pools and in the range of 1 to 1000 (inclusive) for system pools. The default value is 1." + } + }, + "sourceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. This is the ARM ID of the source object to be used to create the target object." + } + }, + "enableAutoScaling": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable auto-scaler." + } + }, + "enableEncryptionAtHost": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. This is only supported on certain VM sizes and in certain Azure regions. For more information, see: /azure/aks/enable-host-encryption. For security reasons, this setting should be enabled." + } + }, + "enableFIPS": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. See Add a FIPS-enabled node pool (https://learn.microsoft.com/en-us/azure/aks/use-multiple-node-pools#add-a-fips-enabled-node-pool-preview) for more details." + } + }, + "enableNodePublicIP": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Some scenarios may require nodes in a node pool to receive their own dedicated public IP addresses. A common scenario is for gaming workloads, where a console needs to make a direct connection to a cloud virtual machine to minimize hops. For more information see assigning a public IP per node (https://learn.microsoft.com/en-us/azure/aks/use-multiple-node-pools#assign-a-public-ip-per-node-for-your-node-pools)." + } + }, + "enableUltraSSD": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable UltraSSD." + } + }, + "gpuInstanceProfile": { + "type": "string", + "nullable": true, + "allowedValues": [ + "MIG1g", + "MIG2g", + "MIG3g", + "MIG4g", + "MIG7g" + ], + "metadata": { + "description": "Optional. GPUInstanceProfile to be used to specify GPU MIG instance profile for supported GPU VM SKU." + } + }, + "kubeletDiskType": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Determines the placement of emptyDir volumes, container runtime data root, and Kubelet ephemeral storage." + } + }, + "maxCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum number of nodes for auto-scaling." + } + }, + "maxPods": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The maximum number of pods that can run on a node." + } + }, + "minCount": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. The minimum number of nodes for auto-scaling." + } + }, + "mode": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A cluster must have at least one \"System\" Agent Pool at all times. For additional information on agent pool restrictions and best practices, see: /azure/aks/use-system-pools." + } + }, + "nodeLabels": { "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. Specify the name of lock." - } - }, - "kind": { - "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, - "metadata": { - "description": "Optional. Specify the type of lock." - } - } - }, - "nullable": true + "nullable": true, + "metadata": { + "description": "Optional. The node labels to be persisted across all nodes in agent pool." + } }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } - } - }, - "nullable": true + "nodePublicIpPrefixId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. ResourceId of the node PublicIPPrefix." + } }, - "manualPrivateLinkServiceConnectionsType": { + "nodeTaints": { "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } - } - } - }, - "nullable": true + "nullable": true, + "metadata": { + "description": "Optional. The taints added to new nodes during node pool create and scale. For example, key=value:NoSchedule." + } }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateLinkServiceId": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } - } - } - }, - "nullable": true + "orchestratorVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. As a best practice, you should upgrade all node pools in an AKS cluster to the same Kubernetes version. The node pool version must have the same major version as the control plane. The node pool minor version must be within two minor versions of the control plane version. The node pool version cannot be greater than the control plane version. For more information see upgrading a node pool (https://learn.microsoft.com/en-us/azure/aks/use-multiple-node-pools#upgrade-a-node-pool)." + } }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } - } - }, - "nullable": true - } - }, - "parameters": { - "name": { + "osDiskSizeGB": { + "type": "int", + "nullable": true, + "metadata": { + "description": "Optional. OS Disk Size in GB to be used to specify the disk size for every machine in the master/agent pool. If you specify 0, it will apply the default osDisk size according to the vmSize specified." + } + }, + "osDiskType": { + "type": "string", + "nullable": true, + "allowedValues": [ + "Ephemeral", + "Managed" + ], + "metadata": { + "description": "Optional. The default is \"Ephemeral\" if the VM supports it and has a cache disk larger than the requested OSDiskSizeGB. Otherwise, defaults to \"Managed\". May not be changed after creation. For more information see Ephemeral OS (https://learn.microsoft.com/en-us/azure/aks/cluster-configuration#ephemeral-os)." + } + }, + "osSku": { + "type": "string", + "nullable": true, + "allowedValues": [ + "AzureLinux", + "CBLMariner", + "Ubuntu", + "Windows2019", + "Windows2022" + ], + "metadata": { + "description": "Optional. Specifies the OS SKU used by the agent pool. The default is Ubuntu if OSType is Linux. The default is Windows2019 when Kubernetes <= 1.24 or Windows2022 when Kubernetes >= 1.25 if OSType is Windows." + } + }, + "osType": { + "type": "string", + "defaultValue": "Linux", + "allowedValues": [ + "Linux", + "Windows" + ], + "metadata": { + "description": "Optional. The operating system type. The default is Linux." + } + }, + "podSubnetId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Subnet ID for the pod IPs. If omitted, pod IPs are statically assigned on the node subnet (see vnetSubnetID for more details). This is of the form: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}." + } + }, + "proximityPlacementGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The ID for the Proximity Placement Group." + } + }, + "scaleDownMode": { + "type": "string", + "defaultValue": "Delete", + "allowedValues": [ + "Deallocate", + "Delete" + ], + "metadata": { + "description": "Optional. Describes how VMs are added to or removed from Agent Pools. See [billing states](https://learn.microsoft.com/en-us/azure/virtual-machines/states-billing)." + } + }, + "scaleSetEvictionPolicy": { + "type": "string", + "defaultValue": "Delete", + "allowedValues": [ + "Deallocate", + "Delete" + ], + "metadata": { + "description": "Optional. The eviction policy specifies what to do with the VM when it is evicted. The default is Delete. For more information about eviction see spot VMs." + } + }, + "scaleSetPriority": { "type": "string", + "nullable": true, + "allowedValues": [ + "Regular", + "Spot" + ], + "metadata": { + "description": "Optional. The Virtual Machine Scale Set priority." + } + }, + "spotMaxPrice": { + "type": "int", + "nullable": true, "metadata": { - "description": "Required. Name of the private endpoint resource to create." + "description": "Optional. Possible values are any decimal value greater than zero or -1 which indicates the willingness to pay any on-demand price. For more details on spot pricing, see spot VMs pricing (https://learn.microsoft.com/en-us/azure/virtual-machines/spot-vms#pricing)." } }, - "subnetResourceId": { - "type": "string", + "tags": { + "type": "object", + "nullable": true, "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + "description": "Optional. Tags of the resource." } }, - "applicationSecurityGroupResourceIds": { - "type": "array", + "type": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + "description": "Optional. The type of Agent Pool." } }, - "customNetworkInterfaceName": { + "maxSurge": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." + "description": "Optional. This can either be set to an integer (e.g. \"5\") or a percentage (e.g. \"50%\"). If a percentage is specified, it is the percentage of the total agent pool size at the time of the upgrade. For percentages, fractional nodes are rounded up. If not specified, the default is 1. For more information, including best practices, see: /azure/aks/upgrade-cluster#customize-node-surge-upgrade." } }, - "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", + "vmSize": { + "type": "string", + "defaultValue": "Standard_D2s_v3", "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + "description": "Optional. VM size. VM size availability varies by region. If a node contains insufficient compute resources (memory, cpu, etc) pods might fail to run correctly. For more details on restricted VM sizes, see: /azure/aks/quotas-skus-regions." } }, - "privateDnsZoneGroupName": { + "vnetSubnetId": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + "description": "Optional. Node Subnet ID. If this is not specified, a VNET and subnet will be generated and used. If no podSubnetID is specified, this applies to nodes and pods, otherwise it applies to just nodes. This is of the form: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{virtualNetworkName}/subnets/{subnetName}." } }, - "privateDnsZoneResourceIds": { - "type": "array", + "workloadRuntime": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. Determines the type of workload a node can run." + } + }, + "sshAccess": { + "type": "string", + "defaultValue": "Disabled", + "allowedValues": [ + "LocalUser", + "Disabled" + ], + "metadata": { + "description": "Optional. Whether to enable SSH access to the nodes." + } + } + }, + "resources": { + "managedCluster": { + "existing": true, + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2024-03-02-preview", + "name": "[parameters('managedClusterName')]" + }, + "agentPool": { + "type": "Microsoft.ContainerService/managedClusters/agentPools", + "apiVersion": "2024-04-02-preview", + "name": "[format('{0}/{1}', parameters('managedClusterName'), parameters('name'))]", + "properties": { + "availabilityZones": "[parameters('availabilityZones')]", + "count": "[parameters('count')]", + "creationData": "[if(not(empty(parameters('sourceResourceId'))), createObject('sourceResourceId', parameters('sourceResourceId')), null())]", + "enableAutoScaling": "[parameters('enableAutoScaling')]", + "enableEncryptionAtHost": "[parameters('enableEncryptionAtHost')]", + "enableFIPS": "[parameters('enableFIPS')]", + "enableNodePublicIP": "[parameters('enableNodePublicIP')]", + "enableUltraSSD": "[parameters('enableUltraSSD')]", + "gpuInstanceProfile": "[parameters('gpuInstanceProfile')]", + "kubeletDiskType": "[parameters('kubeletDiskType')]", + "maxCount": "[parameters('maxCount')]", + "maxPods": "[parameters('maxPods')]", + "minCount": "[parameters('minCount')]", + "mode": "[parameters('mode')]", + "nodeLabels": "[parameters('nodeLabels')]", + "nodePublicIPPrefixID": "[parameters('nodePublicIpPrefixId')]", + "nodeTaints": "[parameters('nodeTaints')]", + "orchestratorVersion": "[parameters('orchestratorVersion')]", + "osDiskSizeGB": "[parameters('osDiskSizeGB')]", + "osDiskType": "[parameters('osDiskType')]", + "osSKU": "[parameters('osSku')]", + "osType": "[parameters('osType')]", + "podSubnetID": "[parameters('podSubnetId')]", + "proximityPlacementGroupID": "[parameters('proximityPlacementGroupResourceId')]", + "scaleDownMode": "[parameters('scaleDownMode')]", + "scaleSetEvictionPolicy": "[parameters('scaleSetEvictionPolicy')]", + "scaleSetPriority": "[parameters('scaleSetPriority')]", + "securityProfile": { + "sshAccess": "[parameters('sshAccess')]" + }, + "spotMaxPrice": "[parameters('spotMaxPrice')]", + "tags": "[parameters('tags')]", + "type": "[parameters('type')]", + "upgradeSettings": { + "maxSurge": "[parameters('maxSurge')]" + }, + "vmSize": "[parameters('vmSize')]", + "vnetSubnetID": "[parameters('vnetSubnetId')]", + "workloadRuntime": "[parameters('workloadRuntime')]" + }, + "dependsOn": [ + "managedCluster" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the agent pool." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the agent pool." + }, + "value": "[resourceId('Microsoft.ContainerService/managedClusters/agentPools', parameters('managedClusterName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the agent pool was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "managedCluster" + ] + }, + "managedCluster_extension": { + "condition": "[not(empty(parameters('fluxExtension')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ManagedCluster-FluxExtension', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "clusterName": { + "value": "[parameters('name')]" + }, + "configurationProtectedSettings": { + "value": "[tryGet(parameters('fluxExtension'), 'configurationProtectedSettings')]" + }, + "configurationSettings": { + "value": "[tryGet(parameters('fluxExtension'), 'configurationSettings')]" + }, + "enableTelemetry": { + "value": "[parameters('enableTelemetry')]" + }, + "extensionType": { + "value": "microsoft.flux" + }, + "fluxConfigurations": { + "value": "[tryGet(parameters('fluxExtension'), 'configurations')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "name": { + "value": "flux" + }, + "releaseNamespace": { + "value": "[coalesce(tryGet(parameters('fluxExtension'), 'releaseNamespace'), 'flux-system')]" + }, + "releaseTrain": { + "value": "[coalesce(tryGet(parameters('fluxExtension'), 'releaseTrain'), 'Stable')]" + }, + "version": { + "value": "[tryGet(parameters('fluxExtension'), 'version')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "12293754418506359991" + }, + "name": "Kubernetes Configuration Extensions", + "description": "This module deploys a Kubernetes Configuration Extension.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Flux Configuration." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "clusterName": { + "type": "string", + "metadata": { + "description": "Required. The name of the AKS cluster that should be configured." } }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Optional. Location for all Resources." + "description": "Optional. Location for all resources." } }, - "lock": { - "$ref": "#/definitions/lockType", + "configurationProtectedSettings": { + "type": "secureObject", + "nullable": true, "metadata": { - "description": "Optional. The lock settings of the service." + "description": "Optional. Configuration settings that are sensitive, as name-value pairs for configuring this extension." } }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "configurationSettings": { + "type": "object", + "nullable": true, "metadata": { - "description": "Optional. Array of role assignments to create." + "description": "Optional. Configuration settings, as name-value pairs for configuring this extension." } }, - "tags": { - "type": "object", + "extensionType": { + "type": "string", + "metadata": { + "description": "Required. Type of the extension, of which this resource is an instance of. It must be one of the Extension Types registered with Microsoft.KubernetesConfiguration by the extension publisher." + } + }, + "releaseTrain": { + "type": "string", "nullable": true, "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + "description": "Optional. ReleaseTrain this extension participates in for auto-upgrade (e.g. Stable, Preview, etc.) - only if autoUpgradeMinorVersion is \"true\"." } }, - "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "releaseNamespace": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. Custom DNS configurations." + "description": "Optional. Namespace where the extension Release must be placed, for a Cluster scoped extension. If this namespace does not exist, it will be created." } }, - "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "targetNamespace": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Optional. Namespace where the extension will be created for an Namespace scoped extension. If this namespace does not exist, it will be created." } }, - "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "version": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Optional. Version of the extension for this extension, if it is \"pinned\" to a specific version." } }, - "enableTelemetry": { - "type": "bool", - "defaultValue": true, + "fluxConfigurations": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." + "description": "Optional. A list of flux configuraitons." } } }, - "variables": { - "builtInRoleNames": { - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" - } - }, "resources": { "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.3.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.kubernetesconfiguration-fluxconfig.{0}.{1}', replace('0.2.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -31757,1768 +32886,1553 @@ } } }, - "privateEndpoint": { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "copy": [ - { - "name": "applicationSecurityGroups", - "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", - "input": { - "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" - } - } - ], - "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", - "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", - "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", - "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", - "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - } + "managedCluster": { + "existing": true, + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2022-07-01", + "name": "[parameters('clusterName')]" }, - "privateEndpoint_lock": { - "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", - "type": "Microsoft.Authorization/locks", - "apiVersion": "2020-05-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "extension": { + "type": "Microsoft.KubernetesConfiguration/extensions", + "apiVersion": "2022-03-01", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "[parameters('name')]", "properties": { - "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", - "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + "autoUpgradeMinorVersion": "[if(not(empty(parameters('version'))), false(), true())]", + "configurationProtectedSettings": "[parameters('configurationProtectedSettings')]", + "configurationSettings": "[parameters('configurationSettings')]", + "extensionType": "[parameters('extensionType')]", + "releaseTrain": "[parameters('releaseTrain')]", + "scope": { + "cluster": "[if(not(empty(coalesce(parameters('releaseNamespace'), ''))), createObject('releaseNamespace', parameters('releaseNamespace')), null())]", + "namespace": "[if(not(empty(coalesce(parameters('targetNamespace'), ''))), createObject('targetNamespace', parameters('targetNamespace')), null())]" + }, + "version": "[parameters('version')]" }, "dependsOn": [ - "privateEndpoint" + "managedCluster" ] }, - "privateEndpoint_roleAssignments": { + "fluxConfiguration": { "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", - "properties": { - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", - "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", - "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", - "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", - "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", - "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", - "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + "name": "fluxConfiguration", + "count": "[length(coalesce(parameters('fluxConfigurations'), createArray()))]" }, - "dependsOn": [ - "privateEndpoint" - ] - }, - "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-ManagedCluster-FluxConfiguration{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "enableTelemetry": { + "value": "[parameters('enableTelemetry')]" + }, + "clusterName": { + "value": "[parameters('clusterName')]" + }, + "scope": { + "value": "[coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()].scope]" + }, + "namespace": { + "value": "[coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()].namespace]" + }, + "sourceKind": "[if(contains(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'gitRepository'), createObject('value', 'GitRepository'), createObject('value', 'Bucket'))]", "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + "value": "[coalesce(tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'name'), toLower(format('{0}-fluxconfiguration{1}', parameters('clusterName'), copyIndex())))]" }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "bucket": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'bucket')]" }, - "privateEndpointName": { - "value": "[parameters('name')]" + "configurationProtectedSettings": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'configurationProtectedSettings')]" + }, + "gitRepository": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'gitRepository')]" + }, + "kustomizations": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'kustomizations')]" + }, + "suspend": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'suspend')]" } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "18168683629401652671" + "templateHash": "13420454476526931427" }, - "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "name": "Kubernetes Configuration Flux Configurations", + "description": "This module deploys a Kubernetes Configuration Flux Configuration.", "owner": "Azure/module-maintainers" }, "parameters": { - "privateEndpointName": { + "name": { "type": "string", "metadata": { - "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + "description": "Required. The name of the Flux Configuration." } }, - "privateDNSResourceIds": { - "type": "array", - "minLength": 1, - "maxLength": 5, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. Enable/Disable usage telemetry for module." } }, - "name": { + "clusterName": { "type": "string", - "defaultValue": "default", "metadata": { - "description": "Optional. The name of the private DNS zone group." + "description": "Required. The name of the AKS cluster that should be configured." } - } - }, - "variables": { - "copy": [ - { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", - "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", - "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" - } - } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." } - ] - }, - "resources": [ - { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", - "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", - "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + }, + "bucket": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Conditional. Parameters to reconcile to the GitRepository source kind type. Required if `sourceKind` is `Bucket`." } - } - ], - "outputs": { - "name": { + }, + "configurationProtectedSettings": { + "type": "secureObject", + "nullable": true, + "metadata": { + "description": "Optional. Key-value pairs of protected configuration settings for the configuration." + } + }, + "gitRepository": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Conditional. Parameters to reconcile to the GitRepository source kind type. Required if `sourceKind` is `GitRepository`." + } + }, + "kustomizations": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Array of kustomizations used to reconcile the artifact pulled by the source type on the cluster." + } + }, + "namespace": { "type": "string", "metadata": { - "description": "The name of the private endpoint DNS zone group." - }, - "value": "[parameters('name')]" + "description": "Required. The namespace to which this configuration is installed to. Maximum of 253 lower case alphanumeric characters, hyphen and period only." + } }, - "resourceId": { + "scope": { "type": "string", + "allowedValues": [ + "cluster", + "namespace" + ], "metadata": { - "description": "The resource ID of the private endpoint DNS zone group." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + "description": "Required. Scope at which the configuration will be installed." + } }, - "resourceGroupName": { + "sourceKind": { "type": "string", + "allowedValues": [ + "Bucket", + "GitRepository" + ], "metadata": { - "description": "The resource group the private endpoint DNS zone group was deployed into." + "description": "Required. Source Kind to pull the configuration data from." + } + }, + "suspend": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether this configuration should suspend its reconciliation of its kustomizations and sources." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.kubernetesconfiguration-extension.{0}.{1}', replace('0.2.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "managedCluster": { + "existing": true, + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2022-07-01", + "name": "[parameters('clusterName')]" + }, + "fluxConfiguration": { + "type": "Microsoft.KubernetesConfiguration/fluxConfigurations", + "apiVersion": "2022-03-01", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "[parameters('name')]", + "properties": { + "bucket": "[parameters('bucket')]", + "configurationProtectedSettings": "[parameters('configurationProtectedSettings')]", + "gitRepository": "[parameters('gitRepository')]", + "kustomizations": "[parameters('kustomizations')]", + "namespace": "[parameters('namespace')]", + "scope": "[parameters('scope')]", + "sourceKind": "[parameters('sourceKind')]", + "suspend": "[parameters('suspend')]" }, - "value": "[resourceGroup().name]" + "dependsOn": [ + "managedCluster" + ] } - } - } - }, - "dependsOn": [ - "privateEndpoint" - ] - } - }, - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint." - }, - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - }, - "name": { - "type": "string", - "metadata": { - "description": "The name of the private endpoint." - }, - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" - } - } - } - }, - "dependsOn": [ - "registry" - ] - } - }, - "outputs": { - "name": { - "type": "string", - "metadata": { - "description": "The Name of the Azure container registry." - }, - "value": "[parameters('name')]" - }, - "loginServer": { - "type": "string", - "metadata": { - "description": "The reference to the Azure container registry." - }, - "value": "[reference(resourceId('Microsoft.ContainerRegistry/registries', parameters('name')), '2019-05-01').loginServer]" - }, - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The name of the Azure container registry." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Azure container registry." - }, - "value": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('name'))]" - }, - "systemAssignedMIPrincipalId": { - "type": "string", - "metadata": { - "description": "The principal ID of the system assigned identity." - }, - "value": "[coalesce(tryGet(tryGet(reference('registry', '2023-06-01-preview', 'full'), 'identity'), 'principalId'), '')]" - }, - "location": { - "type": "string", - "metadata": { - "description": "The location the resource was deployed into." - }, - "value": "[reference('registry', '2023-06-01-preview', 'full').location]" - } - } - } - }, - "dependsOn": [ - "appIdentity" - ] - }, - "cluster": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-aks-cluster', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "resourceName": { - "value": "[parameters('bladeConfig').sectionName]" - }, - "location": { - "value": "[parameters('location')]" - }, - "aksVersion": { - "value": "[variables('serviceLayerConfig').cluster.aksVersion]" - }, - "aad_tenant_id": { - "value": "[subscription().tenantId]" - }, - "clusterSize": { - "value": "[parameters('clusterSize')]" - }, - "networkPlugin": { - "value": "[variables('serviceLayerConfig').cluster.networkPlugin]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" - }, - "aksSubnetId": { - "value": "[parameters('aksSubnetId')]" - }, - "aksPodSubnetId": "[if(equals(parameters('podSubnetId'), ''), createObject('value', null()), createObject('value', parameters('podSubnetId')))]", - "identityId": { - "value": "[parameters('identityId')]" - }, - "workspaceId": { - "value": "[parameters('workspaceResourceId')]" - }, - "serviceCidr": { - "value": "[parameters('serviceCidr')]" - }, - "dnsServiceIP": { - "value": "[parameters('dnsServiceIP')]" - }, - "serviceMeshProfile": "[if(parameters('enableMonitoring'), createObject('value', 'Istio'), createObject('value', null()))]", - "istioRevision": "[if(parameters('enableMonitoring'), createObject('value', variables('serviceLayerConfig').cluster.meshVersion), createObject('value', null()))]", - "istioIngressGatewayMode": "[if(parameters('enableMonitoring'), createObject('value', parameters('clusterIngress')), createObject('value', null()))]", - "enable_aad": "[if(equals(empty(parameters('clusterAdminIds')), true()), createObject('value', false()), createObject('value', true()))]", - "admin_ids": { - "value": "[parameters('clusterAdminIds')]" - }, - "workloadIdentityEnabled": { - "value": true - }, - "oidcIssuer": { - "value": true - }, - "keyvaultEnabled": { - "value": true - }, - "fluxGitOpsAddon": { - "value": true - }, - "enableImageCleaner": { - "value": true - }, - "fileCSIDriver": { - "value": true - }, - "blobCSIDriver": { - "value": true - }, - "azurepolicy": { - "value": "audit" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "547945363481985280" + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the flux configuration." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the flux configuration." + }, + "value": "[extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/fluxConfigurations', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the flux configuration was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "extension", + "managedCluster" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/extensions', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the extension was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "managedCluster" + ] } }, - "parameters": { - "resourceName": { - "type": "string", - "minLength": 1, - "maxLength": 63, - "metadata": { - "description": "Used to name all resources" - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Specify the location of the AKS cluster." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "Tags." - } - }, - "aad_tenant_id": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The ID of the Azure AD tenant" - } - }, - "admin_ids": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The ID of the Azure AD tenant" - } - }, - "skuTierPaid": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Use the paid sku for SLA rather than SLO" - } - }, - "aksVersion": { - "type": "string", - "defaultValue": "1.28", - "metadata": { - "description": "Kubernetes Version" - } - }, - "upgradeChannel": { - "type": "string", - "defaultValue": "stable", - "allowedValues": [ - "none", - "patch", - "stable", - "rapid", - "node-image" - ], - "metadata": { - "description": "AKS upgrade channel" - } - }, - "managedNodeResourceGroup": { - "type": "string", - "defaultValue": "", - "maxLength": 80, - "metadata": { - "description": "The name of the NEW resource group to create the AKS cluster managed resources in" - } - }, - "clusterSize": { - "type": "string", - "defaultValue": "Burstable", - "allowedValues": [ - "Burstable", - "Standard" - ], - "metadata": { - "description": "The System Pool Preset sizing" - } - }, - "customVMSize": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Override the default server type." - } - }, - "AutoscaleProfile": { - "type": "object", - "defaultValue": { - "balance-similar-node-groups": "true", - "expander": "random", - "max-empty-bulk-delete": "10", - "max-graceful-termination-sec": "600", - "max-node-provision-time": "15m", - "max-total-unready-percentage": "45", - "new-pod-scale-up-delay": "0s", - "ok-total-unready-count": "3", - "scale-down-delay-after-add": "10m", - "scale-down-delay-after-delete": "20s", - "scale-down-delay-after-failure": "3m", - "scale-down-unneeded-time": "10m", - "scale-down-unready-time": "20m", - "scale-down-utilization-threshold": "0.5", - "scan-interval": "10s", - "skip-nodes-with-local-storage": "true", - "skip-nodes-with-system-pods": "true" - }, - "metadata": { - "description": "The System Pool Preset sizing" - } - }, - "agentCount": { - "type": "int", - "defaultValue": 3, - "metadata": { - "description": "The number of agents for the user node pool" - } - }, - "agentCountMax": { - "type": "int", - "defaultValue": 0, - "metadata": { - "description": "The maximum number of nodes for the user node pool" - } - }, - "nodePoolName": { - "type": "string", - "defaultValue": "internal", - "minLength": 3, - "maxLength": 12, - "metadata": { - "description": "Name for user node pool" - } - }, - "JustUseSystemPool": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Only use the system node pool" - } - }, - "workspaceId": { - "type": "string", - "metadata": { - "description": "Specify the Log Analytics Workspace Id to use for monitoring." - } - }, - "identityId": { - "type": "string", - "metadata": { - "description": "Specify the User Managed Identity Resource Id." - } - }, - "networkPlugin": { - "type": "string", - "defaultValue": "azure", - "allowedValues": [ - "azure", - "kubenet" - ], - "metadata": { - "description": "The network plugin type" - } - }, - "networkPluginMode": { - "type": "string", - "defaultValue": "Overlay", - "allowedValues": [ - "", - "Overlay" - ], - "metadata": { - "description": "The network plugin type" - } - }, - "networkPolicy": { + "outputs": { + "resourceId": { "type": "string", - "defaultValue": "cilium", - "allowedValues": [ - "", - "azure", - "calico", - "cilium" - ], "metadata": { - "description": "The network policy to use." - } + "description": "The resource ID of the managed cluster." + }, + "value": "[resourceId('Microsoft.ContainerService/managedClusters', parameters('name'))]" }, - "podCidr": { + "resourceGroupName": { "type": "string", - "defaultValue": "192.168.0.0/16", - "minLength": 9, - "maxLength": 18, "metadata": { - "description": "The address range to use for pods" - } + "description": "The resource group the managed cluster was deployed into." + }, + "value": "[resourceGroup().name]" }, - "serviceCidr": { + "name": { "type": "string", - "defaultValue": "172.16.0.0/16", - "minLength": 9, - "maxLength": 18, "metadata": { - "description": "The address range to use for services" - } + "description": "The name of the managed cluster." + }, + "value": "[parameters('name')]" }, - "dnsServiceIP": { + "controlPlaneFQDN": { "type": "string", - "defaultValue": "172.16.0.10", - "minLength": 7, - "maxLength": 15, "metadata": { - "description": "The IP address to reserve for DNS" - } + "description": "The control plane FQDN of the managed cluster." + }, + "value": "[if(parameters('enablePrivateCluster'), reference('managedCluster').privateFQDN, reference('managedCluster').fqdn)]" }, - "aksOutboundTrafficType": { + "systemAssignedMIPrincipalId": { "type": "string", - "defaultValue": "loadBalancer", - "allowedValues": [ - "loadBalancer", - "natGateway", - "userDefinedRouting" - ], "metadata": { - "description": "Outbound traffic type for the egress traffic of your cluster" - } + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('managedCluster', '2024-04-02-preview', 'full'), 'identity'), 'principalId'), '')]" }, - "dnsPrefix": { + "kubeletIdentityClientId": { "type": "string", - "defaultValue": "[format('aks-{0}', resourceGroup().name)]", - "metadata": { - "description": "DNS prefix. Defaults to {resourceName}-dns" - } - }, - "natGwIpCount": { - "type": "int", - "defaultValue": 2, - "minValue": 1, - "maxValue": 16, - "metadata": { - "description": "The effective outbound IP resources of the cluster NAT gateway" - } - }, - "natGwIdleTimeout": { - "type": "int", - "defaultValue": 30, - "minValue": 4, - "maxValue": 120, - "metadata": { - "description": "Outbound flow idle timeout in minutes for NatGw" - } - }, - "cniDynamicIpAllocation": { - "type": "bool", - "defaultValue": false, "metadata": { - "description": "Allocate pod ips dynamically" - } - }, - "custom_vnet": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Are you providing a custom VNET" - } + "description": "The Client ID of the AKS identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(reference('managedCluster'), 'identityProfile'), 'kubeletidentity'), 'clientId'), '')]" }, - "aksSubnetId": { + "kubeletIdentityObjectId": { "type": "string", - "defaultValue": "", "metadata": { - "description": "Full resource id path of an existing subnet to use for AKS" - } + "description": "The Object ID of the AKS identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(reference('managedCluster'), 'identityProfile'), 'kubeletidentity'), 'objectId'), '')]" }, - "aksPodSubnetId": { + "kubeletIdentityResourceId": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "Full resource id path of an existing pod subnet to use for AKS" - } - }, - "enablePrivateCluster": { - "type": "bool", - "defaultValue": false, "metadata": { - "description": "Enable private cluster" - } + "description": "The Resource ID of the AKS identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(reference('managedCluster'), 'identityProfile'), 'kubeletidentity'), 'resourceId'), '')]" }, - "privateClusterDnsMethod": { + "omsagentIdentityObjectId": { "type": "string", - "defaultValue": "system", - "allowedValues": [ - "system", - "none", - "privateDnsZone" - ], "metadata": { - "description": "Private cluster dns advertisment method, leverages the dnsApiPrivateZoneId parameter" - } + "description": "The Object ID of the OMS agent identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('managedCluster'), 'addonProfiles'), 'omsagent'), 'identity'), 'objectId'), '')]" }, - "dnsApiPrivateZoneId": { + "keyvaultIdentityObjectId": { "type": "string", - "defaultValue": "", - "metadata": { - "description": "The full Azure resource ID of the privatelink DNS zone to use for the AKS cluster API Server" - } - }, - "authorizedIPRanges": { - "type": "array", - "defaultValue": [], "metadata": { - "description": "The IP addresses that are allowed to access the API server" - } + "description": "The Object ID of the Key Vault Secrets Provider identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('managedCluster'), 'addonProfiles'), 'azureKeyvaultSecretsProvider'), 'identity'), 'objectId'), '')]" }, - "azurepolicy": { + "keyvaultIdentityClientId": { "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "audit", - "deny" - ], "metadata": { - "description": "Enable the Azure Policy addon" - } + "description": "The Client ID of the Key Vault Secrets Provider identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('managedCluster'), 'addonProfiles'), 'azureKeyvaultSecretsProvider'), 'identity'), 'clientId'), '')]" }, - "azurePolicyInitiative": { + "ingressApplicationGatewayIdentityObjectId": { "type": "string", - "defaultValue": "Baseline", - "allowedValues": [ - "Baseline", - "Restricted" - ] - }, - "kedaEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enables Kubernetes Event-driven Autoscaling (KEDA)" - } - }, - "openServiceMeshEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enables Open Service Mesh" - } - }, - "workloadIdentityEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Installs Azure Workload Identity into the cluster" - } - }, - "defenderEnabled": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable Microsoft Defender for Containers (preview)" - } - }, - "keyvaultEnabled": { - "type": "bool", - "defaultValue": false, "metadata": { - "description": "Installs the AKS KV CSI provider" - } + "description": "The Object ID of Application Gateway Ingress Controller (AGIC) identity." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('managedCluster'), 'addonProfiles'), 'ingressApplicationGateway'), 'identity'), 'objectId'), '')]" }, - "keyVaultAksCSIPollInterval": { + "location": { "type": "string", - "defaultValue": "2m", - "metadata": { - "description": "Rotation poll interval for the AKS KV CSI provider" - } - }, - "enable_aad": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable Azure AD integration on AKS" - } - }, - "enableAzureRBAC": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable RBAC using AAD" - } - }, - "sgxPlugin": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enables SGX Confidential Compute plugin" - } - }, - "blobCSIDriver": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enables the Blob CSI driver" - } - }, - "fileCSIDriver": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Enables the File CSI driver" - } - }, - "diskCSIDriver": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Enables the Disk CSI driver" - } - }, - "AksDisableLocalAccounts": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Disable local K8S accounts for AAD enabled clusters" - } - }, - "oidcIssuer": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Configures the cluster as an OIDC issuer for use with Workload Identity" - } - }, - "warIngressNginx": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable Web App Routing" - } - }, - "enableImageCleaner": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Specifies whether to enable ImageCleaner on AKS cluster. The default value is false." - } - }, - "imageCleanerIntervalHours": { - "type": "int", - "defaultValue": 24, "metadata": { - "description": "Specifies whether ImageCleaner scanning interval in hours." - } + "description": "The location the resource was deployed into." + }, + "value": "[reference('managedCluster', '2024-04-02-preview', 'full').location]" }, - "serviceMeshProfile": { + "oidcIssuerUrl": { "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "Istio" - ], "metadata": { - "description": "The service mesh profile to use" - } + "description": "The OIDC token issuer URL." + }, + "value": "[coalesce(tryGet(tryGet(reference('managedCluster'), 'oidcIssuerProfile'), 'issuerURL'), '')]" }, - "istioIngressGatewayMode": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "External", - "Internal", - "Both" - ], + "addonProfiles": { + "type": "object", "metadata": { - "description": "The ingress gateway to use for the Istio service mesh" - } + "description": "The addonProfiles of the Kubernetes cluster." + }, + "value": "[coalesce(tryGet(reference('managedCluster'), 'addonProfiles'), createObject())]" }, - "istioRevision": { + "webAppRoutingIdentityObjectId": { "type": "string", - "defaultValue": "asm-1-18" - }, - "automatedDeployment": { - "type": "bool", - "defaultValue": false, "metadata": { - "description": "If automated deployment, for the 3 automated user assignments, set Principal Type on each to \"ServicePrincipal\" rarter than \"User\"" - } - }, - "adminPrincipalId": { + "description": "The Object ID of Web Application Routing." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('managedCluster'), 'ingressProfile'), 'webAppRouting'), 'identity'), 'objectId'), '')]" + } + } + } + }, + "dependsOn": [ + "appIdentity" + ] + }, + "policy": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-aks-policy', parameters('bladeConfig').sectionName)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "clusterName": { + "value": "[reference('cluster').outputs.name.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "11565150036561320039" + } + }, + "parameters": { + "clusterName": { "type": "string", "defaultValue": "", "metadata": { - "description": "The principal ID to assign the AKS admin role." - } - }, - "fluxGitOpsAddon": { - "type": "bool", - "defaultValue": false - }, - "daprAddon": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Add the Dapr extension" - } - }, - "daprAddonHA": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Enable high availability (HA) mode for the Dapr control plane" + "description": "The name of the Azure Kubernetes Service Cluster" } } }, "variables": { - "autoScale": "[greater(parameters('agentCountMax'), parameters('agentCount'))]", - "name": "[format('{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]", - "serviceMeshProfileObj": { - "istio": { - "components": { - "ingressGateways": "[if(empty(parameters('istioIngressGatewayMode')), null(), union(if(equals(parameters('istioIngressGatewayMode'), 'Internal'), array(variables('ingressModes').internal), createArray()), if(equals(parameters('istioIngressGatewayMode'), 'External'), array(variables('ingressModes').external), createArray()), if(equals(parameters('istioIngressGatewayMode'), 'Both'), array(variables('ingressModes').internal), createArray()), if(equals(parameters('istioIngressGatewayMode'), 'Both'), array(variables('ingressModes').external), createArray())))]" - }, - "revisions": [ - "[parameters('istioRevision')]" - ] - }, - "mode": "Istio" - }, - "outboundTrafficType": "[if(equals(parameters('aksOutboundTrafficType'), 'natGateway'), if(parameters('custom_vnet'), 'userAssignedNATGateway', 'managedNATGateway'), parameters('aksOutboundTrafficType'))]", - "systemPoolPresets": { - "Burstable": { - "vmSize": "Standard_B2ms", - "minCount": 1, - "maxCount": 3, - "availabilityZones": [ - "1", - "2", - "3" - ], - "osDiskType": "Managed", - "osDiskSize": 128, - "maxPods": 30 - }, - "Standard": { - "vmSize": "Standard_D2s_v5", - "minCount": 1, - "maxCount": 3, - "availabilityZones": [ - "1", - "2", - "3" - ], - "osDiskType": "Managed", - "osDiskSize": 128, - "maxPods": 30 - } - }, - "systemPoolProfile": { - "name": "default", - "mode": "System", - "osType": "Linux", - "osSKU": "AzureLinux", - "type": "VirtualMachineScaleSets", - "osDiskType": "[variables('systemPoolPresets')[parameters('clusterSize')].osDiskType]", - "osDiskSizeGB": "[variables('systemPoolPresets')[parameters('clusterSize')].osDiskSize]", - "vmSize": "[if(empty(parameters('customVMSize')), variables('systemPoolPresets')[parameters('clusterSize')].vmSize, parameters('customVMSize'))]", - "count": "[variables('systemPoolPresets')[parameters('clusterSize')].minCount]", - "minCount": "[variables('systemPoolPresets')[parameters('clusterSize')].minCount]", - "maxCount": "[variables('systemPoolPresets')[parameters('clusterSize')].maxCount]", - "availabilityZones": "[variables('systemPoolPresets')[parameters('clusterSize')].availabilityZones]", - "enableAutoScaling": true, - "maxPods": "[variables('systemPoolPresets')[parameters('clusterSize')].maxPods]", - "vnetSubnetID": "[if(not(empty(parameters('aksSubnetId'))), parameters('aksSubnetId'), null())]", - "podSubnetID": "[if(not(empty(parameters('aksPodSubnetId'))), parameters('aksPodSubnetId'), null())]", - "upgradeSettings": { - "maxSurge": "33%" - }, - "nodeTaints": [ - "[if(parameters('JustUseSystemPool'), '', 'CriticalAddonsOnly=true:NoSchedule')]" - ] - }, - "userPoolPresets": { - "Burstable": { - "vmSize": "Standard_B4ms", - "minCount": 5, - "maxCount": 20, - "availabilityZones": [ - "1", - "2", - "3" - ], - "osDiskType": "Managed", - "osDiskSize": 128, - "maxPods": 60 - }, - "Standard": { - "vmSize": "Standard_D4s_v5", - "minCount": 5, - "maxCount": 20, - "availabilityZones": [ - "1", - "2", - "3" - ], - "osDiskType": "Managed", - "osDiskSize": 128, - "maxPods": 60 - } - }, - "userPoolProfile": { - "name": "[parameters('nodePoolName')]", - "mode": "User", - "osType": "Linux", - "osSKU": "AzureLinux", - "type": "VirtualMachineScaleSets", - "osDiskType": "[variables('userPoolPresets')[parameters('clusterSize')].osDiskType]", - "osDiskSizeGB": "[variables('userPoolPresets')[parameters('clusterSize')].osDiskSize]", - "vmSize": "[if(empty(parameters('customVMSize')), variables('userPoolPresets')[parameters('clusterSize')].vmSize, parameters('customVMSize'))]", - "count": "[variables('userPoolPresets')[parameters('clusterSize')].minCount]", - "minCount": "[variables('userPoolPresets')[parameters('clusterSize')].minCount]", - "maxCount": "[variables('userPoolPresets')[parameters('clusterSize')].maxCount]", - "availabilityZones": "[variables('userPoolPresets')[parameters('clusterSize')].availabilityZones]", - "enableAutoScaling": true, - "maxPods": "[variables('userPoolPresets')[parameters('clusterSize')].maxPods]", - "vnetSubnetID": "[if(not(empty(parameters('aksSubnetId'))), parameters('aksSubnetId'), null())]", - "podSubnetID": "[if(not(empty(parameters('aksPodSubnetId'))), parameters('aksPodSubnetId'), null())]", - "upgradeSettings": { - "maxSurge": "33%" - } - }, - "agentPoolProfiles": "[if(parameters('JustUseSystemPool'), array(variables('systemPoolProfile')), concat(array(variables('systemPoolProfile')), array(variables('userPoolProfile'))))]", - "akssku": "[if(parameters('skuTierPaid'), 'Standard', 'Free')]", - "aks_addons": "[union(createObject('azurepolicy', createObject('config', createObject('version', if(not(empty(parameters('azurepolicy'))), 'v2', null())), 'enabled', not(empty(parameters('azurepolicy')))), 'azureKeyvaultSecretsProvider', createObject('config', createObject('enableSecretRotation', 'true', 'rotationPollInterval', parameters('keyVaultAksCSIPollInterval')), 'enabled', parameters('keyvaultEnabled')), 'openServiceMesh', createObject('enabled', parameters('openServiceMeshEnabled'), 'config', createObject()), 'ACCSGXDevicePlugin', createObject('enabled', parameters('sgxPlugin'), 'config', createObject())), if(not(empty(parameters('workspaceId'))), createObject('omsagent', createObject('enabled', not(empty(parameters('workspaceId'))), 'config', createObject('logAnalyticsWorkspaceResourceID', if(not(empty(parameters('workspaceId'))), parameters('workspaceId'), null())))), createObject()))]", - "aksPrivateDnsZone": "[if(equals(parameters('privateClusterDnsMethod'), 'privateDnsZone'), if(not(empty(parameters('dnsApiPrivateZoneId'))), parameters('dnsApiPrivateZoneId'), 'system'), parameters('privateClusterDnsMethod'))]", - "managedNATGatewayProfile": { - "natGatewayProfile": { - "managedOutboundIPProfile": { - "count": "[parameters('natGwIpCount')]" - }, - "idleTimeoutInMinutes": "[parameters('natGwIdleTimeout')]" - } - }, - "azureDefenderSecurityProfile": { - "securityProfile": { - "defender": { - "logAnalyticsWorkspaceResourceId": "[parameters('workspaceId')]", - "securityMonitoring": { - "enabled": "[parameters('defenderEnabled')]" - } - } - } - }, - "aksProperties": "[union(createObject('kubernetesVersion', parameters('aksVersion'), 'enableRBAC', true(), 'dnsPrefix', parameters('dnsPrefix'), 'aadProfile', if(parameters('enable_aad'), createObject('managed', true(), 'enableAzureRBAC', parameters('enableAzureRBAC'), 'tenantID', parameters('aad_tenant_id'), 'adminGroupObjectIDs', if(empty(parameters('admin_ids')), null(), parameters('admin_ids'))), null()), 'apiServerAccessProfile', if(not(empty(parameters('authorizedIPRanges'))), createObject('authorizedIPRanges', parameters('authorizedIPRanges')), createObject('enablePrivateCluster', parameters('enablePrivateCluster'), 'privateDNSZone', if(parameters('enablePrivateCluster'), variables('aksPrivateDnsZone'), ''), 'enablePrivateClusterPublicFQDN', and(parameters('enablePrivateCluster'), equals(parameters('privateClusterDnsMethod'), 'none')))), 'agentPoolProfiles', variables('agentPoolProfiles'), 'workloadAutoScalerProfile', createObject('keda', createObject('enabled', parameters('kedaEnabled'))), 'networkProfile', createObject('loadBalancerSku', 'standard', 'networkPlugin', parameters('networkPlugin'), 'networkPolicy', parameters('networkPolicy'), 'networkPluginMode', if(equals(parameters('networkPlugin'), 'azure'), parameters('networkPluginMode'), ''), 'networkDataplane', if(equals(parameters('networkPolicy'), 'cilium'), parameters('networkPolicy'), ''), 'podCidr', if(or(or(equals(parameters('networkPlugin'), 'kubenet'), equals(parameters('networkPluginMode'), 'Overlay')), parameters('cniDynamicIpAllocation')), parameters('podCidr'), null()), 'serviceCidr', parameters('serviceCidr'), 'dnsServiceIP', parameters('dnsServiceIP'), 'outboundType', variables('outboundTrafficType')), 'disableLocalAccounts', and(parameters('AksDisableLocalAccounts'), parameters('enable_aad')), 'autoUpgradeProfile', createObject('upgradeChannel', parameters('upgradeChannel')), 'addonProfiles', variables('aks_addons'), 'autoScalerProfile', if(variables('autoScale'), parameters('AutoscaleProfile'), createObject()), 'oidcIssuerProfile', createObject('enabled', parameters('oidcIssuer')), 'securityProfile', createObject('workloadIdentity', createObject('enabled', parameters('workloadIdentityEnabled')), 'defender', createObject('logAnalyticsWorkspaceResourceId', if(parameters('defenderEnabled'), parameters('workspaceId'), null()), 'securityMonitoring', createObject('enabled', parameters('defenderEnabled'))), 'imageCleaner', createObject('enabled', parameters('enableImageCleaner'), 'intervalHours', parameters('imageCleanerIntervalHours'))), 'ingressProfile', createObject('webAppRouting', createObject('enabled', parameters('warIngressNginx'))), 'storageProfile', createObject('blobCSIDriver', createObject('enabled', parameters('blobCSIDriver')), 'diskCSIDriver', createObject('enabled', parameters('diskCSIDriver')), 'fileCSIDriver', createObject('enabled', parameters('fileCSIDriver')))), if(equals(variables('outboundTrafficType'), 'managedNATGateway'), variables('managedNATGatewayProfile'), createObject()), if(parameters('defenderEnabled'), variables('azureDefenderSecurityProfile'), createObject()), if(not(empty(parameters('managedNodeResourceGroup'))), createObject('nodeResourceGroup', parameters('managedNodeResourceGroup')), createObject()), if(not(empty(parameters('serviceMeshProfile'))), createObject('serviceMeshProfile', variables('serviceMeshProfileObj')), createObject()))]", - "ingressModes": { - "external": { - "enabled": true, - "mode": "External" - }, - "internal": { - "enabled": true, - "mode": "Internal" - } - }, - "policySetBaseline": "/providers/Microsoft.Authorization/policySetDefinitions/a8640138-9b0a-4a28-b8cb-1666c838647d", - "policySetRestrictive": "/providers/Microsoft.Authorization/policySetDefinitions/42b8ef37-b724-4e24-bbc8-7a7708edfe00", - "buildInAKSRBACClusterAdmin": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b1ff04bb-8a4e-4dc4-8eb5-8693973ce19b')]" + "policyDefinitionId": "/providers/Microsoft.Authorization/policySetDefinitions/c047ea8e-9c78-49b2-958b-37e56d291a44" }, "resources": [ { - "type": "Microsoft.ContainerService/managedClusters", - "apiVersion": "2024-02-01", - "name": "[if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', parameters('identityId'))]": {} - } - }, - "properties": "[variables('aksProperties')]", - "sku": { - "name": "Base", - "tier": "[variables('akssku')]" - } - }, - { - "condition": "[not(empty(parameters('azurepolicy')))]", "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2023-04-01", - "name": "[format('{0}-{1}', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')), parameters('azurePolicyInitiative'))]", - "location": "[parameters('location')]", + "apiVersion": "2024-04-01", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "aksDeploymentSafeguardsAssignment", "properties": { - "policyDefinitionId": "[if(equals(parameters('azurePolicyInitiative'), 'Baseline'), variables('policySetBaseline'), variables('policySetRestrictive'))]", + "displayName": "AKS Deployment Safeguards", + "policyDefinitionId": "[variables('policyDefinitionId')]", + "enforcementMode": "DoNotEnforce", "parameters": { - "excludedNamespaces": { - "value": [ - "kube-system", - "gatekeeper-system", - "azure-arc", - "cluster-baseline-setting" - ] - }, "effect": { - "value": "[parameters('azurepolicy')]" - } - }, - "metadata": { - "assignedBy": "OSDU Developer" - }, - "displayName": "[format('Kubernetes cluster pod security {0} standards for Linux-based workloads', parameters('azurePolicyInitiative'))]", - "description": "As per: https://github.com/Azure/azure-policy/blob/master/built-in-policies/policySetDefinitions/Kubernetes/" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]" - ] - }, - { - "condition": "[and(parameters('enableAzureRBAC'), not(empty(parameters('adminPrincipalId'))))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), 'aksadmin', variables('buildInAKSRBACClusterAdmin'))]", - "properties": { - "roleDefinitionId": "[variables('buildInAKSRBACClusterAdmin')]", - "principalType": "[if(parameters('automatedDeployment'), 'ServicePrincipal', 'User')]", - "principalId": "[parameters('adminPrincipalId')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]" - ] - }, - { - "condition": "[parameters('fluxGitOpsAddon')]", - "type": "Microsoft.KubernetesConfiguration/extensions", - "apiVersion": "2023-05-01", - "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]", - "name": "flux", - "properties": { - "extensionType": "microsoft.flux", - "autoUpgradeMinorVersion": true, - "configurationSettings": { - "multiTenancy.enforce": "false" - }, - "releaseTrain": "Stable", - "scope": { - "cluster": { - "releaseNamespace": "flux-system" + "value": "Audit" + }, + "allowedUsers": { + "value": [] + }, + "allowedGroups": { + "value": [] + }, + "cpuLimit": { + "value": "4" + }, + "memoryLimit": { + "value": "4Gi" + }, + "labels": { + "value": [] + }, + "allowedContainerImagesRegex": { + "value": ".*" + }, + "reservedTaints": { + "value": [] } - }, - "configurationProtectedSettings": {} - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]", - "[extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), 'Microsoft.KubernetesConfiguration/extensions', 'dapr')]" - ] - }, + } + } + } + ] + } + }, + "dependsOn": [ + "cluster" + ] + }, + "appConfigExtension": { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-aks-extension-appconfig', parameters('bladeConfig').sectionName)]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "clusterName": { + "value": "[reference('cluster').outputs.name.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.30.23.60470", + "templateHash": "14099436865216246445" + } + }, + "parameters": { + "clusterName": { + "type": "string", + "metadata": { + "description": "The name of the Managed Cluster resource." + } + } + }, + "resources": [ { - "condition": "[parameters('daprAddon')]", "type": "Microsoft.KubernetesConfiguration/extensions", "apiVersion": "2023-05-01", - "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]", - "name": "dapr", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "appconfigurationkubernetesprovider", "properties": { - "extensionType": "Microsoft.Dapr", "autoUpgradeMinorVersion": true, - "releaseTrain": "Stable", "configurationSettings": { - "global.ha.enabled": "[format('{0}', parameters('daprAddonHA'))]" - }, - "scope": { - "cluster": { - "releaseNamespace": "dapr-system" - } + "global.clusterType": "managedclusters" }, - "configurationProtectedSettings": {} - }, - "dependsOn": [ - "[resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]" - ] - } - ], - "outputs": { - "aksClusterName": { - "type": "string", - "value": "[if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))]" - }, - "aksOidcIssuerUrl": { - "type": "string", - "value": "[if(parameters('oidcIssuer'), reference(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), '2024-02-01').oidcIssuerProfile.issuerURL, '')]" - }, - "userNodePoolName": { - "type": "string", - "value": "[parameters('nodePoolName')]" - }, - "systemNodePoolName": { - "type": "string", - "value": "[if(parameters('JustUseSystemPool'), parameters('nodePoolName'), 'npsystem')]" - }, - "aksPrivateDnsZone": { - "type": "string", - "value": "[variables('aksPrivateDnsZone')]" - }, - "privateFQDN": { - "type": "string", - "value": "[if(and(parameters('enablePrivateCluster'), not(equals(parameters('privateClusterDnsMethod'), 'none'))), reference(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), '2024-02-01').privateFQDN, '')]" - }, - "aksPrivateDnsZoneName": { - "type": "string", - "value": "[if(and(parameters('enablePrivateCluster'), not(equals(parameters('privateClusterDnsMethod'), 'none'))), join(skip(split(reference(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), '2024-02-01').privateFQDN, '.'), 1), '.'), '')]" - }, - "aksOidcFedIdentityProperties": { - "type": "object", - "metadata": { - "description": "This output can be directly leveraged when creating a ManagedId Federated Identity" - }, - "value": { - "issuer": "[if(parameters('oidcIssuer'), reference(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), '2024-02-01').oidcIssuerProfile.issuerURL, '')]", - "audiences": [ - "api://AzureADTokenExchange" - ], - "subject": "system:serviceaccount:ns:svcaccount" + "extensionType": "microsoft.appconfiguration" } - }, - "aksNodeResourceGroup": { - "type": "string", - "metadata": { - "description": "The name of the managed resource group AKS uses" - }, - "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), '2024-02-01').nodeResourceGroup]" - }, - "aksResourceId": { - "type": "string", - "metadata": { - "description": "The Azure resource id for the AKS cluster" - }, - "value": "[resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name')))]" - }, - "fluxReleaseNamespace": { - "type": "string", - "value": "[if(parameters('fluxGitOpsAddon'), reference(extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), 'Microsoft.KubernetesConfiguration/extensions', 'flux'), '2023-05-01').scope.cluster.releaseNamespace, '')]" - }, - "daprReleaseNamespace": { - "type": "string", - "value": "[if(parameters('daprAddon'), reference(extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', if(greater(length(variables('name')), 63), substring(variables('name'), 0, 63), variables('name'))), 'Microsoft.KubernetesConfiguration/extensions', 'dapr'), '2023-05-01').scope.cluster.releaseNamespace, '')]" } - } + ] } - } + }, + "dependsOn": [ + "cluster" + ] }, - "pool1": { + "fluxExtension": { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-pool1', parameters('bladeConfig').sectionName)]", + "name": "[format('{0}-flux-extension', parameters('bladeConfig').sectionName)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "AksName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" - }, - "PoolName": { - "value": "poolz1" - }, - "agentVMSize": "[if(empty(parameters('customVMSize')), createObject('value', variables('elasticPoolPresets')[parameters('clusterSize')].vmSize), createObject('value', parameters('customVMSize')))]", - "agentCount": { - "value": 1 + "clusterName": { + "value": "[reference('cluster').outputs.name.value]" }, - "agentCountMax": { - "value": 3 + "location": { + "value": "[parameters('location')]" }, - "availabilityZones": { - "value": [ - "1" - ] + "extensionType": { + "value": "microsoft.flux" }, - "subnetId": { - "value": "[parameters('aksSubnetId')]" + "name": { + "value": "flux" }, - "podSubnetId": { - "value": "[parameters('podSubnetId')]" + "releaseNamespace": { + "value": "flux-system" }, - "nodeTaints": { - "value": [ - "app=cluster:NoSchedule" - ] + "releaseTrain": { + "value": "Stable" }, - "nodeLabels": { + "configurationSettings": { "value": { - "app": "cluster" + "multiTenancy.enforce": "false", + "helm-controller.enabled": "true", + "source-controller.enabled": "true", + "kustomize-controller.enabled": "true", + "notification-controller.enabled": "true", + "image-automation-controller.enabled": "false", + "image-reflector-controller.enabled": "false" } } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.30.23.60470", - "templateHash": "6246806135827238683" - } + "templateHash": "4712911489121178960" + }, + "name": "Kubernetes Configuration Extensions", + "description": "This module deploys a Kubernetes Configuration Extension.", + "owner": "Azure/module-maintainers" }, "parameters": { - "AksName": { - "type": "string" - }, - "PoolName": { - "type": "string" - }, - "availabilityZones": { - "type": "array", - "defaultValue": [], + "name": { + "type": "string", "metadata": { - "description": "The zones to use for a node pool" + "description": "Required. The name of the Flux Configuration." } }, - "osDiskType": { - "type": "string", - "defaultValue": "Managed", + "enableTelemetry": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "OS disk type" + "description": "Optional. Enable/Disable usage telemetry for module." } }, - "agentVMSize": { + "clusterName": { "type": "string", - "defaultValue": "Standard_DS3_v2", "metadata": { - "description": "VM SKU" + "description": "Required. The name of the AKS cluster that should be configured." } }, - "osDiskSizeGB": { - "type": "int", - "defaultValue": 0, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Disk size in GB" + "description": "Optional. Location for all resources." } }, - "agentCount": { - "type": "int", - "defaultValue": 3, + "configurationProtectedSettings": { + "type": "secureObject", + "nullable": true, "metadata": { - "description": "The number of agents for the user node pool" + "description": "Optional. Configuration settings that are sensitive, as name-value pairs for configuring this extension." } }, - "agentCountMax": { - "type": "int", - "defaultValue": 0, + "configurationSettings": { + "type": "object", + "nullable": true, "metadata": { - "description": "The maximum number of nodes for the user node pool" + "description": "Optional. Configuration settings, as name-value pairs for configuring this extension." } }, - "maxPods": { - "type": "int", - "defaultValue": 30, + "extensionType": { + "type": "string", "metadata": { - "description": "The maximum number of pods per node." + "description": "Required. Type of the extension, of which this resource is an instance of. It must be one of the Extension Types registered with Microsoft.KubernetesConfiguration by the extension publisher." } }, - "nodeTaints": { - "type": "array", - "defaultValue": [], + "releaseTrain": { + "type": "string", + "nullable": true, "metadata": { - "description": "Any taints that should be applied to the node pool" + "description": "Optional. ReleaseTrain this extension participates in for auto-upgrade (e.g. Stable, Preview, etc.) - only if autoUpgradeMinorVersion is \"true\"." } }, - "nodeLabels": { - "type": "object", - "defaultValue": {}, + "releaseNamespace": { + "type": "string", + "nullable": true, "metadata": { - "description": "Any labels that should be applied to the node pool" + "description": "Optional. Namespace where the extension Release must be placed, for a Cluster scoped extension. If this namespace does not exist, it will be created." } }, - "subnetId": { + "targetNamespace": { "type": "string", + "nullable": true, "metadata": { - "description": "The subnet the node pool will use" + "description": "Optional. Namespace where the extension will be created for an Namespace scoped extension. If this namespace does not exist, it will be created." } }, - "podSubnetId": { + "version": { "type": "string", + "nullable": true, "metadata": { - "description": "The subnet the pods will use" + "description": "Optional. Version of the extension for this extension, if it is \"pinned\" to a specific version." } }, - "osType": { - "type": "string", - "defaultValue": "Linux", - "allowedValues": [ - "Linux", - "Windows" - ], + "fluxConfigurations": { + "type": "array", + "nullable": true, "metadata": { - "description": "OS Type for the node pool" + "description": "Optional. A list of flux configuraitons." } } }, - "variables": { - "autoScale": "[greater(parameters('agentCountMax'), parameters('agentCount'))]" - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters/agentPools", - "apiVersion": "2024-04-02-preview", - "name": "[format('{0}/{1}', parameters('AksName'), parameters('PoolName'))]", + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.kubernetesconfiguration-extension.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { - "mode": "User", - "vmSize": "[parameters('agentVMSize')]", - "count": "[parameters('agentCount')]", - "minCount": "[if(variables('autoScale'), parameters('agentCount'), null())]", - "maxCount": "[if(variables('autoScale'), parameters('agentCountMax'), null())]", - "enableAutoScaling": "[variables('autoScale')]", - "availabilityZones": "[if(not(empty(parameters('availabilityZones'))), parameters('availabilityZones'), null())]", - "osDiskType": "[parameters('osDiskType')]", - "osDiskSizeGB": "[parameters('osDiskSizeGB')]", - "osType": "[parameters('osType')]", - "osSKU": "[if(equals(parameters('osType'), 'Linux'), 'AzureLinux', null())]", - "maxPods": "[parameters('maxPods')]", - "type": "VirtualMachineScaleSets", - "vnetSubnetID": "[if(not(empty(parameters('subnetId'))), parameters('subnetId'), null())]", - "podSubnetID": "[if(not(empty(parameters('podSubnetId'))), parameters('podSubnetId'), null())]", - "upgradeSettings": { - "maxSurge": "33%" - }, - "nodeTaints": "[parameters('nodeTaints')]", - "nodeLabels": "[parameters('nodeLabels')]" + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } } + }, + "managedCluster": { + "existing": true, + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2022-07-01", + "name": "[parameters('clusterName')]" + }, + "extension": { + "type": "Microsoft.KubernetesConfiguration/extensions", + "apiVersion": "2022-03-01", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "[parameters('name')]", + "properties": { + "autoUpgradeMinorVersion": "[if(not(empty(parameters('version'))), false(), true())]", + "configurationProtectedSettings": "[parameters('configurationProtectedSettings')]", + "configurationSettings": "[parameters('configurationSettings')]", + "extensionType": "[parameters('extensionType')]", + "releaseTrain": "[parameters('releaseTrain')]", + "scope": { + "cluster": "[if(not(empty(coalesce(parameters('releaseNamespace'), ''))), createObject('releaseNamespace', parameters('releaseNamespace')), null())]", + "namespace": "[if(not(empty(coalesce(parameters('targetNamespace'), ''))), createObject('targetNamespace', parameters('targetNamespace')), null())]" + }, + "version": "[parameters('version')]" + }, + "dependsOn": [ + "managedCluster" + ] + }, + "fluxConfiguration": { + "copy": { + "name": "fluxConfiguration", + "count": "[length(coalesce(parameters('fluxConfigurations'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ManagedCluster-FluxConfiguration{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "clusterName": { + "value": "[parameters('clusterName')]" + }, + "scope": { + "value": "[coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()].scope]" + }, + "namespace": { + "value": "[coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()].namespace]" + }, + "sourceKind": "[if(contains(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'gitRepository'), createObject('value', 'GitRepository'), createObject('value', 'Bucket'))]", + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'name'), toLower(format('{0}-fluxconfiguration{1}', parameters('clusterName'), copyIndex())))]" + }, + "bucket": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'bucket')]" + }, + "configurationProtectedSettings": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'configurationProtectedSettings')]" + }, + "gitRepository": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'gitRepository')]" + }, + "kustomizations": { + "value": "[coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()].kustomizations]" + }, + "suspend": { + "value": "[tryGet(coalesce(parameters('fluxConfigurations'), createArray())[copyIndex()], 'suspend')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "885928168160399718" + }, + "name": "Kubernetes Configuration Flux Configurations", + "description": "This module deploys a Kubernetes Configuration Flux Configuration.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the Flux Configuration." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "clusterName": { + "type": "string", + "metadata": { + "description": "Required. The name of the AKS cluster that should be configured." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "bucket": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Conditional. Parameters to reconcile to the GitRepository source kind type. Required if `sourceKind` is `Bucket`." + } + }, + "configurationProtectedSettings": { + "type": "secureObject", + "nullable": true, + "metadata": { + "description": "Optional. Key-value pairs of protected configuration settings for the configuration." + } + }, + "gitRepository": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Conditional. Parameters to reconcile to the GitRepository source kind type. Required if `sourceKind` is `GitRepository`." + } + }, + "kustomizations": { + "type": "object", + "metadata": { + "description": "Required. Array of kustomizations used to reconcile the artifact pulled by the source type on the cluster." + } + }, + "namespace": { + "type": "string", + "metadata": { + "description": "Required. The namespace to which this configuration is installed to. Maximum of 253 lower case alphanumeric characters, hyphen and period only." + } + }, + "scope": { + "type": "string", + "allowedValues": [ + "cluster", + "namespace" + ], + "metadata": { + "description": "Required. Scope at which the configuration will be installed." + } + }, + "sourceKind": { + "type": "string", + "allowedValues": [ + "Bucket", + "GitRepository" + ], + "metadata": { + "description": "Required. Source Kind to pull the configuration data from." + } + }, + "suspend": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether this configuration should suspend its reconciliation of its kustomizations and sources." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.kubernetesconfiguration-fluxconfig.{0}.{1}', replace('0.3.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "managedCluster": { + "existing": true, + "type": "Microsoft.ContainerService/managedClusters", + "apiVersion": "2022-07-01", + "name": "[parameters('clusterName')]" + }, + "fluxConfiguration": { + "type": "Microsoft.KubernetesConfiguration/fluxConfigurations", + "apiVersion": "2023-05-01", + "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", + "name": "[parameters('name')]", + "properties": { + "bucket": "[parameters('bucket')]", + "configurationProtectedSettings": "[parameters('configurationProtectedSettings')]", + "gitRepository": "[parameters('gitRepository')]", + "kustomizations": "[parameters('kustomizations')]", + "namespace": "[parameters('namespace')]", + "scope": "[parameters('scope')]", + "sourceKind": "[parameters('sourceKind')]", + "suspend": "[parameters('suspend')]" + }, + "dependsOn": [ + "managedCluster" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the flux configuration." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the flux configuration." + }, + "value": "[extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/fluxConfigurations', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the flux configuration was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "extension", + "managedCluster" + ] } - ] + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the extension." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the extension." + }, + "value": "[extensionResourceId(resourceId('Microsoft.ContainerService/managedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/extensions', parameters('name'))]" + }, + "principalId": { + "type": "string", + "value": "[reference('extension').aksAssignedIdentity.principalId]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the extension was deployed into." + }, + "value": "[resourceGroup().name]" + } + } } }, "dependsOn": [ "cluster" ] }, - "pool2": { + "extensionClientId": { + "condition": "[variables('serviceLayerConfig').gitops.enablePrivateSoftware]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-pool2', parameters('bladeConfig').sectionName)]", + "name": "[format('{0}-script-clientId', parameters('bladeConfig').sectionName)]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "AksName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" + "kind": { + "value": "AzureCLI" }, - "PoolName": { - "value": "poolz2" + "name": { + "value": "aksExtensionClientId" }, - "agentVMSize": "[if(empty(parameters('customVMSize')), createObject('value', variables('elasticPoolPresets')[parameters('clusterSize')].vmSize), createObject('value', parameters('customVMSize')))]", - "agentCount": { - "value": 1 + "azCliVersion": { + "value": "2.63.0" + }, + "location": { + "value": "[parameters('location')]" }, - "agentCountMax": { - "value": 3 + "managedIdentities": { + "value": { + "userAssignedResourcesIds": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" + ] + } }, - "availabilityZones": { + "environmentVariables": { "value": [ - "2" + { + "name": "rgName", + "value": "[format('{0}_aks_{1}_nodes', resourceGroup().name, reference('cluster').outputs.name.value)]" + }, + { + "name": "principalId", + "value": "[reference('fluxExtension').outputs.principalId.value]" + } ] }, - "subnetId": { - "value": "[parameters('aksSubnetId')]" + "timeout": { + "value": "PT30M" }, - "podSubnetId": { - "value": "[parameters('podSubnetId')]" - }, - "nodeTaints": { - "value": [ - "app=cluster:NoSchedule" - ] + "retentionInterval": { + "value": "PT1H" }, - "nodeLabels": { - "value": { - "app": "cluster" - } + "scriptContent": { + "value": " az login --identity\n\n echo \"Looking up client ID for $principalId in ResourceGroup $rgName\"\n clientId=$(az identity list --resource-group $rgName --query \"[?principalId=='$principalId'] | [0].clientId\" -otsv)\n \n echo \"Found ClientId: $clientId\"\n echo \"{\\\"clientId\\\":\\\"$clientId\\\"}\" | jq -c '.' > $AZ_SCRIPTS_OUTPUT_PATH\n " } }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6246806135827238683" + "version": "0.29.47.4906", + "templateHash": "5978422939896103340" + }, + "name": "Deployment Scripts", + "description": "This module deploys Deployment Scripts.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "managedIdentitiesType": { + "type": "object", + "properties": { + "userAssignedResourcesIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "environmentVariableType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the environment variable." + } + }, + "secureValue": { + "type": "securestring", + "nullable": true, + "metadata": { + "description": "Required. The value of the secure environment variable." + } + }, + "value": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. The value of the environment variable." + } + } + } } }, "parameters": { - "AksName": { - "type": "string" - }, - "PoolName": { - "type": "string" - }, - "availabilityZones": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The zones to use for a node pool" - } - }, - "osDiskType": { + "name": { "type": "string", - "defaultValue": "Managed", + "maxLength": 90, "metadata": { - "description": "OS disk type" + "description": "Required. Name of the Deployment Script." } }, - "agentVMSize": { + "location": { "type": "string", - "defaultValue": "Standard_DS3_v2", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "VM SKU" + "description": "Optional. Location for all resources." } }, - "osDiskSizeGB": { - "type": "int", - "defaultValue": 0, + "kind": { + "type": "string", + "allowedValues": [ + "AzureCLI", + "AzurePowerShell" + ], "metadata": { - "description": "Disk size in GB" + "description": "Required. Specifies the Kind of the Deployment Script." } }, - "agentCount": { - "type": "int", - "defaultValue": 3, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", "metadata": { - "description": "The number of agents for the user node pool" + "description": "Optional. The managed identity definition for this resource." } }, - "agentCountMax": { - "type": "int", - "defaultValue": 0, + "tags": { + "type": "object", + "nullable": true, "metadata": { - "description": "The maximum number of nodes for the user node pool" + "description": "Optional. Resource tags." } }, - "maxPods": { - "type": "int", - "defaultValue": 30, + "azPowerShellVersion": { + "type": "string", + "nullable": true, "metadata": { - "description": "The maximum number of pods per node." + "description": "Optional. Azure PowerShell module version to be used. See a list of supported Azure PowerShell versions: https://mcr.microsoft.com/v2/azuredeploymentscripts-powershell/tags/list." } }, - "nodeTaints": { - "type": "array", - "defaultValue": [], + "azCliVersion": { + "type": "string", + "nullable": true, "metadata": { - "description": "Any taints that should be applied to the node pool" + "description": "Optional. Azure CLI module version to be used. See a list of supported Azure CLI versions: https://mcr.microsoft.com/v2/azure-cli/tags/list." } }, - "nodeLabels": { - "type": "object", - "defaultValue": {}, + "scriptContent": { + "type": "string", + "nullable": true, "metadata": { - "description": "Any labels that should be applied to the node pool" + "description": "Optional. Script body. Max length: 32000 characters. To run an external script, use primaryScriptURI instead." } }, - "subnetId": { + "primaryScriptUri": { "type": "string", + "nullable": true, "metadata": { - "description": "The subnet the node pool will use" + "description": "Optional. Uri for the external script. This is the entry point for the external script. To run an internal script, use the scriptContent parameter instead." } }, - "podSubnetId": { - "type": "string", + "environmentVariables": { + "type": "array", + "items": { + "$ref": "#/definitions/environmentVariableType" + }, + "nullable": true, "metadata": { - "description": "The subnet the pods will use" + "description": "Optional. The environment variables to pass over to the script." } }, - "osType": { - "type": "string", - "defaultValue": "Linux", - "allowedValues": [ - "Linux", - "Windows" - ], + "supportingScriptUris": { + "type": "array", + "nullable": true, "metadata": { - "description": "OS Type for the node pool" - } - } - }, - "variables": { - "autoScale": "[greater(parameters('agentCountMax'), parameters('agentCount'))]" - }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters/agentPools", - "apiVersion": "2024-04-02-preview", - "name": "[format('{0}/{1}', parameters('AksName'), parameters('PoolName'))]", - "properties": { - "mode": "User", - "vmSize": "[parameters('agentVMSize')]", - "count": "[parameters('agentCount')]", - "minCount": "[if(variables('autoScale'), parameters('agentCount'), null())]", - "maxCount": "[if(variables('autoScale'), parameters('agentCountMax'), null())]", - "enableAutoScaling": "[variables('autoScale')]", - "availabilityZones": "[if(not(empty(parameters('availabilityZones'))), parameters('availabilityZones'), null())]", - "osDiskType": "[parameters('osDiskType')]", - "osDiskSizeGB": "[parameters('osDiskSizeGB')]", - "osType": "[parameters('osType')]", - "osSKU": "[if(equals(parameters('osType'), 'Linux'), 'AzureLinux', null())]", - "maxPods": "[parameters('maxPods')]", - "type": "VirtualMachineScaleSets", - "vnetSubnetID": "[if(not(empty(parameters('subnetId'))), parameters('subnetId'), null())]", - "podSubnetID": "[if(not(empty(parameters('podSubnetId'))), parameters('podSubnetId'), null())]", - "upgradeSettings": { - "maxSurge": "33%" - }, - "nodeTaints": "[parameters('nodeTaints')]", - "nodeLabels": "[parameters('nodeLabels')]" + "description": "Optional. List of supporting files for the external script (defined in primaryScriptUri). Does not work with internal scripts (code defined in scriptContent)." } - } - ] - } - }, - "dependsOn": [ - "cluster" - ] - }, - "pool3": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-pool3', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "AksName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" - }, - "PoolName": { - "value": "poolz3" - }, - "agentVMSize": "[if(empty(parameters('customVMSize')), createObject('value', variables('elasticPoolPresets')[parameters('clusterSize')].vmSize), createObject('value', parameters('customVMSize')))]", - "agentCount": { - "value": 1 - }, - "agentCountMax": { - "value": 3 - }, - "availabilityZones": { - "value": [ - "3" - ] - }, - "subnetId": { - "value": "[parameters('aksSubnetId')]" - }, - "podSubnetId": { - "value": "[parameters('podSubnetId')]" - }, - "nodeTaints": { - "value": [ - "app=cluster:NoSchedule" - ] - }, - "nodeLabels": { - "value": { - "app": "cluster" - } - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6246806135827238683" - } - }, - "parameters": { - "AksName": { - "type": "string" - }, - "PoolName": { - "type": "string" }, - "availabilityZones": { + "subnetResourceIds": { "type": "array", - "defaultValue": [], + "items": { + "type": "string" + }, + "nullable": true, "metadata": { - "description": "The zones to use for a node pool" + "description": "Optional. List of subnet IDs to use for the container group. This is required if you want to run the deployment script in a private network. When using a private network, the `Storage File Data Privileged Contributor` role needs to be assigned to the user-assigned managed identity and the deployment principal needs to have permissions to list the storage account keys. Also, Shared-Keys must not be disabled on the used storage account [ref](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-script-vnet)." } }, - "osDiskType": { + "arguments": { "type": "string", - "defaultValue": "Managed", + "nullable": true, "metadata": { - "description": "OS disk type" + "description": "Optional. Command-line arguments to pass to the script. Arguments are separated by spaces." } }, - "agentVMSize": { + "retentionInterval": { "type": "string", - "defaultValue": "Standard_DS3_v2", + "defaultValue": "P1D", "metadata": { - "description": "VM SKU" + "description": "Optional. Interval for which the service retains the script resource after it reaches a terminal state. Resource will be deleted when this duration expires. Duration is based on ISO 8601 pattern (for example P7D means one week)." } }, - "osDiskSizeGB": { - "type": "int", - "defaultValue": 0, + "baseTime": { + "type": "string", + "defaultValue": "[utcNow('yyyy-MM-dd-HH-mm-ss')]", "metadata": { - "description": "Disk size in GB" + "description": "Generated. Do not provide a value! This date value is used to make sure the script run every time the template is deployed." } }, - "agentCount": { - "type": "int", - "defaultValue": 3, + "runOnce": { + "type": "bool", + "defaultValue": false, "metadata": { - "description": "The number of agents for the user node pool" + "description": "Optional. When set to false, script will run every time the template is deployed. When set to true, the script will only run once." } }, - "agentCountMax": { - "type": "int", - "defaultValue": 0, + "cleanupPreference": { + "type": "string", + "defaultValue": "Always", + "allowedValues": [ + "Always", + "OnSuccess", + "OnExpiration" + ], "metadata": { - "description": "The maximum number of nodes for the user node pool" + "description": "Optional. The clean up preference when the script execution gets in a terminal state. Specify the preference on when to delete the deployment script resources. The default value is Always, which means the deployment script resources are deleted despite the terminal state (Succeeded, Failed, canceled)." } }, - "maxPods": { - "type": "int", - "defaultValue": 30, + "containerGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "The maximum number of pods per node." + "description": "Optional. Container group name, if not specified then the name will get auto-generated. Not specifying a 'containerGroupName' indicates the system to generate a unique name which might end up flagging an Azure Policy as non-compliant. Use 'containerGroupName' when you have an Azure Policy that expects a specific naming convention or when you want to fully control the name. 'containerGroupName' property must be between 1 and 63 characters long, must contain only lowercase letters, numbers, and dashes and it cannot start or end with a dash and consecutive dashes are not allowed." } }, - "nodeTaints": { - "type": "array", - "defaultValue": [], + "storageAccountResourceId": { + "type": "string", + "defaultValue": "", "metadata": { - "description": "Any taints that should be applied to the node pool" + "description": "Optional. The resource ID of the storage account to use for this deployment script. If none is provided, the deployment script uses a temporary, managed storage account." } }, - "nodeLabels": { - "type": "object", - "defaultValue": {}, + "timeout": { + "type": "string", + "nullable": true, "metadata": { - "description": "Any labels that should be applied to the node pool" + "description": "Optional. Maximum allowed script execution time specified in ISO 8601 format. Default value is PT1H - 1 hour; 'PT30M' - 30 minutes; 'P5D' - 5 days; 'P1Y' 1 year." } }, - "subnetId": { - "type": "string", + "lock": { + "$ref": "#/definitions/lockType", "metadata": { - "description": "The subnet the node pool will use" + "description": "Optional. The lock settings of the service." } }, - "podSubnetId": { - "type": "string", + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", "metadata": { - "description": "The subnet the pods will use" + "description": "Optional. Array of role assignments to create." } }, - "osType": { - "type": "string", - "defaultValue": "Linux", - "allowedValues": [ - "Linux", - "Windows" - ], + "enableTelemetry": { + "type": "bool", + "defaultValue": true, "metadata": { - "description": "OS Type for the node pool" + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "autoScale": "[greater(parameters('agentCountMax'), parameters('agentCount'))]" + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + }, + { + "name": "subnetIds", + "count": "[length(coalesce(parameters('subnetResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('subnetResourceIds'), createArray())[copyIndex('subnetIds')]]" + } + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + }, + "containerSettings": { + "containerGroupName": "[parameters('containerGroupName')]", + "subnetIds": "[if(not(empty(coalesce(variables('subnetIds'), createArray()))), variables('subnetIds'), null())]" + }, + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourcesIds'), createObject()))), 'UserAssigned', null()), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]" }, - "resources": [ - { - "type": "Microsoft.ContainerService/managedClusters/agentPools", - "apiVersion": "2024-04-02-preview", - "name": "[format('{0}/{1}', parameters('AksName'), parameters('PoolName'))]", + "resources": { + "storageAccount": { + "condition": "[not(empty(parameters('storageAccountResourceId')))]", + "existing": true, + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-04-01", + "subscriptionId": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '////'), '/')[4]]", + "name": "[last(split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), 'dummyAccount'), '/'))]" + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.resources-deploymentscript.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { - "mode": "User", - "vmSize": "[parameters('agentVMSize')]", - "count": "[parameters('agentCount')]", - "minCount": "[if(variables('autoScale'), parameters('agentCount'), null())]", - "maxCount": "[if(variables('autoScale'), parameters('agentCountMax'), null())]", - "enableAutoScaling": "[variables('autoScale')]", - "availabilityZones": "[if(not(empty(parameters('availabilityZones'))), parameters('availabilityZones'), null())]", - "osDiskType": "[parameters('osDiskType')]", - "osDiskSizeGB": "[parameters('osDiskSizeGB')]", - "osType": "[parameters('osType')]", - "osSKU": "[if(equals(parameters('osType'), 'Linux'), 'AzureLinux', null())]", - "maxPods": "[parameters('maxPods')]", - "type": "VirtualMachineScaleSets", - "vnetSubnetID": "[if(not(empty(parameters('subnetId'))), parameters('subnetId'), null())]", - "podSubnetID": "[if(not(empty(parameters('podSubnetId'))), parameters('podSubnetId'), null())]", - "upgradeSettings": { - "maxSurge": "33%" - }, - "nodeTaints": "[parameters('nodeTaints')]", - "nodeLabels": "[parameters('nodeLabels')]" + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } } + }, + "deploymentScript": { + "type": "Microsoft.Resources/deploymentScripts", + "apiVersion": "2023-08-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", + "kind": "[parameters('kind')]", + "properties": { + "azPowerShellVersion": "[if(equals(parameters('kind'), 'AzurePowerShell'), parameters('azPowerShellVersion'), null())]", + "azCliVersion": "[if(equals(parameters('kind'), 'AzureCLI'), parameters('azCliVersion'), null())]", + "containerSettings": "[if(not(empty(variables('containerSettings'))), variables('containerSettings'), null())]", + "storageAccountSettings": "[if(not(empty(parameters('storageAccountResourceId'))), if(not(empty(parameters('storageAccountResourceId'))), createObject('storageAccountKey', if(empty(parameters('subnetResourceIds')), listKeys(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '//'), '/')[2], split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), '////'), '/')[4]), 'Microsoft.Storage/storageAccounts', last(split(if(not(empty(parameters('storageAccountResourceId'))), parameters('storageAccountResourceId'), 'dummyAccount'), '/'))), '2023-01-01').keys[0].value, null()), 'storageAccountName', last(split(parameters('storageAccountResourceId'), '/'))), null()), null())]", + "arguments": "[parameters('arguments')]", + "environmentVariables": "[parameters('environmentVariables')]", + "scriptContent": "[if(not(empty(parameters('scriptContent'))), parameters('scriptContent'), null())]", + "primaryScriptUri": "[if(not(empty(parameters('primaryScriptUri'))), parameters('primaryScriptUri'), null())]", + "supportingScriptUris": "[if(not(empty(parameters('supportingScriptUris'))), parameters('supportingScriptUris'), null())]", + "cleanupPreference": "[parameters('cleanupPreference')]", + "forceUpdateTag": "[if(parameters('runOnce'), resourceGroup().name, parameters('baseTime'))]", + "retentionInterval": "[parameters('retentionInterval')]", + "timeout": "[parameters('timeout')]" + }, + "dependsOn": [ + "storageAccount" + ] + }, + "deploymentScript_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Resources/deploymentScripts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "deploymentScript" + ] + }, + "deploymentScript_roleAssignments": { + "copy": { + "name": "deploymentScript_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Resources/deploymentScripts/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Resources/deploymentScripts', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "deploymentScript" + ] + }, + "deploymentScriptLogs": { + "existing": true, + "type": "Microsoft.Resources/deploymentScripts/logs", + "apiVersion": "2023-08-01", + "name": "[format('{0}/{1}', parameters('name'), 'default')]", + "dependsOn": [ + "deploymentScript" + ] } - ] + }, + "outputs": { + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the deployment script." + }, + "value": "[resourceId('Microsoft.Resources/deploymentScripts', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the deployment script was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the deployment script." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('deploymentScript', '2023-08-01', 'full').location]" + }, + "outputs": { + "type": "object", + "metadata": { + "description": "The output of the deployment script." + }, + "value": "[coalesce(tryGet(reference('deploymentScript'), 'outputs'), createObject())]" + }, + "deploymentScriptLogs": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The logs of the deployment script." + }, + "value": "[split(reference('deploymentScriptLogs').log, '\n')]" + } + } } }, "dependsOn": [ - "cluster" + "appIdentity", + "cluster", + "fluxExtension" ] }, "federatedCredentials": { @@ -33546,7 +34460,7 @@ ] }, "issuer": { - "value": "[reference('cluster').outputs.aksOidcIssuerUrl.value]" + "value": "[reference('cluster').outputs.oidcIssuerUrl.value]" }, "userAssignedIdentityName": { "value": "[parameters('managedIdentityName')]" @@ -33907,259 +34821,6 @@ "federatedCredentials" ] }, - "helmAppConfigProvider": { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-helm-appconfig-provider', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "aksName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "initialScriptDelay": { - "value": "130s" - }, - "newOrExistingManagedIdentity": { - "value": "existing" - }, - "managedIdentityName": { - "value": "[parameters('managedIdentityName')]" - }, - "existingManagedIdentitySubId": { - "value": "[subscription().subscriptionId]" - }, - "existingManagedIdentityResourceGroupName": { - "value": "[resourceGroup().name]" - }, - "commands": { - "value": [ - "helm install azureappconfiguration.kubernetesprovider oci://mcr.microsoft.com/azure-app-configuration/helmchart/kubernetes-provider --namespace azappconfig-system --create-namespace" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16189139743926010860" - }, - "name": "AKS Run Command Script", - "description": "An Azure CLI Deployment Script that allows you to run a command on a Kubernetes cluster.", - "owner": "Aks-Bicep-Accelerator-Maintainers" - }, - "parameters": { - "aksName": { - "type": "string", - "metadata": { - "description": "The name of the Azure Kubernetes Service" - } - }, - "location": { - "type": "string", - "metadata": { - "description": "The location to deploy the resources to" - } - }, - "forceUpdateTag": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "How the deployment script should be forced to execute" - } - }, - "rbacRolesNeeded": { - "type": "array", - "defaultValue": [ - "b24988ac-6180-42a0-ab88-20f7382dd24c", - "7f6c6a51-bcf8-42ba-9220-52d62157d7db" - ], - "metadata": { - "description": "An array of Azure RoleIds that are required for the DeploymentScript resource" - } - }, - "newOrExistingManagedIdentity": { - "type": "string", - "defaultValue": "new", - "allowedValues": [ - "new", - "existing" - ], - "metadata": { - "description": "Create \"new\" or use \"existing\" Managed Identity. Default: new" - } - }, - "managedIdentityName": { - "type": "string", - "defaultValue": "[format('id-AksRunCommandProxy-{0}', parameters('location'))]", - "metadata": { - "description": "Name of the Managed Identity resource" - } - }, - "existingManagedIdentitySubId": { - "type": "string", - "defaultValue": "[subscription().subscriptionId]", - "metadata": { - "description": "For an existing Managed Identity, the Subscription Id it is located in" - } - }, - "existingManagedIdentityResourceGroupName": { - "type": "string", - "defaultValue": "[resourceGroup().name]", - "metadata": { - "description": "For an existing Managed Identity, the Resource Group it is located in" - } - }, - "commands": { - "type": "array", - "metadata": { - "description": "An array of commands to run" - } - }, - "initialScriptDelay": { - "type": "string", - "defaultValue": "120s", - "metadata": { - "description": "A delay before the script import operation starts. Primarily to allow Azure AAD Role Assignments to propagate" - } - }, - "cleanupPreference": { - "type": "string", - "defaultValue": "OnSuccess", - "allowedValues": [ - "OnSuccess", - "OnExpiration", - "Always" - ], - "metadata": { - "description": "When the script resource is cleaned up" - } - }, - "isCrossTenant": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Set to true when deploying template across tenants" - } - } - }, - "variables": { - "$fxv#0": "#!/bin/bash\n\nset -e +H\n# -e to exit on error\n# +H to prevent history expansion\n\nif [ \"$loopIndex\" == \"0\" ] && [ \"$initialDelay\" != \"0\" ]\nthen\n echo \"Waiting on RBAC replication ($initialDelay)\"\n sleep $initialDelay\n\n #Force RBAC refresh\n az logout\n az login --identity\nfi\n\necho \"Sending command $command to AKS Cluster $aksName in $RG\"\ncmdOut=$(az aks command invoke -g $RG -n $aksName -o json --command \"${command}\")\necho $cmdOut\n\njsonOutputString=$cmdOut\necho $jsonOutputString > $AZ_SCRIPTS_OUTPUT_PATH\n", - "useExistingManagedIdentity": "[equals(parameters('newOrExistingManagedIdentity'), 'existing')]", - "delegatedManagedIdentityResourceId": "[if(variables('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')))]" - }, - "resources": [ - { - "condition": "[not(variables('useExistingManagedIdentity'))]", - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "name": "[parameters('managedIdentityName')]", - "location": "[parameters('location')]" - }, - { - "copy": { - "name": "rbac", - "count": "[length(parameters('rbacRolesNeeded'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('aksName'))]", - "name": "[guid(resourceId('Microsoft.ContainerService/managedClusters', parameters('aksName')), parameters('rbacRolesNeeded')[copyIndex()], if(variables('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('rbacRolesNeeded')[copyIndex()])]", - "principalId": "[if(variables('useExistingManagedIdentity'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId, reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), '2023-01-31').principalId)]", - "principalType": "ServicePrincipal", - "delegatedManagedIdentityResourceId": "[if(parameters('isCrossTenant'), variables('delegatedManagedIdentityResourceId'), null())]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]" - ] - }, - { - "copy": { - "name": "runAksCommand", - "count": "[length(parameters('commands'))]", - "mode": "serial", - "batchSize": 1 - }, - "type": "Microsoft.Resources/deploymentScripts", - "apiVersion": "2023-08-01", - "name": "[format('script-{0}-{1}-{2}', parameters('aksName'), deployment().name, copyIndex())]", - "location": "[parameters('location')]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', if(variables('useExistingManagedIdentity'), extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('existingManagedIdentitySubId'), parameters('existingManagedIdentityResourceGroupName')), 'Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName')), resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))))]": {} - } - }, - "kind": "AzureCLI", - "properties": { - "forceUpdateTag": "[parameters('forceUpdateTag')]", - "azCliVersion": "2.63.0", - "timeout": "PT30M", - "retentionInterval": "PT1H", - "environmentVariables": [ - { - "name": "RG", - "value": "[resourceGroup().name]" - }, - { - "name": "aksName", - "value": "[parameters('aksName')]" - }, - { - "name": "command", - "value": "[parameters('commands')[copyIndex()]]" - }, - { - "name": "initialDelay", - "value": "[parameters('initialScriptDelay')]" - }, - { - "name": "loopIndex", - "value": "[string(copyIndex())]" - } - ], - "scriptContent": "[variables('$fxv#0')]", - "cleanupPreference": "[parameters('cleanupPreference')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('managedIdentityName'))]", - "rbac" - ] - } - ], - "outputs": { - "commandOutput": { - "type": "array", - "metadata": { - "description": "Array of command output from each Deployment Script AKS run command" - }, - "copy": { - "count": "[length(parameters('commands'))]", - "input": { - "Index": "[copyIndex()]", - "Name": "[format('script-{0}-{1}-{2}', parameters('aksName'), deployment().name, copyIndex())]", - "CommandOutput": "[reference(resourceId('Microsoft.Resources/deploymentScripts', format('script-{0}-{1}-{2}', parameters('aksName'), deployment().name, copyIndex())), '2023-08-01').outputs]" - } - } - } - } - } - }, - "dependsOn": [ - "cluster" - ] - }, "app_config": { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -34873,7 +35534,7 @@ "mode": "Incremental", "parameters": { "aksName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" + "value": "[reference('cluster').outputs.name.value]" }, "location": { "value": "[parameters('location')]" @@ -35158,10 +35819,10 @@ "value": "[parameters('location')]" }, "namespace": { - "value": "[reference('cluster').outputs.fluxReleaseNamespace.value]" + "value": "flux-system" }, "clusterName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" + "value": "[reference('cluster').outputs.name.value]" }, "scope": { "value": "cluster" @@ -35359,774 +36020,8 @@ "dependsOn": [ "app_config", "appConfigMap", - "cluster", - "pool1", - "pool2", - "pool3" - ] - }, - "prometheus": { - "condition": "[parameters('enableMonitoring')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-managed-prometheus', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": "[if(greater(length(variables('name')), 23), createObject('value', substring(variables('name'), 0, 23)), createObject('value', variables('name')))]", - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" - }, - "publicNetworkAccess": { - "value": "Enabled" - }, - "clusterName": { - "value": "[reference('cluster').outputs.aksClusterName.value]" - }, - "actionGroupId": { - "value": "" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14168109191710291458" - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Specifies the name of the Azure Monitor managed service for Prometheus resource." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Specifies the location of the Azure Monitor managed service for Prometheus resource." - } - }, - "clusterName": { - "type": "string", - "metadata": { - "description": "Specifies the name of the AKS cluster." - } - }, - "publicNetworkAccess": { - "type": "string", - "defaultValue": "Enabled", - "allowedValues": [ - "Enabled", - "Disabled" - ], - "metadata": { - "description": "Specifies whether or not public endpoint access is allowed for the Azure Monitor managed service for Prometheus resource." - } - }, - "actionGroupId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Specifies the resource id of an Action Group resource. If empty, no action is specifies for metric alerts." - } - }, - "tags": { - "type": "object", - "metadata": { - "description": "Specifies the resource tags for the Azure Monitor managed service for Prometheus resource." - } - } - }, - "variables": { - "nodeRecordingRuleGroupPrefix": "NodeRecordingRulesRuleGroup-", - "nodeRecordingRuleGroupName": "[format('{0}{1}', variables('nodeRecordingRuleGroupPrefix'), parameters('clusterName'))]", - "nodeRecordingRuleGroupDescription": "Node Recording Rules RuleGroup", - "version": " - 0.1" - }, - "resources": [ - { - "type": "Microsoft.Monitor/accounts", - "apiVersion": "2023-04-03", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]" - }, - { - "type": "Microsoft.Insights/dataCollectionEndpoints", - "apiVersion": "2022-06-01", - "name": "[format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName'))]", - "location": "[parameters('location')]", - "kind": "Linux", - "tags": "[parameters('tags')]", - "properties": { - "networkAcls": { - "publicNetworkAccess": "[parameters('publicNetworkAccess')]" - } - } - }, - { - "type": "Microsoft.Insights/dataCollectionRules", - "apiVersion": "2022-06-01", - "name": "[format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "properties": { - "dataCollectionEndpointId": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName')))]", - "dataSources": { - "prometheusForwarder": [ - { - "name": "PrometheusDataSource", - "streams": [ - "Microsoft-PrometheusMetrics" - ], - "labelIncludeFilter": {} - } - ] - }, - "destinations": { - "monitoringAccounts": [ - { - "accountResourceId": "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]", - "name": "MonitoringAccount1" - } - ] - }, - "dataFlows": [ - { - "streams": [ - "Microsoft-PrometheusMetrics" - ], - "destinations": [ - "MonitoringAccount1" - ] - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]", - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName')))]" - ] - }, - { - "type": "Microsoft.Insights/dataCollectionRuleAssociations", - "apiVersion": "2022-06-01", - "scope": "[format('Microsoft.ContainerService/managedClusters/{0}', parameters('clusterName'))]", - "name": "[format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName'))]", - "properties": { - "dataCollectionRuleId": "[resourceId('Microsoft.Insights/dataCollectionRules', format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName')))]", - "description": "Association of data collection rule. Deleting this association will break the data collection for this AKS Cluster." - }, - "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionRules', format('MSProm-{0}-{1}', parameters('location'), parameters('clusterName')))]" - ] - }, - { - "type": "Microsoft.AlertsManagement/prometheusRuleGroups", - "apiVersion": "2023-03-01", - "name": "[variables('nodeRecordingRuleGroupName')]", - "location": "[parameters('location')]", - "properties": { - "description": "[format('{0}{1}', variables('nodeRecordingRuleGroupDescription'), variables('version'))]", - "scopes": [ - "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]" - ], - "enabled": true, - "clusterName": "[parameters('clusterName')]", - "interval": "PT1M", - "rules": [ - { - "record": "instance:node_num_cpu:sum", - "expression": "count without (cpu, mode) ( node_cpu_seconds_total{job=\"node\",mode=\"idle\"})" - }, - { - "record": "instance:node_cpu_utilisation:rate5m", - "expression": "1 - avg without (cpu) ( sum without (mode) (rate(node_cpu_seconds_total{job=\"node\", mode=~\"idle|iowait|steal\"}[5m])))" - }, - { - "record": "instance:node_load1_per_cpu:ratio", - "expression": "( node_load1{job=\"node\"}/ instance:node_num_cpu:sum{job=\"node\"})" - }, - { - "record": "instance:node_memory_utilisation:ratio", - "expression": "1 - ( ( node_memory_MemAvailable_bytes{job=\"node\"} or ( node_memory_Buffers_bytes{job=\"node\"} + node_memory_Cached_bytes{job=\"node\"} + node_memory_MemFree_bytes{job=\"node\"} + node_memory_Slab_bytes{job=\"node\"} ) )/ node_memory_MemTotal_bytes{job=\"node\"})" - }, - { - "record": "instance:node_vmstat_pgmajfault:rate5m", - "expression": "rate(node_vmstat_pgmajfault{job=\"node\"}[5m])" - }, - { - "record": "instance_device:node_disk_io_time_seconds:rate5m", - "expression": "rate(node_disk_io_time_seconds_total{job=\"node\", device!=\"\"}[5m])" - }, - { - "record": "instance_device:node_disk_io_time_weighted_seconds:rate5m", - "expression": "rate(node_disk_io_time_weighted_seconds_total{job=\"node\", device!=\"\"}[5m])" - }, - { - "record": "instance:node_network_receive_bytes_excluding_lo:rate5m", - "expression": "sum without (device) ( rate(node_network_receive_bytes_total{job=\"node\", device!=\"lo\"}[5m]))" - }, - { - "record": "instance:node_network_transmit_bytes_excluding_lo:rate5m", - "expression": "sum without (device) ( rate(node_network_transmit_bytes_total{job=\"node\", device!=\"lo\"}[5m]))" - }, - { - "record": "instance:node_network_receive_drop_excluding_lo:rate5m", - "expression": "sum without (device) ( rate(node_network_receive_drop_total{job=\"node\", device!=\"lo\"}[5m]))" - }, - { - "record": "instance:node_network_transmit_drop_excluding_lo:rate5m", - "expression": "sum without (device) ( rate(node_network_transmit_drop_total{job=\"node\", device!=\"lo\"}[5m]))" - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]" - ] - }, - { - "type": "Microsoft.AlertsManagement/prometheusRuleGroups", - "apiVersion": "2021-07-22-preview", - "name": "[format('CommunityCIAlerts-{0}', parameters('clusterName'))]", - "location": "[parameters('location')]", - "properties": { - "description": "Kubernetes Alert RuleGroup-communityCIAlerts - 0.1", - "scopes": [ - "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]" - ], - "clusterName": "[parameters('clusterName')]", - "enabled": true, - "interval": "PT1M", - "rules": [ - { - "alert": "KubePodCrashLooping", - "expression": "max_over_time(kube_pod_container_status_waiting_reason{reason=\"CrashLoopBackOff\", job=\"kube-state-metrics\"}[5m]) >= 1", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubePodNotReady", - "expression": "sum by (namespace, pod, cluster) ( max by(namespace, pod, cluster) ( kube_pod_status_phase{job=\"kube-state-metrics\", phase=~\"Pending|Unknown\"} ) * on(namespace, pod, cluster) group_left(owner_kind) topk by(namespace, pod, cluster) ( 1, max by(namespace, pod, owner_kind, cluster) (kube_pod_owner{owner_kind!=\"Job\"}) )) > 0", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeDeploymentReplicasMismatch", - "expression": "( kube_deployment_spec_replicas{job=\"kube-state-metrics\"} > kube_deployment_status_replicas_available{job=\"kube-state-metrics\"}) and ( changes(kube_deployment_status_replicas_updated{job=\"kube-state-metrics\"}[10m]) == 0)", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeStatefulSetReplicasMismatch", - "expression": "( kube_statefulset_status_replicas_ready{job=\"kube-state-metrics\"} != kube_statefulset_status_replicas{job=\"kube-state-metrics\"}) and ( changes(kube_statefulset_status_replicas_updated{job=\"kube-state-metrics\"}[10m]) == 0)", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeJobNotCompleted", - "expression": "time() - max by(namespace, job_name, cluster) (kube_job_status_start_time{job=\"kube-state-metrics\"} and kube_job_status_active{job=\"kube-state-metrics\"} > 0) > 43200", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeJobFailed", - "expression": "kube_job_failed{job=\"kube-state-metrics\"} > 0", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeHpaReplicasMismatch", - "expression": "(kube_horizontalpodautoscaler_status_desired_replicas{job=\"kube-state-metrics\"} !=kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"}) and(kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"} >kube_horizontalpodautoscaler_spec_min_replicas{job=\"kube-state-metrics\"}) and(kube_horizontalpodautoscaler_status_current_replicas{job=\"kube-state-metrics\"} 1.5", - "for": "PT5M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeMemoryQuotaOvercommit", - "expression": "sum(min without(resource) (kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\", resource=~\"(memory|requests.memory)\"})) /sum(kube_node_status_allocatable{resource=\"memory\", job=\"kube-state-metrics\"}) > 1.5", - "for": "PT5M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeQuotaAlmostFull", - "expression": "kube_resourcequota{job=\"kube-state-metrics\", type=\"used\"} / ignoring(instance, job, type)(kube_resourcequota{job=\"kube-state-metrics\", type=\"hard\"} > 0) > 0.9 < 1", - "for": "PT15M", - "labels": { - "severity": "info" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeVersionMismatch", - "expression": "count by (cluster) (count by (git_version, cluster) (label_replace(kubernetes_build_info{job!~\"kube-dns|coredns\"},\"git_version\",\"$1\",\"git_version\",\"(v[0-9]*.[0-9]*).*\"))) > 1", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeNodeNotReady", - "expression": "kube_node_status_condition{job=\"kube-state-metrics\",condition=\"Ready\",status=\"true\"} == 0", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeNodeUnreachable", - "expression": "(kube_node_spec_taint{job=\"kube-state-metrics\",key=\"node.kubernetes.io/unreachable\",effect=\"NoSchedule\"} unless ignoring(key,value) kube_node_spec_taint{job=\"kube-state-metrics\",key=~\"ToBeDeletedByClusterAutoscaler|cloud.google.com/impending-node-termination|aws-node-termination-handler/spot-itn\"}) == 1", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeletTooManyPods", - "expression": "count by(cluster, node) ( (kube_pod_status_phase{job=\"kube-state-metrics\",phase=\"Running\"} == 1) * on(instance,pod,namespace,cluster) group_left(node) topk by(instance,pod,namespace,cluster) (1, kube_pod_info{job=\"kube-state-metrics\"}))/max by(cluster, node) ( kube_node_status_capacity{job=\"kube-state-metrics\",resource=\"pods\"} != 1) > 0.95", - "for": "PT15M", - "labels": { - "severity": "info" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - }, - { - "alert": "KubeNodeReadinessFlapping", - "expression": "sum(changes(kube_node_status_condition{status=\"true\",condition=\"Ready\"}[15m])) by (cluster, node) > 2", - "for": "PT15M", - "labels": { - "severity": "warning" - }, - "severity": 3, - "enabled": true, - "resolveConfiguration": { - "autoResolved": true, - "timeToResolve": "PT10M" - }, - "actions": "[if(equals(parameters('actionGroupId'), ''), createArray(), createArray(createObject('actionGroupId', parameters('actionGroupId'))))]" - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]" - ] - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Monitor/accounts', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Monitor/accounts', parameters('name')), '2023-04-03', 'full').location]" - }, - "accountId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Monitor/accounts', parameters('name')), '2023-04-03').accountId]" - }, - "prometheusQueryEndpoint": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Monitor/accounts', parameters('name')), '2023-04-03').metrics.prometheusQueryEndpoint]" - }, - "internalId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Monitor/accounts', parameters('name')), '2023-04-03').metrics.internalId]" - } - } - } - }, - "dependsOn": [ "cluster" ] - }, - "grafana": { - "condition": "[parameters('enableMonitoring')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-managed-grafana', parameters('bladeConfig').sectionName)]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "name": "[if(greater(length(variables('name')), 23), createObject('value', substring(variables('name'), 0, 23)), createObject('value', variables('name')))]", - "location": { - "value": "[parameters('location')]" - }, - "tags": { - "value": "[union(parameters('tags'), createObject('layer', parameters('bladeConfig').displayName))]" - }, - "skuName": { - "value": "Standard" - }, - "apiKey": { - "value": "Enabled" - }, - "autoGeneratedDomainNameLabelScope": { - "value": "TenantReuse" - }, - "deterministicOutboundIP": { - "value": "Disabled" - }, - "publicNetworkAccess": { - "value": "Enabled" - }, - "zoneRedundancy": { - "value": "Disabled" - }, - "prometheusName": { - "value": "[reference('prometheus').outputs.name.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14420603474598171305" - } - }, - "parameters": { - "name": { - "type": "string", - "metadata": { - "description": "Specifies the name of the Azure Monitor managed service for Grafana resource." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "Specifies the location of the Azure Managed Grafana resource." - } - }, - "prometheusName": { - "type": "string", - "metadata": { - "description": "Specifies the name of the Azure Monitor managed service for Prometheus resource." - } - }, - "skuName": { - "type": "string", - "defaultValue": "Standard", - "metadata": { - "description": "Specifies the sku of the Azure Managed Grafana resource." - } - }, - "apiKey": { - "type": "string", - "defaultValue": "Enabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "Specifies the api key setting of the Azure Managed Grafana resource." - } - }, - "autoGeneratedDomainNameLabelScope": { - "type": "string", - "defaultValue": "TenantReuse", - "allowedValues": [ - "TenantReuse" - ], - "metadata": { - "description": "Specifies the scope for dns deterministic name hash calculation." - } - }, - "deterministicOutboundIP": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "Specifies whether the Azure Managed Grafana resource uses deterministic outbound IPs." - } - }, - "publicNetworkAccess": { - "type": "string", - "defaultValue": "Enabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "Specifies the the state for enable or disable traffic over the public interface for the the Azure Managed Grafana resource." - } - }, - "zoneRedundancy": { - "type": "string", - "defaultValue": "Disabled", - "allowedValues": [ - "Disabled", - "Enabled" - ], - "metadata": { - "description": "The zone redundancy setting of the Azure Managed Grafana resource." - } - }, - "userId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Specifies the object id of an Azure Active Directory user. In general, this the object id of the system administrator who deploys the Azure resources." - } - }, - "tags": { - "type": "object", - "metadata": { - "description": "Specifies the resource tags for the Azure Monitor managed service for Prometheus resource." - } - } - }, - "resources": [ - { - "type": "Microsoft.Dashboard/grafana", - "apiVersion": "2022-08-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", - "sku": { - "name": "[parameters('skuName')]" - }, - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "apiKey": "[parameters('apiKey')]", - "autoGeneratedDomainNameLabelScope": "[parameters('autoGeneratedDomainNameLabelScope')]", - "deterministicOutboundIP": "[parameters('deterministicOutboundIP')]", - "grafanaIntegrations": { - "azureMonitorWorkspaceIntegrations": [ - { - "azureMonitorWorkspaceResourceId": "[resourceId('Microsoft.Monitor/accounts', parameters('prometheusName'))]" - } - ] - }, - "publicNetworkAccess": "[parameters('publicNetworkAccess')]", - "zoneRedundancy": "[parameters('zoneRedundancy')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Monitor/accounts/{0}', parameters('prometheusName'))]", - "name": "[guid(parameters('name'), parameters('prometheusName'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "principalId": "[reference(resourceId('Microsoft.Dashboard/grafana', parameters('name')), '2022-08-01', 'full').identity.principalId]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Dashboard/grafana', parameters('name'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Monitor/accounts/{0}', parameters('prometheusName'))]", - "name": "[guid(parameters('name'), parameters('prometheusName'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b0d8363b-8ddd-447d-831f-62ca05bff136'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b0d8363b-8ddd-447d-831f-62ca05bff136')]", - "principalId": "[reference(resourceId('Microsoft.Dashboard/grafana', parameters('name')), '2022-08-01', 'full').identity.principalId]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Dashboard/grafana', parameters('name'))]" - ] - }, - { - "condition": "[not(empty(parameters('userId')))]", - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Dashboard/grafana/{0}', parameters('name'))]", - "name": "[guid(parameters('name'), parameters('userId'), subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '22926164-76b3-42b3-bc55-97df8dab3e41'))]", - "properties": { - "roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '22926164-76b3-42b3-bc55-97df8dab3e41')]", - "principalId": "[parameters('userId')]", - "principalType": "User" - }, - "dependsOn": [ - "[resourceId('Microsoft.Dashboard/grafana', parameters('name'))]" - ] - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Dashboard/grafana', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Dashboard/grafana', parameters('name')), '2022-08-01', 'full').location]" - }, - "principalId": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Dashboard/grafana', parameters('name')), '2022-08-01', 'full').identity.principalId]" - } - } - } - }, - "dependsOn": [ - "prometheus" - ] } }, "outputs": { @@ -36156,7 +36051,7 @@ "metadata": { "description": "The name of the cluster." }, - "value": "[reference('cluster').outputs.aksClusterName.value]" + "value": "[reference('cluster').outputs.name.value]" } } } diff --git a/version.json b/version.json index 3b42ebef..b4c82222 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"release": "v0.38.0"} +{"release": "v0.39.0"}