├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── samples ├── best-practices │ └── resource-name-expressions.bicep ├── create-storage-account │ ├── azuredeploy.bicep │ └── main.bicep ├── create-template-spec │ ├── azuredeploy.bicep │ └── main.bicep ├── deploy-what-if │ ├── what-if-after.bicep │ └── what-if-before.bicep ├── deployment-script │ ├── create-cert.ps1 │ ├── deploymentscript-jsonEscape.bicep │ ├── deploymentscript-keyvault-mi.bicep │ ├── deploymentscript-keyvault-subscription.bicep │ ├── deploymentscript-keyvault.bicep │ ├── externalScript.bicep │ ├── hello.ps1 │ ├── hello.sh │ ├── inlineScript.bicep │ ├── inlineScript.ps1 │ ├── passValue-cli.bicep │ ├── passValues.bicep │ ├── readme.txt │ └── sample.bicep ├── loops-quickstart │ ├── createStorage.bicep │ ├── loopArrayObject.bicep │ ├── loopArrayString.bicep │ ├── loopArrayStringAndNumber.bicep │ ├── loopNumbered.bicep │ ├── loopObject.bicep │ └── loopWithCondition.bicep ├── loops │ ├── loopproperty.bicep │ ├── loopserialstorage.bicep │ ├── loopstorage.bicep │ ├── loopstoragewitharray.bicep │ ├── loopvariables.bicep │ ├── multiplesecurityrules.bicep │ └── multiplesecurityrules.parameters.json ├── modules │ ├── parent-output.bicep │ ├── rg-and-storage.bicep │ └── scope-two-resource-groups.bicep ├── patterns-configuration-set │ └── main.bicep ├── patterns-logical-parameter │ ├── all-tenant-resources.bicep │ ├── resources.bicep │ ├── service-bus.bicep │ ├── tenant-resources.bicep │ └── virtual-network.bicep ├── patterns-name-generation │ ├── app-service.bicep │ └── storage.bicep ├── patterns-shared-variable-file │ ├── .vscode │ │ └── settings.json │ ├── example-1.bicep │ ├── example-2.bicep │ ├── shared-prefixes.json │ └── shared-rules.json ├── scenarios-monitoring │ ├── action-group.bicep │ ├── activity-log-alert.bicep │ ├── alert-processing-rules.bicep │ ├── autoscaling-rules.bicep │ ├── diagnostic-settings-activity-log.bicep │ ├── diagnostic-settings.bicep │ └── resource-health-alerts.bicep ├── scenarios-rbac │ ├── built-in-role.bicep │ ├── managed-identity.bicep │ ├── scope-default.bicep │ └── scope.bicep ├── scenarios-secrets │ ├── function-app.bicep │ └── key-vault-secret.bicep ├── scenarios-virtual-networks │ └── vnet.bicep └── scopes │ └── resource-group │ └── locktargetscope.bicep └── syntax-samples ├── child-resource-name-type ├── fullnamedeclaration.bicep ├── insidedeclaration.bicep └── outsidedeclaration.bicep ├── functions ├── loadJsonContent │ ├── loadsharedrules.bicep │ └── nsg-security-rules.json ├── loadTextContent │ ├── loaddeploymentscript.bicep │ ├── loadsharedrules.bicep │ └── nsg-security-rules.json └── loadYamlContent │ ├── loadsharedrules.bicep │ └── nsg-security-rules.yaml ├── modules ├── alias-definition-public.bicep ├── alias-definition.bicep ├── conditional-definition.bicep ├── dependsOn-definition.bicep ├── function-scope.bicep ├── iterative-definition.bicep ├── local-file-definition-json.bicep ├── local-file-definition.bicep ├── registry-definition-public.bicep ├── registry-definition.bicep └── scope-definition.bicep ├── outputs ├── module-output.bicep └── output.bicep ├── parameters ├── parameterobject.bicep └── parameterswithfunctions.bicep ├── synapse-keys └── keys.bicep └── variables ├── variables.bicep ├── variablesconfigurations.bicep └── variableswithfunction.bicep /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bicep samples for documentation 2 | 3 | This repo holds Bicep samples that are used with documentation. 4 | 5 | The folder **syntax-samples** contains samples that are meant to demonstrate a feature of the language. The samples in this folder are not real-world examples. In most cases, the samples do not deploy an actual resource. 6 | 7 | The folder **samples** contains samples that address a scenario in the documentation. These samples are real-world examples and deploy resources. 8 | 9 | ## Contributing 10 | 11 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 12 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 13 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 14 | 15 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 16 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 17 | provided by the bot. You will only need to do this once across all repos using our CLA. 18 | 19 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 20 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 21 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 22 | 23 | ## Trademarks 24 | 25 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 26 | trademarks or logos is subject to and must follow 27 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 28 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 29 | Any use of third-party trademarks or logos are subject to those third-party's policies. 30 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # TODO: The maintainer of this repo has not yet edited this file 2 | 3 | **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project? 4 | 5 | - **No CSS support:** Fill out this template with information about how to file issues and get help. 6 | - **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). 7 | - **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide. 8 | 9 | *Then remove this first heading from this SUPPORT.MD file before publishing your repo.* 10 | 11 | # Support 12 | 13 | ## How to file issues and get help 14 | 15 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 16 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 17 | feature request as a new Issue. 18 | 19 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE 20 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER 21 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**. 22 | 23 | ## Microsoft Support Policy 24 | 25 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 26 | -------------------------------------------------------------------------------- /samples/best-practices/resource-name-expressions.bicep: -------------------------------------------------------------------------------- 1 | param shortAppName string = 'toy' 2 | param shortEnvironmentName string = 'prod' 3 | param appServiceAppName string = '${shortAppName}-${shortEnvironmentName}-${uniqueString(resourceGroup().id)}' 4 | -------------------------------------------------------------------------------- /samples/create-storage-account/azuredeploy.bicep: -------------------------------------------------------------------------------- 1 | @minLength(3) 2 | @maxLength(11) 3 | param storagePrefix string 4 | 5 | @allowed([ 6 | 'Standard_LRS' 7 | 'Standard_GRS' 8 | 'Standard_RAGRS' 9 | 'Standard_ZRS' 10 | 'Premium_LRS' 11 | 'Premium_ZRS' 12 | 'Standard_GZRS' 13 | 'Standard_RAGZRS' 14 | ]) 15 | param storageSKU string = 'Standard_LRS' 16 | 17 | param location string = resourceGroup().location 18 | 19 | var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}' 20 | 21 | resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = { 22 | name: uniqueStorageName 23 | location: location 24 | sku: { 25 | name: storageSKU 26 | } 27 | kind: 'StorageV2' 28 | properties: { 29 | supportsHttpsTrafficOnly: true 30 | } 31 | } 32 | 33 | output storageEndpoint object = stg.properties.primaryEndpoints 34 | -------------------------------------------------------------------------------- /samples/create-storage-account/main.bicep: -------------------------------------------------------------------------------- 1 | @minLength(3) 2 | @maxLength(11) 3 | param storagePrefix string 4 | 5 | @allowed([ 6 | 'Standard_LRS' 7 | 'Standard_GRS' 8 | 'Standard_RAGRS' 9 | 'Standard_ZRS' 10 | 'Premium_LRS' 11 | 'Premium_ZRS' 12 | 'Standard_GZRS' 13 | 'Standard_RAGZRS' 14 | ]) 15 | param storageSKU string = 'Standard_LRS' 16 | 17 | param location string 18 | 19 | var uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}' 20 | 21 | resource stg 'Microsoft.Storage/storageAccounts@2021-04-01' = { 22 | name: uniqueStorageName 23 | location: location 24 | sku: { 25 | name: storageSKU 26 | } 27 | kind: 'StorageV2' 28 | properties: { 29 | supportsHttpsTrafficOnly: true 30 | } 31 | } 32 | 33 | output storageEndpoint object = stg.properties.primaryEndpoints 34 | -------------------------------------------------------------------------------- /samples/create-template-spec/azuredeploy.bicep: -------------------------------------------------------------------------------- 1 | @description('Name of the templateSpec') 2 | param templateSpecName string = 'ManagedDisk' 3 | 4 | @description('Version for this instance of the templateSpec') 5 | param templateSpecVersion string = '0.1' 6 | 7 | @description('Location for all resources.') 8 | param location string = resourceGroup().location 9 | 10 | resource templateSpecName_resource 'Microsoft.Resources/templateSpecs@2019-06-01-preview' = { 11 | name: templateSpecName 12 | location: location 13 | properties: { 14 | description: 'A basic templateSpec - creates a managed disk.' 15 | displayName: 'Managed Disk (Standard_LRS)' 16 | } 17 | } 18 | 19 | resource templateSpecName_templateSpecVersion 'Microsoft.Resources/templateSpecs/versions@2019-06-01-preview' = { 20 | name: '${templateSpecName_resource.name}/${templateSpecVersion}' 21 | location: location 22 | tags: { 23 | Dept: 'Finance' 24 | Environment: 'Production' 25 | } 26 | properties: { 27 | template: { 28 | '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' 29 | contentVersion: '1.0.0.0' 30 | parameters: { 31 | diskName: { 32 | type: 'string' 33 | } 34 | location: { 35 | type: 'string' 36 | } 37 | } 38 | resources: [ 39 | { 40 | type: 'Microsoft.Compute/disks' 41 | name: '[parameters(\'diskName\')]' 42 | apiVersion: '2020-05-01' 43 | location: '[parameters(\'location\')]' 44 | sku: { 45 | name: 'Standard_LRS' 46 | } 47 | properties: { 48 | creationData: { 49 | createOption: 'Empty' 50 | } 51 | diskSizeGB: 64 52 | } 53 | } 54 | ] 55 | } 56 | } 57 | } 58 | 59 | output templateSpecName string = templateSpecName 60 | output templateSpecVersion string = templateSpecVersion 61 | output templateSpecResourceGroupName string = resourceGroup().name 62 | output templateSpecSubscriptionId string = subscription().subscriptionId -------------------------------------------------------------------------------- /samples/create-template-spec/main.bicep: -------------------------------------------------------------------------------- 1 | @description('Name of the templateSpec') 2 | param templateSpecName string = 'ManagedDisk' 3 | 4 | @description('Version for this instance of the templateSpec') 5 | param templateSpecVersion string = '0.1' 6 | 7 | @description('Location for all resources.') 8 | param location string = resourceGroup().location 9 | 10 | resource templateSpecName_resource 'Microsoft.Resources/templateSpecs@2019-06-01-preview' = { 11 | name: templateSpecName 12 | location: location 13 | properties: { 14 | description: 'A basic templateSpec - creates a managed disk.' 15 | displayName: 'Managed Disk (Standard_LRS)' 16 | } 17 | } 18 | 19 | resource templateSpecName_templateSpecVersion 'Microsoft.Resources/templateSpecs/versions@2019-06-01-preview' = { 20 | name: '${templateSpecName_resource.name}/${templateSpecVersion}' 21 | location: location 22 | tags: { 23 | Dept: 'Finance' 24 | Environment: 'Production' 25 | } 26 | properties: { 27 | template: { 28 | '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' 29 | contentVersion: '1.0.0.0' 30 | parameters: { 31 | diskName: { 32 | type: 'string' 33 | } 34 | location: { 35 | type: 'string' 36 | } 37 | } 38 | resources: [ 39 | { 40 | type: 'Microsoft.Compute/disks' 41 | name: '[parameters(\'diskName\')]' 42 | apiVersion: '2020-05-01' 43 | location: '[parameters(\'location\')]' 44 | sku: { 45 | name: 'Standard_LRS' 46 | } 47 | properties: { 48 | creationData: { 49 | createOption: 'Empty' 50 | } 51 | diskSizeGB: 64 52 | } 53 | } 54 | ] 55 | } 56 | } 57 | } 58 | 59 | output templateSpecName string = templateSpecName 60 | output templateSpecVersion string = templateSpecVersion 61 | output templateSpecResourceGroupName string = resourceGroup().name 62 | output templateSpecSubscriptionId string = subscription().subscriptionId -------------------------------------------------------------------------------- /samples/deploy-what-if/what-if-after.bicep: -------------------------------------------------------------------------------- 1 | resource vnet 'Microsoft.Network/virtualNetworks@2021-02-01' = { 2 | name: 'vnet-001' 3 | location: resourceGroup().location 4 | tags: { 5 | CostCenter: '12345' 6 | } 7 | properties: { 8 | addressSpace: { 9 | addressPrefixes: [ 10 | '10.0.0.0/15' 11 | ] 12 | } 13 | enableVmProtection: false 14 | enableDdosProtection: false 15 | subnets: [ 16 | { 17 | name: 'subnet002' 18 | properties: { 19 | addressPrefix: '10.0.1.0/24' 20 | } 21 | } 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/deploy-what-if/what-if-before.bicep: -------------------------------------------------------------------------------- 1 | resource vnet 'Microsoft.Network/virtualNetworks@2021-02-01' = { 2 | name: 'vnet-001' 3 | location: resourceGroup().location 4 | tags: { 5 | CostCenter: '12345' 6 | Owner: 'Team A' 7 | } 8 | properties: { 9 | addressSpace: { 10 | addressPrefixes: [ 11 | '10.0.0.0/16' 12 | ] 13 | } 14 | enableVmProtection: false 15 | enableDdosProtection: false 16 | subnets: [ 17 | { 18 | name: 'subnet001' 19 | properties: { 20 | addressPrefix: '10.0.0.0/24' 21 | } 22 | } 23 | { 24 | name: 'subnet002' 25 | properties: { 26 | addressPrefix: '10.0.1.0/24' 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/deployment-script/create-cert.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [string] [Parameter(Mandatory=$false)] $vaultName, 3 | [string] [Parameter(Mandatory=$false)] $certificateName, 4 | [string] [Parameter(Mandatory=$false)] $subjectName 5 | ) 6 | 7 | $ErrorActionPreference = 'Stop' 8 | 9 | $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose 10 | 11 | # private key is added as a secret that can be retrieved in the ARM template 12 | Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose 13 | 14 | $cert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 15 | 16 | # it take a few seconds for KeyVault to finish 17 | while($cert.Thumbprint -eq $null){ 18 | Write-Output 'Sleeping...' 19 | Start-Sleep 5 20 | $cert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 21 | } 22 | 23 | $DeploymentScriptOutputs = New-Object -TypeName hashtable 24 | $DeploymentScriptOutputs['certThumbprint'] = $cert.Thumbprint 25 | $cert | Out-String 26 | -------------------------------------------------------------------------------- /samples/deployment-script/deploymentscript-jsonEscape.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param tables object = { 3 | abc: [ 4 | { 5 | partitionKey: 'emotion' 6 | rowKey: 'happy' 7 | blah: 'asdf' 8 | test: 5 9 | } 10 | { 11 | partitionKey: 'emotion' 12 | rowKey: 'angry' 13 | blah: 'bdfae' 14 | test: 221 15 | another: 'testing' 16 | } 17 | ] 18 | def: [ 19 | { 20 | partitionKey: 'emotion' 21 | rowKey: 'sad' 22 | blah: 'jiuo' 23 | test: 2 24 | } 25 | ] 26 | ghi: [] 27 | } 28 | 29 | var apostrophe = '\'' 30 | 31 | resource runPowerShellInline 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 32 | name: 'runPowerShellInline' 33 | location: location 34 | kind: 'AzurePowerShell' 35 | properties: { 36 | forceUpdateTag: '1' 37 | azPowerShellVersion: '8.3' 38 | arguments: '-tables ${apostrophe}${replace(string(tables), '"', '\\"')}${apostrophe}' 39 | scriptContent: ''' 40 | param([string] $tables) 41 | $output = ConvertFrom-Json $tables -AsHashtable | ConvertTo-Json -Depth 5 -Compress 42 | $DeploymentScriptOutputs = @{} 43 | $DeploymentScriptOutputs['text'] = $output 44 | ''' 45 | supportingScriptUris: [] 46 | timeout: 'PT10M' 47 | cleanupPreference: 'OnSuccess' 48 | retentionInterval: 'P1D' 49 | } 50 | } 51 | 52 | output result string = runPowerShellInline.properties.outputs.text 53 | -------------------------------------------------------------------------------- /samples/deployment-script/deploymentscript-keyvault-mi.bicep: -------------------------------------------------------------------------------- 1 | @description('Specifies the name of the key vault.') 2 | param keyVaultName string 3 | 4 | @description('Specifies the Azure location where the key vault should be created.') 5 | param location string = resourceGroup().location 6 | 7 | @description('Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault.') 8 | @allowed([ 9 | true 10 | false 11 | ]) 12 | param enabledForDeployment bool = false 13 | 14 | @description('Specifies whether Azure Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys.') 15 | @allowed([ 16 | true 17 | false 18 | ]) 19 | param enabledForDiskEncryption bool = false 20 | 21 | @description('Specifies whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') 22 | @allowed([ 23 | true 24 | false 25 | ]) 26 | param enabledForTemplateDeployment bool = false 27 | 28 | @description('Specifies the Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Get it by using Get-AzSubscription cmdlet.') 29 | param tenantId string = subscription().tenantId 30 | 31 | @description('Specifies the object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault. The object ID must be unique for the list of access policies. Get it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets.') 32 | param objectId string 33 | 34 | @description('Specifies the permissions to keys in the vault. Valid values are: all, encrypt, decrypt, wrapKey, unwrapKey, sign, verify, get, list, create, update, import, delete, backup, restore, recover, and purge.') 35 | param keysPermissions array = [ 36 | 'list' 37 | ] 38 | 39 | @description('Specifies the permissions to secrets in the vault. Valid values are: all, get, list, set, delete, backup, restore, recover, and purge.') 40 | param secretsPermissions array = [ 41 | 'list' 42 | ] 43 | 44 | @description('Specifies whether the key vault is a standard vault or a premium vault.') 45 | @allowed([ 46 | 'standard' 47 | 'premium' 48 | ]) 49 | param skuName string = 'standard' 50 | 51 | @description('Specifies the name of the user-assigned managed identity.') 52 | param identityName string 53 | 54 | @description('Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities.') 55 | param certificatesPermissions array = [ 56 | 'get' 57 | 'list' 58 | 'update' 59 | 'create' 60 | ] 61 | param certificateName string = 'DeploymentScripts2019' 62 | param subjectName string = 'CN=contoso.com' 63 | param utcValue string = utcNow() 64 | 65 | var bootstrapRoleAssignmentId = guid('${resourceGroup().id}contributor') 66 | var contributorRoleDefinitionId = '/subscriptions/${subscription().subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c' 67 | 68 | resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { 69 | name: identityName 70 | location: location 71 | } 72 | 73 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2021-04-01-preview' = { 74 | name: bootstrapRoleAssignmentId 75 | properties: { 76 | roleDefinitionId: contributorRoleDefinitionId 77 | principalId: reference(managedIdentity.id, '2018-11-30').principalId 78 | scope: resourceGroup().id 79 | principalType: 'ServicePrincipal' 80 | } 81 | } 82 | 83 | resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' = { 84 | name: keyVaultName 85 | location: location 86 | properties: { 87 | enabledForDeployment: enabledForDeployment 88 | enabledForDiskEncryption: enabledForDiskEncryption 89 | enabledForTemplateDeployment: enabledForTemplateDeployment 90 | tenantId: tenantId 91 | accessPolicies: [ 92 | { 93 | objectId: objectId 94 | tenantId: tenantId 95 | permissions: { 96 | keys: keysPermissions 97 | secrets: secretsPermissions 98 | certificates: certificatesPermissions 99 | } 100 | } 101 | { 102 | objectId: reference(managedIdentity.id, '2018-11-30').principalId 103 | tenantId: tenantId 104 | permissions: { 105 | keys: keysPermissions 106 | secrets: secretsPermissions 107 | certificates: certificatesPermissions 108 | } 109 | } 110 | ] 111 | sku: { 112 | name: skuName 113 | family: 'A' 114 | } 115 | networkAcls: { 116 | defaultAction: 'Allow' 117 | bypass: 'AzureServices' 118 | } 119 | } 120 | } 121 | 122 | resource createAddCertificate 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 123 | name: 'createAddCertificate' 124 | location: location 125 | identity: { 126 | type: 'UserAssigned' 127 | userAssignedIdentities: { 128 | '${managedIdentity.id}': {} 129 | } 130 | } 131 | kind: 'AzurePowerShell' 132 | properties: { 133 | forceUpdateTag: utcValue 134 | azPowerShellVersion: '8.3' 135 | timeout: 'PT30M' 136 | arguments: ' -vaultName ${keyVaultName} -certificateName ${certificateName} -subjectName ${subjectName}' 137 | scriptContent: ''' 138 | param( 139 | [string] [Parameter(Mandatory=$true)] $vaultName, 140 | [string] [Parameter(Mandatory=$true)] $certificateName, 141 | [string] [Parameter(Mandatory=$true)] $subjectName 142 | ) 143 | 144 | $ErrorActionPreference = 'Stop' 145 | $DeploymentScriptOutputs = @{} 146 | 147 | $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 148 | 149 | if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) { 150 | 151 | Write-Host 'Certificate $certificateName in vault $vaultName is already present.' 152 | 153 | $DeploymentScriptOutputs['certThumbprint'] = $existingCert.Thumbprint 154 | $existingCert | Out-String 155 | } 156 | else { 157 | $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose 158 | 159 | # private key is added as a secret that can be retrieved in the ARM template 160 | Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose 161 | 162 | $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 163 | 164 | # it takes a few seconds for KeyVault to finish 165 | $tries = 0 166 | do { 167 | Write-Host 'Waiting for certificate creation completion...' 168 | Start-Sleep -Seconds 10 169 | $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName 170 | $tries++ 171 | 172 | if ($operation.Status -eq 'failed') 173 | { 174 | throw 'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)' 175 | } 176 | 177 | if ($tries -gt 120) 178 | { 179 | throw 'Timed out waiting for creation of certificate $certificateName in vault $vaultName' 180 | } 181 | } while ($operation.Status -ne 'completed') 182 | 183 | $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint 184 | $newCert | Out-String 185 | } 186 | ''' 187 | cleanupPreference: 'OnSuccess' 188 | retentionInterval: 'P1D' 189 | } 190 | dependsOn: [ 191 | keyVault 192 | roleAssignment 193 | ] 194 | } 195 | -------------------------------------------------------------------------------- /samples/deployment-script/deploymentscript-keyvault-subscription.bicep: -------------------------------------------------------------------------------- 1 | targetScope = 'subscription' 2 | 3 | @description('Specifies a project name that is used for generating resource group name and resource names.') 4 | param projectName string 5 | 6 | @description('Specifies the Azure location where the key vault should be created.') 7 | param location string = resourceGroup().location 8 | 9 | @description('Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault.') 10 | @allowed([ 11 | true 12 | false 13 | ]) 14 | param enabledForDeployment bool = false 15 | 16 | @description('Specifies whether Azure Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys.') 17 | @allowed([ 18 | true 19 | false 20 | ]) 21 | param enabledForDiskEncryption bool = false 22 | 23 | @description('Specifies whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') 24 | @allowed([ 25 | true 26 | false 27 | ]) 28 | param enabledForTemplateDeployment bool = false 29 | 30 | @description('Specifies the Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Get it by using Get-AzSubscription cmdlet.') 31 | param tenantId string = subscription().tenantId 32 | 33 | @description('Specifies the object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault. The object ID must be unique for the list of access policies. Get it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets.') 34 | param objectId string 35 | 36 | @description('Specifies the permissions to keys in the vault. Valid values are: all, encrypt, decrypt, wrapKey, unwrapKey, sign, verify, get, list, create, update, import, delete, backup, restore, recover, and purge.') 37 | param keysPermissions array = [ 38 | 'list' 39 | ] 40 | 41 | @description('Specifies the permissions to secrets in the vault. Valid values are: all, get, list, set, delete, backup, restore, recover, and purge.') 42 | param secretsPermissions array = [ 43 | 'list' 44 | ] 45 | 46 | @description('Specifies whether the key vault is a standard vault or a premium vault.') 47 | @allowed([ 48 | 'standard' 49 | 'premium' 50 | ]) 51 | param skuName string = 'standard' 52 | 53 | @description('Specifies the ID of the user-assigned managed identity.') 54 | param identityId string 55 | 56 | @description('Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities.') 57 | param certificatesPermissions array = [ 58 | 'get' 59 | 'list' 60 | 'update' 61 | 'create' 62 | ] 63 | param certificateName string = 'DeploymentScripts2020' 64 | param subjectName string = 'CN=contoso.com' 65 | param utcValue string = utcNow() 66 | 67 | var resourceGroupName = '${projectName}rg' 68 | var keyVaultName = '${projectName}kv' 69 | 70 | resource kvResourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { 71 | name: resourceGroupName 72 | location: location 73 | properties: {} 74 | } 75 | 76 | module KeyVaultDeployment './deploymentscript-keyvault.bicep' = { 77 | name: 'KeyVaultDeployment' 78 | scope: resourceGroup(resourceGroupName) 79 | params: { 80 | keyVaultName: keyVaultName 81 | location: location 82 | enabledForDeployment: enabledForDeployment 83 | enabledForDiskEncryption: enabledForDiskEncryption 84 | enabledForTemplateDeployment: enabledForTemplateDeployment 85 | tenantId: tenantId 86 | objectId: objectId 87 | keysPermissions: keysPermissions 88 | secretsPermissions: secretsPermissions 89 | certificatesPermissions: certificatesPermissions 90 | skuName: skuName 91 | identityId: identityId 92 | utcValue: utcValue 93 | certificateName: certificateName 94 | subjectName: subjectName 95 | } 96 | dependsOn: [ 97 | kvResourceGroup 98 | ] 99 | } 100 | -------------------------------------------------------------------------------- /samples/deployment-script/deploymentscript-keyvault.bicep: -------------------------------------------------------------------------------- 1 | @description('Specifies the name of the key vault.') 2 | param keyVaultName string 3 | 4 | @description('Specifies the Azure location where the key vault should be created.') 5 | param location string = resourceGroup().location 6 | 7 | @description('Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault.') 8 | @allowed([ 9 | true 10 | false 11 | ]) 12 | param enabledForDeployment bool = false 13 | 14 | @description('Specifies whether Azure Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys.') 15 | @allowed([ 16 | true 17 | false 18 | ]) 19 | param enabledForDiskEncryption bool = false 20 | 21 | @description('Specifies whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') 22 | @allowed([ 23 | true 24 | false 25 | ]) 26 | param enabledForTemplateDeployment bool = false 27 | 28 | @description('Specifies the Azure Active Directory tenant ID that should be used for authenticating requests to the key vault. Get it by using Get-AzSubscription cmdlet.') 29 | param tenantId string = subscription().tenantId 30 | 31 | @description('Specifies the object ID of a user, service principal or security group in the Azure Active Directory tenant for the vault. The object ID must be unique for the list of access policies. Get it by using Get-AzADUser or Get-AzADServicePrincipal cmdlets.') 32 | param objectId string 33 | 34 | @description('Specifies the permissions to keys in the vault. Valid values are: all, encrypt, decrypt, wrapKey, unwrapKey, sign, verify, get, list, create, update, import, delete, backup, restore, recover, and purge.') 35 | param keysPermissions array = [ 36 | 'list' 37 | ] 38 | 39 | @description('Specifies the permissions to secrets in the vault. Valid values are: all, get, list, set, delete, backup, restore, recover, and purge.') 40 | param secretsPermissions array = [ 41 | 'list' 42 | ] 43 | 44 | @description('Specifies whether the key vault is a standard vault or a premium vault.') 45 | @allowed([ 46 | 'standard' 47 | 'premium' 48 | ]) 49 | param skuName string = 'standard' 50 | 51 | @description('Specifies the ID of the user-assigned managed identity.') 52 | param identityId string 53 | 54 | @description('Specifies the permissions to certificates in the vault. Valid values are: all, get, list, update, create, import, delete, recover, backup, restore, manage contacts, manage certificate authorities, get certificate authorities, list certificate authorities, set certificate authorities, delete certificate authorities.') 55 | param certificatesPermissions array = [ 56 | 'get' 57 | 'list' 58 | 'update' 59 | 'create' 60 | ] 61 | param certificateName string = 'DeploymentScripts2019' 62 | param subjectName string = 'CN=contoso.com' 63 | param utcValue string = utcNow() 64 | 65 | resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' = { 66 | name: keyVaultName 67 | location: location 68 | properties: { 69 | enabledForDeployment: enabledForDeployment 70 | enabledForDiskEncryption: enabledForDiskEncryption 71 | enabledForTemplateDeployment: enabledForTemplateDeployment 72 | tenantId: tenantId 73 | accessPolicies: [ 74 | { 75 | objectId: objectId 76 | tenantId: tenantId 77 | permissions: { 78 | keys: keysPermissions 79 | secrets: secretsPermissions 80 | certificates: certificatesPermissions 81 | } 82 | } 83 | { 84 | objectId: reference(identityId, '2018-11-30').principalId 85 | tenantId: tenantId 86 | permissions: { 87 | keys: keysPermissions 88 | secrets: secretsPermissions 89 | certificates: certificatesPermissions 90 | } 91 | } 92 | ] 93 | sku: { 94 | name: skuName 95 | family: 'A' 96 | } 97 | networkAcls: { 98 | defaultAction: 'Allow' 99 | bypass: 'AzureServices' 100 | } 101 | } 102 | } 103 | 104 | resource createAddCertificate 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 105 | name: 'createAddCertificate' 106 | location: location 107 | identity: { 108 | type: 'UserAssigned' 109 | userAssignedIdentities: { 110 | '${identityId}': {} 111 | } 112 | } 113 | kind: 'AzurePowerShell' 114 | properties: { 115 | forceUpdateTag: utcValue 116 | azPowerShellVersion: '8.3' 117 | timeout: 'PT30M' 118 | arguments: ' -vaultName ${keyVaultName} -certificateName ${certificateName} -subjectName ${subjectName}' 119 | scriptContent: ''' 120 | param( 121 | [string] [Parameter(Mandatory=$true)] $vaultName, 122 | [string] [Parameter(Mandatory=$true)] $certificateName, 123 | [string] [Parameter(Mandatory=$true)] $subjectName 124 | ) 125 | 126 | $ErrorActionPreference = 'Stop' 127 | $DeploymentScriptOutputs = @{} 128 | 129 | $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 130 | 131 | if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) { 132 | 133 | Write-Host 'Certificate $certificateName in vault $vaultName is already present.' 134 | $DeploymentScriptOutputs['certThumbprint'] = $existingCert.Thumbprint 135 | $existingCert | Out-String 136 | } 137 | else { 138 | $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose 139 | 140 | # private key is added as a secret that can be retrieved in the ARM template 141 | Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose 142 | 143 | $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName 144 | 145 | # it takes a few seconds for KeyVault to finish 146 | $tries = 0 147 | do { 148 | Write-Host 'Waiting for certificate creation completion...' 149 | Start-Sleep -Seconds 10 150 | $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName 151 | $tries++ 152 | 153 | if ($operation.Status -eq 'failed') 154 | { 155 | throw 'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)' 156 | } 157 | 158 | if ($tries -gt 120) 159 | { 160 | throw 'Timed out waiting for creation of certificate $certificateName in vault $vaultName' 161 | } 162 | } while ($operation.Status -ne 'completed') 163 | 164 | $DeploymentScriptOutputs['certThumbprint'] = $newCert.Thumbprint 165 | $newCert | Out-String 166 | } 167 | ''' 168 | cleanupPreference: 'OnSuccess' 169 | retentionInterval: 'P1D' 170 | } 171 | dependsOn: [ 172 | keyVault 173 | ] 174 | } 175 | -------------------------------------------------------------------------------- /samples/deployment-script/externalScript.bicep: -------------------------------------------------------------------------------- 1 | param name string = '\\"John Dole\\"' 2 | param utcValue string = utcNow() 3 | param location string = resourceGroup().location 4 | 5 | resource runPowerShellInlineWithOutput 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 6 | name: 'runPowerShellInlineWithOutput' 7 | location: location 8 | kind: 'AzurePowerShell' 9 | properties: { 10 | forceUpdateTag: utcValue 11 | azPowerShellVersion: '8.3' 12 | primaryScriptURI: 'https://raw.githubusercontent.com/Azure/azure-docs-bicep-samples/main/samples/deployment-script/inlineScript.ps1' 13 | arguments: '-name ${name}' 14 | timeout: 'PT1H' 15 | cleanupPreference: 'OnSuccess' 16 | retentionInterval: 'P1D' 17 | } 18 | } 19 | 20 | output result string = runPowerShellInlineWithOutput.properties.outputs.text 21 | -------------------------------------------------------------------------------- /samples/deployment-script/hello.ps1: -------------------------------------------------------------------------------- 1 | param([string] $name) 2 | $output = "Hello {0}" -f $name 3 | Write-Output "Output is: '$output'." -------------------------------------------------------------------------------- /samples/deployment-script/hello.sh: -------------------------------------------------------------------------------- 1 | output="Hello $1" 2 | echo $output -------------------------------------------------------------------------------- /samples/deployment-script/inlineScript.bicep: -------------------------------------------------------------------------------- 1 | param name string = '\\"John Dole\\"' 2 | param utcValue string = utcNow() 3 | param location string = resourceGroup().location 4 | 5 | resource runPowerShellInlineWithOutput 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 6 | name: 'runPowerShellInlineWithOutput' 7 | location: location 8 | kind: 'AzurePowerShell' 9 | properties: { 10 | forceUpdateTag: utcValue 11 | azPowerShellVersion: '8.3' 12 | scriptContent: ''' 13 | param([string] $name) 14 | $output = "Hello {0}" -f $name 15 | Write-Output $output 16 | $DeploymentScriptOutputs = @{} 17 | $DeploymentScriptOutputs["text"] = $output 18 | ''' 19 | arguments: '-name ${name}' 20 | timeout: 'PT1H' 21 | cleanupPreference: 'OnSuccess' 22 | retentionInterval: 'P1D' 23 | } 24 | } 25 | 26 | output result string = runPowerShellInlineWithOutput.properties.outputs.text 27 | -------------------------------------------------------------------------------- /samples/deployment-script/inlineScript.ps1: -------------------------------------------------------------------------------- 1 | param([string] $name) 2 | $output = 'Hello {0}' -f $name 3 | Write-Output $output 4 | $DeploymentScriptOutputs = @{} 5 | $DeploymentScriptOutputs['text'] = $output 6 | -------------------------------------------------------------------------------- /samples/deployment-script/passValue-cli.bicep: -------------------------------------------------------------------------------- 1 | param identity string 2 | param utcValue string = utcNow() 3 | param location string = resourceGroup().location 4 | 5 | var storageAccountName = 'ds${uniqueString(resourceGroup().id)}' 6 | 7 | resource dsStorage 'Microsoft.Storage/storageAccounts@2023-01-01' = { 8 | name: storageAccountName 9 | location: location 10 | sku: { 11 | name: 'Standard_LRS' 12 | } 13 | kind: 'StorageV2' 14 | } 15 | 16 | resource runBashWithOutputs 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 17 | name: 'runBashWithOutputs' 18 | location: location 19 | kind: 'AzureCLI' 20 | identity: { 21 | type: 'UserAssigned' 22 | userAssignedIdentities: { 23 | '${identity}': {} 24 | } 25 | } 26 | properties: { 27 | forceUpdateTag: utcValue 28 | storageAccountSettings: { 29 | storageAccountName: dsStorage.name 30 | storageAccountKey: dsStorage.listKeys().keys[0].value 31 | } 32 | azCliVersion: '2.40.0' 33 | timeout: 'PT30M' 34 | arguments: '\'foo\' \'bar\'' 35 | environmentVariables: [ 36 | { 37 | name: 'UserName' 38 | value: 'jdole' 39 | } 40 | { 41 | name: 'Password' 42 | secureValue: 'jDolePassword' 43 | } 44 | ] 45 | scriptContent: 'result=$(az keyvault list); echo "arg1 is: $1"; echo "arg2 is: $2"; echo "Username is :$Username"; echo "Password is: $Password"; echo $result | jq -c \'{Result: map({id: .id})}\' > $AZ_SCRIPTS_OUTPUT_PATH' 46 | cleanupPreference: 'OnSuccess' 47 | retentionInterval: 'P1D' 48 | } 49 | } 50 | 51 | output result object = runBashWithOutputs.properties.outputs 52 | -------------------------------------------------------------------------------- /samples/deployment-script/passValues.bicep: -------------------------------------------------------------------------------- 1 | param name string = 'John Dole' 2 | param utcValue string = utcNow() 3 | param location string = resourceGroup().location 4 | 5 | resource scriptInTemplate1 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 6 | name: 'scriptInTemplate1' 7 | location: location 8 | kind: 'AzurePowerShell' 9 | properties: { 10 | forceUpdateTag: utcValue 11 | azPowerShellVersion: '8.3' 12 | timeout: 'PT1H' 13 | arguments: '-name \\"${name}\\"' 14 | scriptContent: ''' 15 | param([string] $name) 16 | $output = 'Hello {0}' -f $name 17 | Write-Output $output 18 | $DeploymentScriptOutputs = @{} 19 | $DeploymentScriptOutputs['text'] = $output 20 | ''' 21 | cleanupPreference: 'Always' 22 | retentionInterval: 'P1D' 23 | } 24 | } 25 | 26 | resource scriptInTemplate2 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 27 | name: 'scriptInTemplate2' 28 | location: location 29 | kind: 'AzurePowerShell' 30 | properties: { 31 | forceUpdateTag: utcValue 32 | azPowerShellVersion: '6.4' 33 | timeout: 'PT1H' 34 | arguments: '-textToEcho \\"${scriptInTemplate1.properties.outputs.text}\\"' 35 | scriptContent: ''' 36 | param([string] $textToEcho) 37 | Write-Output $textToEcho 38 | $DeploymentScriptOutputs = @{} 39 | $DeploymentScriptOutputs['text'] = $textToEcho 40 | ''' 41 | cleanupPreference: 'Always' 42 | retentionInterval: 'P1D' 43 | } 44 | } 45 | 46 | output result string = scriptInTemplate2.properties.outputs.text 47 | -------------------------------------------------------------------------------- /samples/deployment-script/readme.txt: -------------------------------------------------------------------------------- 1 | The Bicep files used in deployment-script-bicep.md -------------------------------------------------------------------------------- /samples/deployment-script/sample.bicep: -------------------------------------------------------------------------------- 1 | param identity string 2 | param utcValue string = utcNow() 3 | param storageAccountName string = 'mystore' 4 | 5 | resource runPowerShellInline 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 6 | name: 'runPowerShellInline' 7 | location: resourceGroup().location 8 | kind: 'AzurePowerShell' 9 | identity: { 10 | type: 'UserAssigned' 11 | userAssignedIdentities: { 12 | '/subscriptions/01234567-89AB-CDEF-0123-456789ABCDEF/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID': {} 13 | } 14 | } 15 | properties: { 16 | forceUpdateTag: '1' 17 | containerSettings: { 18 | containerGroupName: 'mycustomaci' 19 | } 20 | storageAccountSettings: { 21 | storageAccountName: 'myStorageAccount' 22 | storageAccountKey: 'myKey' 23 | } 24 | azPowerShellVersion: '8.3' // or "azCliVersion": "2.0.80", 25 | arguments: '-name \\"John Dole\\"' 26 | environmentVariables: [ 27 | { 28 | name: 'UserName' 29 | value: 'jdole' 30 | } 31 | { 32 | name: 'Password' 33 | secureValue: 'jDolePassword' 34 | } 35 | ] 36 | scriptContent: ''' 37 | param([string] $name) 38 | $output = \'Hello {0}. The username is {1}, the password is {2}.\' -f $name,\${Env:UserName},\${Env:Password} 39 | Write-Output $output 40 | $DeploymentScriptOutputs = @{} 41 | $DeploymentScriptOutputs[\'text\'] = $output 42 | ''' // or "primaryScriptUri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/deployment-script/deploymentscript-helloworld.ps1", 43 | supportingScriptUris: [] 44 | timeout: 'PT30M' 45 | cleanupPreference: 'OnSuccess' 46 | retentionInterval: 'P1D' 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/loops-quickstart/createStorage.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | 3 | resource createStorage 'Microsoft.Storage/storageAccounts@2022-09-01' = { 4 | name: 'storage${uniqueString(resourceGroup().id)}' 5 | location: rgLocation 6 | sku: { 7 | name: 'Standard_LRS' 8 | } 9 | kind: 'StorageV2' 10 | } 11 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopArrayObject.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | param storages array = [ 3 | { 4 | name: 'contoso' 5 | skuName: 'Standard_LRS' 6 | } 7 | { 8 | name: 'fabrikam' 9 | skuName: 'Premium_LRS' 10 | } 11 | ] 12 | 13 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for storage in storages: { 14 | name: '${storage.name}obj${uniqueString(resourceGroup().id)}' 15 | location: rgLocation 16 | sku: { 17 | name: storage.skuName 18 | } 19 | kind: 'StorageV2' 20 | }] 21 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopArrayString.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | param storageNames array = [ 3 | 'contoso' 4 | 'fabrikam' 5 | ] 6 | 7 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for name in storageNames: { 8 | name: '${name}str${uniqueString(resourceGroup().id)}' 9 | location: rgLocation 10 | sku: { 11 | name: 'Standard_LRS' 12 | } 13 | kind: 'StorageV2' 14 | }] 15 | 16 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopArrayStringAndNumber.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | param storageNames array = [ 3 | 'contoso' 4 | 'fabrikam' 5 | ] 6 | 7 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for (name, i) in storageNames: { 8 | name: '${i}${name}${uniqueString(resourceGroup().id)}' 9 | location: rgLocation 10 | sku: { 11 | name: 'Standard_LRS' 12 | } 13 | kind: 'StorageV2' 14 | }] 15 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopNumbered.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | param storageCount int = 2 3 | 4 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for i in range(0, storageCount): { 5 | name: '${i}storage${uniqueString(resourceGroup().id)}' 6 | location: rgLocation 7 | sku: { 8 | name: 'Standard_LRS' 9 | } 10 | kind: 'StorageV2' 11 | }] 12 | 13 | output names array = [for i in range(0,storageCount) : { 14 | name: createStorages[i].name 15 | } ] 16 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopObject.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | 3 | param storageConfig object = { 4 | storage1: { 5 | name: 'contoso' 6 | skuName: 'Standard_LRS' 7 | } 8 | storage2: { 9 | name: 'fabrikam' 10 | skuName: 'Premium_LRS' 11 | } 12 | } 13 | 14 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for config in items(storageConfig): { 15 | name: '${config.value.name}${uniqueString(resourceGroup().id)}' 16 | location: rgLocation 17 | sku: { 18 | name: config.value.skuName 19 | } 20 | kind: 'StorageV2' 21 | }] 22 | -------------------------------------------------------------------------------- /samples/loops-quickstart/loopWithCondition.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | param storageCount int = 2 3 | param createNewStorage bool = true 4 | 5 | resource createStorages 'Microsoft.Storage/storageAccounts@2022-09-01' = [for i in range(0, storageCount): if(createNewStorage) { 6 | name: '${i}storage${uniqueString(resourceGroup().id)}' 7 | location: rgLocation 8 | sku: { 9 | name: 'Standard_LRS' 10 | } 11 | kind: 'StorageV2' 12 | }] 13 | -------------------------------------------------------------------------------- /samples/loops/loopproperty.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string = resourceGroup().location 2 | 3 | var subnets = [ 4 | { 5 | name: 'api' 6 | subnetPrefix: '10.144.0.0/24' 7 | } 8 | { 9 | name: 'worker' 10 | subnetPrefix: '10.144.1.0/24' 11 | } 12 | ] 13 | 14 | resource vnet 'Microsoft.Network/virtualNetworks@2020-07-01' = { 15 | name: 'vnet' 16 | location: rgLocation 17 | properties: { 18 | addressSpace: { 19 | addressPrefixes: [ 20 | '10.144.0.0/20' 21 | ] 22 | } 23 | subnets: [for subnet in subnets: { 24 | name: subnet.name 25 | properties: { 26 | addressPrefix: subnet.subnetPrefix 27 | } 28 | }] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /samples/loops/loopserialstorage.bicep: -------------------------------------------------------------------------------- 1 | @maxValue(6) 2 | param storageCount int = 3 3 | 4 | param rgLocation string = resourceGroup().location 5 | 6 | @batchSize(1) 7 | resource storageAcct 'Microsoft.Storage/storageAccounts@2021-02-01' = [for i in range(0, storageCount): { 8 | name: '${i}storage${uniqueString(resourceGroup().id)}' 9 | location: rgLocation 10 | sku: { 11 | name: 'Standard_LRS' 12 | } 13 | kind: 'Storage' 14 | }] 15 | -------------------------------------------------------------------------------- /samples/loops/loopstorage.bicep: -------------------------------------------------------------------------------- 1 | @maxValue(6) 2 | param storageCount int = 3 3 | 4 | param rgLocation string = resourceGroup().location 5 | 6 | resource storageAcct 'Microsoft.Storage/storageAccounts@2021-02-01' = [for i in range(0, storageCount): { 7 | name: '${i}storage${uniqueString(resourceGroup().id)}' 8 | location: rgLocation 9 | sku: { 10 | name: 'Standard_LRS' 11 | } 12 | kind: 'Storage' 13 | }] 14 | -------------------------------------------------------------------------------- /samples/loops/loopstoragewitharray.bicep: -------------------------------------------------------------------------------- 1 | param org array = [ 2 | 'contoso' 3 | 'fabrikam' 4 | 'coho' 5 | ] 6 | 7 | param rgLocation string = resourceGroup().location 8 | 9 | resource storageAcct 'Microsoft.Storage/storageAccounts@2021-02-01' = [for item in org: { 10 | name: '${item}${uniqueString(resourceGroup().id)}' 11 | location: rgLocation 12 | sku: { 13 | name: 'Standard_LRS' 14 | } 15 | kind: 'Storage' 16 | }] 17 | -------------------------------------------------------------------------------- /samples/loops/loopvariables.bicep: -------------------------------------------------------------------------------- 1 | var disks_top_level_array = [for i in range(0, 5): { 2 | name: 'myDataDisk${(i + 1)}' 3 | diskSizeGB: '1' 4 | diskIndex: i 5 | }] 6 | 7 | output exampleArray array = disks_top_level_array 8 | -------------------------------------------------------------------------------- /samples/loops/multiplesecurityrules.bicep: -------------------------------------------------------------------------------- 1 | @description('An array that contains objects with properties for the security rules. For format, see multiplesecurityrules.parameters.json.') 2 | param securityRules array 3 | 4 | var securityRulesVar = [for item in securityRules: { 5 | name: item.name 6 | properties: { 7 | description: item.description 8 | priority: item.priority 9 | protocol: item.protocol 10 | sourcePortRange: item.sourcePortRange 11 | destinationPortRange: item.destinationPortRange 12 | sourceAddressPrefix: item.sourceAddressPrefix 13 | destinationAddressPrefix: item.destinationAddressPrefix 14 | access: item.access 15 | direction: item.direction 16 | } 17 | }] 18 | 19 | resource netSG 'Microsoft.Network/networkSecurityGroups@2020-11-01' = { 20 | name: 'NSG1' 21 | location: resourceGroup().location 22 | properties: { 23 | securityRules: securityRulesVar 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/loops/multiplesecurityrules.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "securityRules": { 6 | "value": [ 7 | { 8 | "name": "RDPAllow", 9 | "description": "allow RDP connections", 10 | "direction": "Inbound", 11 | "priority": 100, 12 | "sourceAddressPrefix": "*", 13 | "destinationAddressPrefix": "10.0.0.0/24", 14 | "sourcePortRange": "*", 15 | "destinationPortRange": "3389", 16 | "access": "Allow", 17 | "protocol": "Tcp" 18 | }, 19 | { 20 | "name": "HTTPAllow", 21 | "description": "allow HTTP connections", 22 | "direction": "Inbound", 23 | "priority": 200, 24 | "sourceAddressPrefix": "*", 25 | "destinationAddressPrefix": "10.0.1.0/24", 26 | "sourcePortRange": "*", 27 | "destinationPortRange": "80", 28 | "access": "Allow", 29 | "protocol": "Tcp" 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /samples/modules/parent-output.bicep: -------------------------------------------------------------------------------- 1 | targetScope = 'subscription' 2 | 3 | @minLength(3) 4 | @maxLength(11) 5 | param namePrefix string 6 | 7 | resource demoRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = { 8 | name: 'demogroup1' 9 | } 10 | 11 | module stgModule '../create-storage-account/main.bicep' = { 12 | name: 'storageDeploy' 13 | scope: demoRG 14 | params: { 15 | storagePrefix: namePrefix 16 | location: demoRG.location 17 | } 18 | } 19 | 20 | output storageEndpoint object = stgModule.outputs.storageEndpoint 21 | -------------------------------------------------------------------------------- /samples/modules/rg-and-storage.bicep: -------------------------------------------------------------------------------- 1 | // set the target scope for this file 2 | targetScope = 'subscription' 3 | 4 | @minLength(3) 5 | @maxLength(11) 6 | param namePrefix string 7 | 8 | param location string = deployment().location 9 | 10 | var resourceGroupName = '${namePrefix}rg' 11 | 12 | resource newRG 'Microsoft.Resources/resourceGroups@2021-04-01' = { 13 | name: resourceGroupName 14 | location: location 15 | } 16 | 17 | module stgModule '../create-storage-account/main.bicep' = { 18 | name: 'storageDeploy' 19 | scope: newRG 20 | params: { 21 | storagePrefix: namePrefix 22 | location: location 23 | } 24 | } 25 | 26 | output storageEndpoint object = stgModule.outputs.storageEndpoint 27 | -------------------------------------------------------------------------------- /samples/modules/scope-two-resource-groups.bicep: -------------------------------------------------------------------------------- 1 | targetScope = 'subscription' 2 | 3 | resource firstRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = { 4 | name: 'demogroup1' 5 | } 6 | 7 | resource secondRG 'Microsoft.Resources/resourceGroups@2021-04-01' existing = { 8 | name: 'demogroup2' 9 | } 10 | 11 | module storage1 '../create-storage-account/main.bicep' = { 12 | name: 'westusdeploy' 13 | scope: firstRG 14 | params: { 15 | storagePrefix: 'stg1' 16 | location: 'westus' 17 | } 18 | } 19 | 20 | module storage2 '../create-storage-account/main.bicep' = { 21 | name: 'eastusdeploy' 22 | scope: secondRG 23 | params: { 24 | storagePrefix: 'stg2' 25 | location: 'eastus' 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/patterns-configuration-set/main.bicep: -------------------------------------------------------------------------------- 1 | @description('The location into which your Azure resources should be deployed.') 2 | param location string = resourceGroup().location 3 | 4 | @description('Select the type of environment you want to provision. Allowed values are Production and NonProduction.') 5 | @allowed([ 6 | 'Production' 7 | 'NonProduction' 8 | ]) 9 | param environmentType string = 'NonProduction' 10 | 11 | param storageAccountName string = 'stor${uniqueString(resourceGroup().id)}' 12 | param appServiceAppName string = 'app${uniqueString(resourceGroup().id)}' 13 | 14 | var appServicePlanName = 'MyAppServicePlan' 15 | 16 | var environmentConfigurationMap = { 17 | Production: { 18 | appServicePlan: { 19 | sku: { 20 | name: 'P2V3' 21 | capacity: 3 22 | } 23 | } 24 | appServiceApp: { 25 | alwaysOn: false 26 | } 27 | storageAccount: { 28 | sku: { 29 | name: 'Standard_ZRS' 30 | } 31 | } 32 | } 33 | NonProduction: { 34 | appServicePlan: { 35 | sku: { 36 | name: 'S2' 37 | capacity: 1 38 | } 39 | } 40 | appServiceApp: { 41 | alwaysOn: false 42 | } 43 | storageAccount: { 44 | sku: { 45 | name: 'Standard_LRS' 46 | } 47 | } 48 | } 49 | } 50 | 51 | resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { 52 | name: appServicePlanName 53 | location: location 54 | sku: environmentConfigurationMap[environmentType].appServicePlan.sku 55 | } 56 | 57 | resource appServiceApp 'Microsoft.Web/sites@2022-09-01' = { 58 | name: appServiceAppName 59 | location: location 60 | properties: { 61 | serverFarmId: appServicePlan.id 62 | httpsOnly: true 63 | siteConfig: { 64 | alwaysOn: environmentConfigurationMap[environmentType].appServiceApp.alwaysOn 65 | } 66 | } 67 | } 68 | 69 | resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { 70 | name: storageAccountName 71 | location: location 72 | kind: 'StorageV2' 73 | sku: environmentConfigurationMap[environmentType].storageAccount.sku 74 | } 75 | -------------------------------------------------------------------------------- /samples/patterns-logical-parameter/all-tenant-resources.bicep: -------------------------------------------------------------------------------- 1 | param location string 2 | param sqlServerName string 3 | param frontDoorProfileName string 4 | param tenants array 5 | 6 | // This needs to ge in a separate module so that we can iterate through the outputs of each tenant module's deployment and create an array of all custom domain resource IDs. 7 | 8 | module tenantResources 'tenant-resources.bicep' = [for tenant in tenants: { 9 | name: 'tenant-${tenant.id}' 10 | params: { 11 | location: location 12 | tenant: tenant 13 | sqlServerName: sqlServerName 14 | frontDoorProfileName: frontDoorProfileName 15 | } 16 | }] 17 | 18 | output tenantFrontDoorCustomDomainIds array = [for (tenant, index) in tenants: { 19 | id: tenantResources[index].outputs.frontDoorCustomDomainId 20 | }] 21 | -------------------------------------------------------------------------------- /samples/patterns-logical-parameter/resources.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | param sqlServerName string = 'myapp${uniqueString(resourceGroup().id)}' 4 | 5 | param frontDoorEndpointName string = 'myapp-${uniqueString(resourceGroup().id)}' 6 | 7 | param applicationHostName string = 'jodownsll.azurewebsites.net' // TODO 8 | 9 | @allowed([ 10 | 'Standard_AzureFrontDoor' 11 | 'Premium_AzureFrontDoor' 12 | ]) 13 | param frontDoorSkuName string = 'Standard_AzureFrontDoor' 14 | 15 | param tenants array = [ 16 | { 17 | id: 'fabrikam' 18 | domainName: 'fabrikam.com' 19 | } 20 | { 21 | id: 'contoso' 22 | domainName: 'contoso.com' 23 | } 24 | ] 25 | 26 | var frontDoorProfileName = 'MyFrontDoor' 27 | var frontDoorOriginGroupName = 'MyOriginGroup' 28 | var frontDoorOriginName = 'MyAppServiceOrigin' 29 | var frontDoorRouteName = 'MyRoute' 30 | 31 | // All tenant-specific resources are created within this module. 32 | module allTenantResources 'all-tenant-resources.bicep' = { 33 | name: 'all-tenants' 34 | params: { 35 | location: location 36 | tenants: tenants 37 | sqlServerName: sqlServer.name 38 | frontDoorProfileName: frontDoorProfile.name 39 | } 40 | } 41 | 42 | // Shared Azure SQL logical server. 43 | resource sqlServer 'Microsoft.Sql/servers@2022-11-01-preview' = { 44 | name: sqlServerName 45 | location: location 46 | } 47 | 48 | // Shared Front Door resources 49 | resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' = { 50 | name: frontDoorProfileName 51 | location: 'global' 52 | sku: { 53 | name: frontDoorSkuName 54 | } 55 | } 56 | 57 | resource frontDoorEndpoint 'Microsoft.Cdn/profiles/afdEndpoints@2023-05-01' = { 58 | name: frontDoorEndpointName 59 | parent: frontDoorProfile 60 | location: 'global' 61 | properties: { 62 | originResponseTimeoutSeconds: 240 63 | enabledState: 'Enabled' 64 | } 65 | } 66 | 67 | resource frontDoorOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = { 68 | name: frontDoorOriginGroupName 69 | parent: frontDoorProfile 70 | properties: { 71 | loadBalancingSettings: { 72 | sampleSize: 4 73 | successfulSamplesRequired: 3 74 | } 75 | healthProbeSettings: { 76 | probePath: '/' 77 | probeRequestType: 'HEAD' 78 | probeProtocol: 'Http' 79 | probeIntervalInSeconds: 100 80 | } 81 | } 82 | } 83 | 84 | resource frontDoorOrigin 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01' = { 85 | name: frontDoorOriginName 86 | parent: frontDoorOriginGroup 87 | properties: { 88 | hostName: applicationHostName 89 | httpPort: 80 90 | httpsPort: 443 91 | priority: 1 92 | weight: 1000 93 | } 94 | } 95 | 96 | resource frontDoorRoute 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = { 97 | name: frontDoorRouteName 98 | parent: frontDoorEndpoint 99 | dependsOn: [ 100 | allTenantResources 101 | ] 102 | properties: { 103 | originGroup: { 104 | id: frontDoorOriginGroup.id 105 | } 106 | customDomains: allTenantResources.outputs.tenantFrontDoorCustomDomainIds 107 | supportedProtocols: [ 108 | 'Http' 109 | 'Https' 110 | ] 111 | patternsToMatch: [ 112 | '/*' 113 | ] 114 | compressionSettings: { 115 | contentTypesToCompress: [ 116 | 'application/eot' 117 | 'application/font' 118 | 'application/font-sfnt' 119 | 'application/javascript' 120 | 'application/json' 121 | 'application/opentype' 122 | 'application/otf' 123 | 'application/pkcs7-mime' 124 | 'application/truetype' 125 | 'application/ttf' 126 | 'application/vnd.ms-fontobject' 127 | 'application/xhtml+xml' 128 | 'application/xml' 129 | 'application/xml+rss' 130 | 'application/x-font-opentype' 131 | 'application/x-font-truetype' 132 | 'application/x-font-ttf' 133 | 'application/x-httpd-cgi' 134 | 'application/x-javascript' 135 | 'application/x-mpegurl' 136 | 'application/x-opentype' 137 | 'application/x-otf' 138 | 'application/x-perl' 139 | 'application/x-ttf' 140 | 'font/eot' 141 | 'font/ttf' 142 | 'font/otf' 143 | 'font/opentype' 144 | 'image/svg+xml' 145 | 'text/css' 146 | 'text/csv' 147 | 'text/html' 148 | 'text/javascript' 149 | 'text/js' 150 | 'text/plain' 151 | 'text/richtext' 152 | 'text/tab-separated-values' 153 | 'text/xml' 154 | 'text/x-script' 155 | 'text/x-component' 156 | 'text/x-java-source' 157 | ] 158 | isCompressionEnabled: true 159 | } 160 | queryStringCachingBehavior: 'IgnoreQueryString' 161 | forwardingProtocol: 'HttpsOnly' 162 | linkToDefaultDomain: 'Enabled' 163 | httpsRedirect: 'Enabled' 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /samples/patterns-logical-parameter/service-bus.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param serviceBusNamespaceName string = 'myapp${uniqueString(resourceGroup().id)}' 3 | param skuName string = 'Basic' 4 | 5 | param queueNames array = [ 6 | 'queue1' 7 | 'queue2' 8 | ] 9 | 10 | var deadLetterFirehoseQueueName = 'deadletterfirehose' 11 | 12 | resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-10-01-preview' = { 13 | name: serviceBusNamespaceName 14 | location: location 15 | sku: { 16 | name: skuName 17 | } 18 | } 19 | 20 | resource deadLetterFirehoseQueue 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = { 21 | name: deadLetterFirehoseQueueName 22 | parent: serviceBusNamespace 23 | properties: { 24 | requiresDuplicateDetection: false 25 | requiresSession: false 26 | enablePartitioning: false 27 | } 28 | } 29 | 30 | resource queues 'Microsoft.ServiceBus/namespaces/queues@2022-10-01-preview' = [for queueName in queueNames: { 31 | parent: serviceBusNamespace 32 | name: queueName 33 | dependsOn: [ 34 | deadLetterFirehoseQueue 35 | ] 36 | properties: { 37 | forwardDeadLetteredMessagesTo: deadLetterFirehoseQueueName 38 | } 39 | }] 40 | -------------------------------------------------------------------------------- /samples/patterns-logical-parameter/tenant-resources.bicep: -------------------------------------------------------------------------------- 1 | param location string 2 | param sqlServerName string 3 | param frontDoorProfileName string 4 | param tenant object 5 | 6 | var frontDoorCustomDomainName = replace(tenant.domainName, '.', '-') 7 | 8 | // Deploy a database for the tenant. 9 | resource sqlServer 'Microsoft.Sql/servers@2022-11-01-preview' existing = { 10 | name: sqlServerName 11 | } 12 | 13 | resource sqlServerDatabase 'Microsoft.Sql/servers/databases@2022-11-01-preview' = { 14 | parent: sqlServer 15 | name: tenant.id 16 | location: location 17 | } 18 | 19 | // Deploy a Front Door custom domain for the tenant. 20 | resource frontDoorProfile 'Microsoft.Cdn/profiles@2023-05-01' existing = { 21 | name: frontDoorProfileName 22 | } 23 | 24 | resource frontDoorCustomDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = { 25 | parent: frontDoorProfile 26 | name: frontDoorCustomDomainName 27 | properties: { 28 | hostName: tenant.domainName 29 | } 30 | } 31 | 32 | output frontDoorCustomDomainId string = frontDoorCustomDomain.id 33 | -------------------------------------------------------------------------------- /samples/patterns-logical-parameter/virtual-network.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param virtualNetworkName string = 'my-vnet' 3 | param virtualNetworkAddressPrefix string = '10.0.0.0/16' 4 | param subnets array = [ 5 | { 6 | name: 'Web' 7 | addressPrefix: '10.0.0.0/24' 8 | allowRdp: false 9 | } 10 | { 11 | name: 'JumpBox' 12 | addressPrefix: '10.0.1.0/24' 13 | allowRdp: true 14 | } 15 | ] 16 | 17 | var subnetsToCreate = [for item in subnets: { 18 | name: item.name 19 | properties: { 20 | addressPrefix: item.addressPrefix 21 | networkSecurityGroup: item.allowRdp ? { 22 | id: nsgAllowRdp.id 23 | } : null 24 | } 25 | }] 26 | var nsgAllowRdpName = 'nsg-allow-rdp' 27 | 28 | resource nsgAllowRdp 'Microsoft.Network/networkSecurityGroups@2022-11-01' = { 29 | name: nsgAllowRdpName 30 | location: location 31 | properties: { 32 | securityRules: [ 33 | { 34 | name: 'allow-rdp' 35 | properties: { 36 | description: 'Allow RDP' 37 | protocol: 'Tcp' 38 | sourcePortRange: '*' 39 | destinationPortRange: '3389' 40 | sourceAddressPrefix: 'Internet' 41 | destinationAddressPrefix: '*' 42 | access: 'Allow' 43 | priority: 100 44 | direction: 'Inbound' 45 | } 46 | } 47 | ] 48 | } 49 | } 50 | 51 | resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-11-01' = { 52 | name: virtualNetworkName 53 | location: location 54 | properties: { 55 | addressSpace: { 56 | addressPrefixes: [ 57 | virtualNetworkAddressPrefix 58 | ] 59 | } 60 | subnets: subnetsToCreate 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /samples/patterns-name-generation/app-service.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param environmentName string 3 | param appServiceAppName string = 'app-contoso-${environmentName}-${uniqueString(resourceGroup().id)}' 4 | param appServicePlanName string = 'plan-contoso-${environmentName}-${uniqueString(resourceGroup().id)}' 5 | 6 | resource appServiceApp 'Microsoft.Web/sites@2022-09-01' = { 7 | name: appServiceAppName 8 | // ... 9 | location: location 10 | properties: { 11 | serverFarmId: appServicePlan.id 12 | } 13 | } 14 | 15 | resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { 16 | name: appServicePlanName 17 | // ... 18 | location: location 19 | sku: { 20 | name: 'S1' 21 | capacity: 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/patterns-name-generation/storage.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | param primaryStorageAccountName string = 'contosopri${uniqueString(resourceGroup().id)}' 4 | param secondaryStorageAccountName string = 'contososec${uniqueString(resourceGroup().id)}' 5 | 6 | resource primaryStorageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { 7 | name: primaryStorageAccountName 8 | // ... 9 | location: location 10 | kind: 'StorageV2' 11 | sku: { 12 | name: 'Premium_LRS' 13 | } 14 | } 15 | 16 | resource secondaryStorageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { 17 | name: secondaryStorageAccountName 18 | // ... 19 | location: location 20 | kind: 'StorageV2' 21 | sku: { 22 | name: 'Premium_LRS' 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/patterns-shared-variable-file/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "yaml.schemas": { 3 | "file:///c%3A/Users/jgao/.vscode/extensions/docsmsft.docs-yaml-1.0.0/dist/toc.schema.json": "/toc\\.yml/i", 4 | "file:///c:/Users/jgao/.vscode/extensions/teamtoolbox.docindex-1.4.2/resources/config/common/docindex.schema.json": "**/.[dD][oO][cC][iI][nN][dD][eE][xX]/**/*.yml", 5 | "file:///c:/Users/jgao/.vscode/extensions/teamtoolbox.docindex-1.4.2/resources/config/common/module.schema.json": "**/[iI][nN][dD][eE][xX].yml" 6 | } 7 | } -------------------------------------------------------------------------------- /samples/patterns-shared-variable-file/example-1.bicep: -------------------------------------------------------------------------------- 1 | var sharedNamePrefixes = loadJsonContent('./shared-prefixes.json') 2 | 3 | var appServiceAppName = '${sharedNamePrefixes.appServicePrefix}-myapp-${uniqueString(resourceGroup().id)}' 4 | var storageAccountName = '${sharedNamePrefixes.storageAccountPrefix}myapp${uniqueString(resourceGroup().id)}' 5 | -------------------------------------------------------------------------------- /samples/patterns-shared-variable-file/example-2.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | var nsgName = 'MyNSG' 4 | 5 | var sharedRules = loadJsonContent('./shared-rules.json', 'securityRules') 6 | var customRules = [ 7 | { 8 | name: 'Allow_Internet_HTTPS_Inbound' 9 | properties: { 10 | description: 'Allow inbound internet connectivity for HTTPS only.' 11 | protocol: 'Tcp' 12 | sourcePortRange: '*' 13 | destinationPortRange: '443' 14 | sourceAddressPrefix: 'Internet' 15 | destinationAddressPrefix: 'VirtualNetwork' 16 | access: 'Allow' 17 | priority: 400 18 | direction: 'Inbound' 19 | } 20 | } 21 | ] 22 | 23 | resource nsg 'Microsoft.Network/networkSecurityGroups@2021-08-01' = { 24 | name: nsgName 25 | location: location 26 | properties: { 27 | securityRules: concat(sharedRules, customRules) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/patterns-shared-variable-file/shared-prefixes.json: -------------------------------------------------------------------------------- 1 | { 2 | "storageAccountPrefix": "stg", 3 | "appServicePrefix": "app" 4 | } -------------------------------------------------------------------------------- /samples/patterns-shared-variable-file/shared-rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "securityRules": [ 3 | { 4 | "name": "Allow_RDP_from_company_IP_address", 5 | "properties": { 6 | "description": "Allow inbound RDP from the company's IP address range.", 7 | "protocol": "Tcp", 8 | "sourceAddressPrefix": "203.0.113.0/24", 9 | "sourcePortRange": "*", 10 | "destinationAddressPrefix": "VirtualNetwork", 11 | "destinationPortRange": "3389", 12 | "access": "Allow", 13 | "priority": 100, 14 | "direction": "Inbound" 15 | } 16 | }, 17 | { 18 | "name": "Allow_VirtualNetwork_to_Storage", 19 | "properties": { 20 | "description": "Allow outbound connections to the Azure Storage service tag.", 21 | "protocol": "Tcp", 22 | "sourceAddressPrefix": "VirtualNetwork", 23 | "sourcePortRange": "*", 24 | "destinationAddressPrefix": "Storage", 25 | "destinationPortRange": "*", 26 | "access": "Allow", 27 | "priority": 100, 28 | "direction": "Outbound" 29 | } 30 | } 31 | // other rules here 32 | ] 33 | } -------------------------------------------------------------------------------- /samples/scenarios-monitoring/action-group.bicep: -------------------------------------------------------------------------------- 1 | param actionGroupName string = 'On-Call Team' 2 | param location string = resourceGroup().location 3 | 4 | var actionGroupEmail = 'oncallteam@contoso.com' 5 | 6 | resource supportTeamActionGroup 'Microsoft.Insights/actionGroups@2023-01-01' = { 7 | name: actionGroupName 8 | location: location 9 | properties: { 10 | enabled: true 11 | groupShortName: actionGroupName 12 | emailReceivers: [ 13 | { 14 | name: actionGroupName 15 | emailAddress: actionGroupEmail 16 | useCommonAlertSchema: true 17 | } 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/activity-log-alert.bicep: -------------------------------------------------------------------------------- 1 | param activityLogAlertName string = '${uniqueString(resourceGroup().id)}-alert' 2 | param actionGroupName string = 'adminactiongroup' 3 | 4 | resource actionGroup 'Microsoft.Insights/actionGroups@2021-09-01' existing = { 5 | name: actionGroupName 6 | } 7 | 8 | resource activityLogAlert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = { 9 | name: activityLogAlertName 10 | location: 'Global' 11 | properties: { 12 | condition: { 13 | allOf: [ 14 | { 15 | field: 'category' 16 | equals: 'Administrative' 17 | } 18 | { 19 | field: 'operationName' 20 | equals: 'Microsoft.Resources/deployments/write' 21 | } 22 | { 23 | field: 'resourceType' 24 | equals: 'Microsoft.Resources/deployments' 25 | } 26 | ] 27 | } 28 | actions: { 29 | actionGroups: [ 30 | { 31 | actionGroupId: actionGroup.id 32 | } 33 | ] 34 | } 35 | scopes: [ 36 | subscription().id 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/alert-processing-rules.bicep: -------------------------------------------------------------------------------- 1 | param alertRuleName string = 'AlertRuleName' 2 | param actionGroupName string = 'On-Call Team' 3 | param location string = resourceGroup().location 4 | 5 | resource actionGroup 'Microsoft.Insights/actionGroups@2021-09-01' existing = { 6 | name: actionGroupName 7 | } 8 | 9 | resource alertProcessingRule 'Microsoft.AlertsManagement/actionRules@2021-08-08' = { 10 | name: alertRuleName 11 | location: location 12 | properties: { 13 | actions: [ 14 | { 15 | actionType: 'AddActionGroups' 16 | actionGroupIds: [ 17 | actionGroup.id 18 | ] 19 | } 20 | ] 21 | conditions: [ 22 | { 23 | field: 'MonitorService' 24 | operator: 'Equals' 25 | values: [ 26 | 'Azure Backup' 27 | ] 28 | } 29 | ] 30 | enabled: true 31 | scopes: [ 32 | subscription().id 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/autoscaling-rules.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param appPlanName string = '${uniqueString(resourceGroup().id)}asp' 3 | 4 | var appPlanSkuName = 'S1' 5 | 6 | resource appServicePlan 'Microsoft.Web/serverfarms@2022-09-01' = { 7 | name: appPlanName 8 | location: location 9 | properties: {} 10 | sku: { 11 | name: appPlanSkuName 12 | capacity: 1 13 | } 14 | } 15 | 16 | resource scaleOutRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = { 17 | name: appServicePlan.name 18 | location: location 19 | properties: { 20 | enabled: true 21 | profiles: [ 22 | { 23 | name: 'Scale out condition' 24 | capacity: { 25 | maximum: '3' 26 | default: '1' 27 | minimum: '1' 28 | } 29 | rules: [ 30 | { 31 | scaleAction: { 32 | type: 'ChangeCount' 33 | direction: 'Increase' 34 | cooldown: 'PT5M' 35 | value: '1' 36 | } 37 | metricTrigger: { 38 | metricName: 'CpuPercentage' 39 | operator: 'GreaterThan' 40 | timeAggregation: 'Average' 41 | threshold: 70 42 | metricResourceUri: appServicePlan.id 43 | timeWindow: 'PT10M' 44 | timeGrain: 'PT1M' 45 | statistic: 'Average' 46 | } 47 | } 48 | ] 49 | } 50 | ] 51 | targetResourceUri: appServicePlan.id 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/diagnostic-settings-activity-log.bicep: -------------------------------------------------------------------------------- 1 | targetScope = 'subscription' 2 | 3 | param logAnalyticsWorkspaceId string 4 | 5 | var activityLogDiagnosticSettingsName = 'export-activity-log' 6 | 7 | resource subscriptionActivityLog 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { 8 | name: activityLogDiagnosticSettingsName 9 | properties: { 10 | workspaceId: logAnalyticsWorkspaceId 11 | logs: [ 12 | { 13 | category: 'Administrative' 14 | enabled: true 15 | } 16 | { 17 | category: 'Security' 18 | enabled: true 19 | } 20 | { 21 | category: 'ServiceHealth' 22 | enabled: true 23 | } 24 | { 25 | category: 'Alert' 26 | enabled: true 27 | } 28 | { 29 | category: 'Recommendation' 30 | enabled: true 31 | } 32 | { 33 | category: 'Policy' 34 | enabled: true 35 | } 36 | { 37 | category: 'Autoscale' 38 | enabled: true 39 | } 40 | { 41 | category: 'ResourceHealth' 42 | enabled: true 43 | } 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/diagnostic-settings.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param appPlanName string = '${uniqueString(resourceGroup().id)}asp' 3 | param logAnalyticsWorkspace string = '${uniqueString(resourceGroup().id)}la' 4 | 5 | var appPlanSkuName = 'S1' 6 | 7 | resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' existing = { 8 | name: logAnalyticsWorkspace 9 | } 10 | 11 | resource appServicePlan 'Microsoft.Web/serverfarms@2021-03-01' = { 12 | name: appPlanName 13 | location: location 14 | sku: { 15 | name: appPlanSkuName 16 | capacity: 1 17 | } 18 | } 19 | 20 | resource diagnosticLogs 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = { 21 | name: appServicePlan.name 22 | scope: appServicePlan 23 | properties: { 24 | workspaceId: logAnalytics.id 25 | logs: [ 26 | { 27 | category: 'AllMetrics' 28 | enabled: true 29 | retentionPolicy: { 30 | days: 30 31 | enabled: true 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/scenarios-monitoring/resource-health-alerts.bicep: -------------------------------------------------------------------------------- 1 | param activityLogAlertName string = uniqueString(resourceGroup().id) 2 | param actionGroupName string = 'oncallactiongroup' 3 | 4 | resource actionGroup 'Microsoft.Insights/actionGroups@2021-09-01' existing = { 5 | name: actionGroupName 6 | } 7 | 8 | resource resourceHealthAlert 'Microsoft.Insights/activityLogAlerts@2020-10-01' = { 9 | name: activityLogAlertName 10 | location: 'global' 11 | properties: { 12 | condition: { 13 | allOf: [ 14 | { 15 | field: 'category' 16 | equals: 'ServiceHealth' 17 | } 18 | ] 19 | } 20 | scopes: [ 21 | subscription().id 22 | ] 23 | actions: { 24 | actionGroups: [ 25 | { 26 | actionGroupId: actionGroup.id 27 | } 28 | ] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/scenarios-rbac/built-in-role.bicep: -------------------------------------------------------------------------------- 1 | param principalId string 2 | 3 | @description('This is the built-in Contributor role. See https://docs.microsoft.com/azure/role-based-access-control/built-in-roles#contributor') 4 | resource contributorRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = { 5 | scope: subscription() 6 | name: 'b24988ac-6180-42a0-ab88-20f7382dd24c' 7 | } 8 | 9 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { 10 | name: guid(resourceGroup().id, principalId, contributorRoleDefinition.id) 11 | properties: { 12 | roleDefinitionId: contributorRoleDefinition.id 13 | principalId: principalId 14 | principalType: 'ServicePrincipal' 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/scenarios-rbac/managed-identity.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param roleDefinitionResourceId string 3 | 4 | var managedIdentityName = 'MyManagedIdentity' 5 | 6 | resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { 7 | name: managedIdentityName 8 | location: location 9 | } 10 | 11 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { 12 | name: guid(resourceGroup().id, managedIdentity.id, roleDefinitionResourceId) 13 | properties: { 14 | roleDefinitionId: roleDefinitionResourceId 15 | principalId: managedIdentity.properties.principalId 16 | principalType: 'ServicePrincipal' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/scenarios-rbac/scope-default.bicep: -------------------------------------------------------------------------------- 1 | param roleDefinitionResourceId string 2 | param principalId string 3 | 4 | targetScope = 'subscription' 5 | 6 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { 7 | name: guid(subscription().id, principalId, roleDefinitionResourceId) 8 | properties: { 9 | roleDefinitionId: roleDefinitionResourceId 10 | principalId: principalId 11 | principalType: 'ServicePrincipal' 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples/scenarios-rbac/scope.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param storageAccountName string = 'stor${uniqueString(resourceGroup().id)}' 3 | param storageSkuName string = 'Standard_LRS' 4 | param roleDefinitionResourceId string 5 | param principalId string 6 | 7 | resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { 8 | name: storageAccountName 9 | location: location 10 | kind: 'StorageV2' 11 | sku: { 12 | name: storageSkuName 13 | } 14 | } 15 | 16 | resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { 17 | scope: storageAccount 18 | name: guid(storageAccount.id, principalId, roleDefinitionResourceId) 19 | properties: { 20 | roleDefinitionId: roleDefinitionResourceId 21 | principalId: principalId 22 | principalType: 'ServicePrincipal' 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/scenarios-secrets/function-app.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param storageAccountName string 3 | param functionAppName string = 'fn-${uniqueString(resourceGroup().id)}' 4 | 5 | var appServicePlanName = 'MyPlan' 6 | var applicationInsightsName = 'MyApplicationInsights' 7 | 8 | resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' existing = { 9 | name: storageAccountName 10 | } 11 | 12 | var storageAccountConnectionString = 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};EndpointSuffix=${environment().suffixes.storage};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}' 13 | 14 | resource functionApp 'Microsoft.Web/sites@2021-02-01' = { 15 | name: functionAppName 16 | location: location 17 | kind: 'functionapp' 18 | properties: { 19 | httpsOnly: true 20 | serverFarmId: appServicePlan.id 21 | siteConfig: { 22 | appSettings: [ 23 | { 24 | name: 'APPINSIGHTS_INSTRUMENTATIONKEY' 25 | value: applicationInsights.properties.InstrumentationKey 26 | } 27 | { 28 | name: 'AzureWebJobsStorage' 29 | value: storageAccountConnectionString 30 | } 31 | { 32 | name: 'FUNCTIONS_EXTENSION_VERSION' 33 | value: '~3' 34 | } 35 | { 36 | name: 'FUNCTIONS_WORKER_RUNTIME' 37 | value: 'dotnet' 38 | } 39 | { 40 | name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING' 41 | value: storageAccountConnectionString 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | 48 | resource appServicePlan 'Microsoft.Web/serverfarms@2020-10-01' = { 49 | name: appServicePlanName 50 | location: location 51 | sku: { 52 | name: 'Y1' 53 | tier: 'Dynamic' 54 | } 55 | } 56 | 57 | resource applicationInsights 'Microsoft.Insights/components@2020-02-02-preview' = { 58 | name: applicationInsightsName 59 | location: location 60 | kind: 'web' 61 | properties: { 62 | Application_Type: 'web' 63 | publicNetworkAccessForIngestion: 'Enabled' 64 | publicNetworkAccessForQuery: 'Enabled' 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /samples/scenarios-secrets/key-vault-secret.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | param keyVaultName string = 'mykv${uniqueString(resourceGroup().id)}' 3 | 4 | resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { 5 | name: keyVaultName 6 | location: location 7 | properties: { 8 | enabledForTemplateDeployment: true 9 | tenantId: tenant().tenantId 10 | accessPolicies: [ 11 | ] 12 | sku: { 13 | name: 'standard' 14 | family: 'A' 15 | } 16 | } 17 | } 18 | 19 | resource keyVaultSecret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = { 20 | parent: keyVault 21 | name: 'MySecretName' 22 | properties: { 23 | value: 'MyVerySecretValue' 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/scenarios-virtual-networks/vnet.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | var virtualNetworkName = 'my-vnet' 4 | var subnet1Name = 'Subnet-1' 5 | var subnet2Name = 'Subnet-2' 6 | 7 | resource virtualNetwork 'Microsoft.Network/virtualNetworks@2019-11-01' = { 8 | name: virtualNetworkName 9 | location: location 10 | properties: { 11 | addressSpace: { 12 | addressPrefixes: [ 13 | '10.0.0.0/16' 14 | ] 15 | } 16 | subnets: [ 17 | { 18 | name: subnet1Name 19 | properties: { 20 | addressPrefix: '10.0.0.0/24' 21 | } 22 | } 23 | { 24 | name: subnet2Name 25 | properties: { 26 | addressPrefix: '10.0.1.0/24' 27 | } 28 | } 29 | ] 30 | } 31 | 32 | resource subnet1 'subnets' existing = { 33 | name: subnet1Name 34 | } 35 | 36 | resource subnet2 'subnets' existing = { 37 | name: subnet2Name 38 | } 39 | } 40 | 41 | output subnet1ResourceId string = virtualNetwork::subnet1.id 42 | output subnet2ResourceId string = virtualNetwork::subnet2.id 43 | -------------------------------------------------------------------------------- /samples/scopes/resource-group/locktargetscope.bicep: -------------------------------------------------------------------------------- 1 | resource createRgLock 'Microsoft.Authorization/locks@2016-09-01' = { 2 | name: 'rgLock' 3 | properties: { 4 | level: 'CanNotDelete' 5 | notes: 'Resource group should not be deleted.' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /syntax-samples/child-resource-name-type/fullnamedeclaration.bicep: -------------------------------------------------------------------------------- 1 | resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = { 2 | name: 'examplestorage' 3 | location: resourceGroup().location 4 | kind: 'StorageV2' 5 | sku: { 6 | name: 'Standard_LRS' 7 | } 8 | } 9 | 10 | resource service 'Microsoft.Storage/storageAccounts/fileServices@2022-09-01' = { 11 | name: 'examplestorage/default' 12 | dependsOn: [ 13 | storage 14 | ] 15 | } 16 | 17 | resource share 'Microsoft.Storage/storageAccounts/fileServices/shares@2022-09-01' = { 18 | name: 'examplestorage/default/exampleshare' 19 | dependsOn: [ 20 | service 21 | ] 22 | } 23 | 24 | -------------------------------------------------------------------------------- /syntax-samples/child-resource-name-type/insidedeclaration.bicep: -------------------------------------------------------------------------------- 1 | resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = { 2 | name: 'examplestorage' 3 | location: resourceGroup().location 4 | kind: 'StorageV2' 5 | sku: { 6 | name: 'Standard_LRS' 7 | } 8 | 9 | resource service 'fileServices' = { 10 | name: 'default' 11 | 12 | resource share 'shares' = { 13 | name: 'exampleshare' 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /syntax-samples/child-resource-name-type/outsidedeclaration.bicep: -------------------------------------------------------------------------------- 1 | resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = { 2 | name: 'examplestorage' 3 | location: resourceGroup().location 4 | kind: 'StorageV2' 5 | sku: { 6 | name: 'Standard_LRS' 7 | } 8 | } 9 | 10 | resource service 'Microsoft.Storage/storageAccounts/fileServices@2022-09-01' = { 11 | name: 'default' 12 | parent: storage 13 | } 14 | 15 | resource share 'Microsoft.Storage/storageAccounts/fileServices/shares@2022-09-01' = { 16 | name: 'exampleshare' 17 | parent: service 18 | } 19 | -------------------------------------------------------------------------------- /syntax-samples/functions/loadJsonContent/loadsharedrules.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | var nsgconfig = loadJsonContent('nsg-security-rules.json') 4 | 5 | resource newNSG 'Microsoft.Network/networkSecurityGroups@2021-02-01' = { 6 | name: 'example-nsg' 7 | location: location 8 | properties: { 9 | securityRules: [ 10 | { 11 | name: 'SSH' 12 | properties: nsgconfig 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /syntax-samples/functions/loadJsonContent/nsg-security-rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Allows SSH traffic", 3 | "protocol": "Tcp", 4 | "sourcePortRange": "*", 5 | "destinationPortRange": "22", 6 | "sourceAddressPrefix": "*", 7 | "destinationAddressPrefix": "*", 8 | "access": "Allow", 9 | "priority": 100, 10 | "direction": "Inbound" 11 | } -------------------------------------------------------------------------------- /syntax-samples/functions/loadTextContent/loaddeploymentscript.bicep: -------------------------------------------------------------------------------- 1 | resource exampleScript 'Microsoft.Resources/deploymentScripts@2020-10-01' = { 2 | name: 'exampleScript' 3 | location: resourceGroup().location 4 | kind: 'AzurePowerShell' 5 | identity: { 6 | type: 'UserAssigned' 7 | userAssignedIdentities: { 8 | '/subscriptions/{sub-id}/resourcegroups/{rg-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{id-name}': {} 9 | } 10 | } 11 | properties: { 12 | azPowerShellVersion: '8.3' 13 | scriptContent: loadTextContent('myscript.ps1') 14 | retentionInterval: 'P1D' 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /syntax-samples/functions/loadTextContent/loadsharedrules.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | var nsgconfig = json(loadTextContent('nsg-security-rules.json')) 4 | 5 | resource newNSG 'Microsoft.Network/networkSecurityGroups@2021-02-01' = { 6 | name: 'example-nsg' 7 | location: location 8 | properties: { 9 | securityRules: [ 10 | { 11 | name: 'SSH' 12 | properties: { 13 | description: nsgconfig.description 14 | protocol: nsgconfig.protocol 15 | sourcePortRange: nsgconfig.sourcePortRange 16 | destinationPortRange: nsgconfig.destinationPortRange 17 | sourceAddressPrefix: nsgconfig.sourceAddressPrefix 18 | destinationAddressPrefix: nsgconfig.destinationAddressPrefix 19 | access: nsgconfig.access 20 | priority: nsgconfig.priority 21 | direction: nsgconfig.direction 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /syntax-samples/functions/loadTextContent/nsg-security-rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Allows SSH traffic", 3 | "protocol": "Tcp", 4 | "sourcePortRange": "*", 5 | "destinationPortRange": "22", 6 | "sourceAddressPrefix": "*", 7 | "destinationAddressPrefix": "*", 8 | "access": "Allow", 9 | "priority": 100, 10 | "direction": "Inbound" 11 | } -------------------------------------------------------------------------------- /syntax-samples/functions/loadYamlContent/loadsharedrules.bicep: -------------------------------------------------------------------------------- 1 | param location string = resourceGroup().location 2 | 3 | var nsgconfig = loadYamlContent('nsg-security-rules.yaml') 4 | 5 | resource newNSG 'Microsoft.Network/networkSecurityGroups@2021-02-01' = { 6 | name: 'example-nsg' 7 | location: location 8 | properties: { 9 | securityRules: [ 10 | { 11 | name: 'SSH' 12 | properties: nsgconfig 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /syntax-samples/functions/loadYamlContent/nsg-security-rules.yaml: -------------------------------------------------------------------------------- 1 | description: "Allows SSH traffic" 2 | protocol: "Tcp" 3 | sourcePortRange: "*" 4 | destinationPortRange: "22" 5 | sourceAddressPrefix: "*" 6 | destinationAddressPrefix: "*" 7 | access: "Allow" 8 | priority: 100 9 | direction: "Inbound" -------------------------------------------------------------------------------- /syntax-samples/modules/alias-definition-public.bicep: -------------------------------------------------------------------------------- 1 | module hw 'br/public:samples/hello-world:1.0.2' = { 2 | name: 'helloWorld' 3 | params: { 4 | name: 'John Dole' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/alias-definition.bicep: -------------------------------------------------------------------------------- 1 | module stgModule 'br/ContosoModules:storage:v1' = { 2 | name: 'storageDeploy' 3 | params: { 4 | storagePrefix: 'examplestg1' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/conditional-definition.bicep: -------------------------------------------------------------------------------- 1 | // conditional deployment 2 | module '' = if () { 3 | name: '' 4 | params: { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /syntax-samples/modules/dependsOn-definition.bicep: -------------------------------------------------------------------------------- 1 | module '' = { 2 | name: '' 3 | params: { 4 | 5 | } 6 | dependsOn: [ 7 | 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /syntax-samples/modules/function-scope.bicep: -------------------------------------------------------------------------------- 1 | param managementGroupName string 2 | 3 | module mgDeploy 'main.bicep' = { 4 | name: 'deployToMG' 5 | scope: managementGroup(managementGroupName) 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/iterative-definition.bicep: -------------------------------------------------------------------------------- 1 | // iterative deployment 2 | @batchSize(int) // optional decorator for serial deployment 3 | module '' = [for in : { 4 | name: '' 5 | params: { 6 | 7 | } 8 | }] 9 | -------------------------------------------------------------------------------- /syntax-samples/modules/local-file-definition-json.bicep: -------------------------------------------------------------------------------- 1 | module stgModule '../storageAccount.json' = { 2 | name: 'storageDeploy' 3 | params: { 4 | storagePrefix: 'examplestg1' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/local-file-definition.bicep: -------------------------------------------------------------------------------- 1 | module stgModule '../storageAccount.bicep' = { 2 | name: 'storageDeploy' 3 | params: { 4 | storagePrefix: 'examplestg1' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/registry-definition-public.bicep: -------------------------------------------------------------------------------- 1 | module hw 'br/public:samples/hello-world:1.0.2' = { 2 | name: 'helloWorld' 3 | params: { 4 | name: 'John Dole' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/registry-definition.bicep: -------------------------------------------------------------------------------- 1 | module stgModule 'br:exampleregistry.azurecr.io/bicep/modules/storage:v1' = { 2 | name: 'storageDeploy' 3 | params: { 4 | storagePrefix: 'examplestg1' 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /syntax-samples/modules/scope-definition.bicep: -------------------------------------------------------------------------------- 1 | // deploy to different scope 2 | module '' = { 3 | name: '' 4 | scope: 5 | params: { 6 | 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /syntax-samples/outputs/module-output.bicep: -------------------------------------------------------------------------------- 1 | module publicIP 'modules/public-ip-address.bicep' = { 2 | name: 'public-ip-address-module' 3 | } 4 | 5 | resource loadBalancer 'Microsoft.Network/loadBalancers@2020-11-01' = { 6 | name: loadBalancerName 7 | location: location 8 | properties: { 9 | frontendIPConfigurations: [ 10 | { 11 | name: 'name' 12 | properties: { 13 | publicIPAddress: { 14 | id: publicIP.outputs.resourceId 15 | } 16 | } 17 | } 18 | ] 19 | // ... 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /syntax-samples/outputs/output.bicep: -------------------------------------------------------------------------------- 1 | output stringOutput string = deployment().name 2 | output integerOutput int = length(environment().authentication.audiences) 3 | output booleanOutput bool = contains(deployment().name, 'demo') 4 | output arrayOutput array = environment().authentication.audiences 5 | output objectOutput object = subscription() 6 | -------------------------------------------------------------------------------- /syntax-samples/parameters/parameterobject.bicep: -------------------------------------------------------------------------------- 1 | param vNetSettings object = { 2 | name: 'VNet1' 3 | location: 'eastus' 4 | addressPrefixes: [ 5 | { 6 | name: 'firstPrefix' 7 | addressPrefix: '10.0.0.0/22' 8 | } 9 | ] 10 | subnets: [ 11 | { 12 | name: 'firstSubnet' 13 | addressPrefix: '10.0.0.0/24' 14 | } 15 | { 16 | name: 'secondSubnet' 17 | addressPrefix: '10.0.1.0/24' 18 | } 19 | ] 20 | } 21 | 22 | resource vnet 'Microsoft.Network/virtualNetworks@2020-06-01' = { 23 | name: vNetSettings.name 24 | location: vNetSettings.location 25 | properties: { 26 | addressSpace: { 27 | addressPrefixes: [ 28 | vNetSettings.addressPrefixes[0].addressPrefix 29 | ] 30 | } 31 | subnets: [ 32 | { 33 | name: vNetSettings.subnets[0].name 34 | properties: { 35 | addressPrefix: vNetSettings.subnets[0].addressPrefix 36 | } 37 | } 38 | { 39 | name: vNetSettings.subnets[1].name 40 | properties: { 41 | addressPrefix: vNetSettings.subnets[1].addressPrefix 42 | } 43 | } 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /syntax-samples/parameters/parameterswithfunctions.bicep: -------------------------------------------------------------------------------- 1 | param siteName string = 'site${uniqueString(resourceGroup().id)}' 2 | param hostingPlanName string = '${siteName}-plan' 3 | 4 | output siteNameOutput string = siteName 5 | output hostingPlanOutput string = hostingPlanName 6 | -------------------------------------------------------------------------------- /syntax-samples/synapse-keys/keys.bicep: -------------------------------------------------------------------------------- 1 | resource customerManagedKey 'Microsoft.KeyVault/vaults/keys@2021-10-01' = { 2 | name: keyName 3 | parent: keyVault 4 | properties: { 5 | kty: 'RSA' 6 | } 7 | } 8 | 9 | resource synapseWorkspace 'Microsoft.Synapse/workspaces@2021-06-01' = { 10 | name: workspaceName 11 | properties: { 12 | encryption: { 13 | cmk: { 14 | key: { 15 | name: keyName 16 | keyVaultUrl: customerManagedKey.properties.keyUri 17 | } 18 | } 19 | } 20 | } 21 | } 22 | 23 | resource workspaceKey 'Microsoft.Synapse/workspaces/keys@2021-06-01' = { 24 | name: keyName 25 | parent: synapseWorkspace 26 | } 27 | -------------------------------------------------------------------------------- /syntax-samples/variables/variables.bicep: -------------------------------------------------------------------------------- 1 | param inputValue string = 'deployment parameter' 2 | param storageID string 3 | 4 | var stringVar = 'myVariable' 5 | var concatToVar = '${stringVar}-addtovar' 6 | var concatToParam = '${inputValue}-addtoparam' 7 | var arrayVar = [ 8 | 1 9 | 2 10 | 3 11 | 4 12 | ] 13 | var objectVar = { 14 | property1: 'value1' 15 | property2: 'value2' 16 | } 17 | var storageKeys = listKeys(storageID, '2019-06-01') 18 | var referenceStorage = reference(storageID, '2019-06-01') 19 | 20 | output stringOutput string = stringVar 21 | output concatToVariableOutput string = concatToVar 22 | output concatToParameterOutput string = concatToParam 23 | output arrayOutput array = arrayVar 24 | output objectOutput object = objectVar 25 | output listKeysOutput object = storageKeys 26 | output referenceOutput object = referenceStorage 27 | -------------------------------------------------------------------------------- /syntax-samples/variables/variablesconfigurations.bicep: -------------------------------------------------------------------------------- 1 | @allowed([ 2 | 'test' 3 | 'prod' 4 | ]) 5 | param environmentName string 6 | 7 | var environmentSettings = { 8 | test: { 9 | instanceSize: 'Small' 10 | instanceCount: 1 11 | } 12 | prod: { 13 | instanceSize: 'Large' 14 | instanceCount: 4 15 | } 16 | } 17 | 18 | output instanceSize string = environmentSettings[environmentName].instanceSize 19 | output instanceCount int = environmentSettings[environmentName].instanceCount 20 | -------------------------------------------------------------------------------- /syntax-samples/variables/variableswithfunction.bicep: -------------------------------------------------------------------------------- 1 | param rgLocation string 2 | param storageNamePrefix string = 'STG' 3 | 4 | var storageName = '${toLower(storageNamePrefix)}${uniqueString(resourceGroup().id)}' 5 | 6 | resource demoAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = { 7 | name: storageName 8 | location: rgLocation 9 | kind: 'Storage' 10 | sku: { 11 | name: 'Standard_LRS' 12 | } 13 | } 14 | 15 | output stgOutput string = storageName 16 | --------------------------------------------------------------------------------