|
| 1 | +# Azure Bicep - @onlyIfNotExists Decorator |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | +The `@onlyIfNotExists()` decorator in Azure Bicep enables **conditional resource deployment** based on whether a resource with the specified name already exists. When applied to a resource declaration, Azure Resource Manager will only create the resource if one with that name doesn't already exist in the target scope. |
| 6 | + |
| 7 | +It's particularly valuable for deploying resources that should only be created once, such as Key Vault secrets, where you want to avoid overwriting existing values or encountering "resource already exists" errors. |
| 8 | + |
| 9 | +> [!NOTE] |
| 10 | +> The decorator checks only the resource **name** - it does not compare properties or configurations. If a resource with the same name exists, deployment is skipped entirely for that resource, regardless of whether its properties match the template definition. |
| 11 | +
|
| 12 | +Learn more about the `@onlyIfNotExists()` decorator in the [official Microsoft Learn documentation](https://learn.microsoft.com/azure/azure-resource-manager/bicep/resource-declaration?WT.mc_id=MVP_319025#onlyifnotexists-decorator). |
| 13 | + |
| 14 | +## ✅ Benefits of Using @onlyIfNotExists |
| 15 | + |
| 16 | +✅ **Prevents Overwriting Critical Data**: Protects existing resources (like secrets with sensitive values) from being accidentally overwritten during redeployment. |
| 17 | + |
| 18 | +✅ **Idempotent Deployments**: Enables truly idempotent templates where multiple executions won't fail or cause unintended changes if resources already exist. |
| 19 | + |
| 20 | +✅ **Simplified Secret Management**: Perfect for one-time secret deployments where you want to set an initial value but never modify it through automation afterward. |
| 21 | + |
| 22 | +✅ **Reduces Deployment Errors**: Eliminates "resource already exists" conflicts in scenarios where you're uncertain whether a resource has been previously deployed. |
| 23 | + |
| 24 | +## ⚗️ Example: Key Vault Secret with @onlyIfNotExists |
| 25 | + |
| 26 | +This example demonstrates deploying an Azure Key Vault and a secret using the `@onlyIfNotExists()` decorator. The Key Vault will always be deployed (or updated), but the secret will **only be created if it doesn't already exist**. |
| 27 | + |
| 28 | +### Bicep Code Snippet |
| 29 | + |
| 30 | +```bicep |
| 31 | +@secure() |
| 32 | +param kvSecretValue string |
| 33 | +
|
| 34 | +// Deploy secret to the Key Vault using @onlyIfNotExists decorator |
| 35 | +@onlyIfNotExists() |
| 36 | +resource kvSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { |
| 37 | + name: '${keyVault.outputs.name}/mySecret' |
| 38 | + properties: { |
| 39 | + value: kvSecretValue |
| 40 | + } |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +### How It Works |
| 45 | + |
| 46 | +1. **First Deployment**: The secret `mySecret` doesn't exist, so it's created with the value you pass at deployment time |
| 47 | +2. **Subsequent Deployments**: The secret already exists with the same name, so deployment is skipped entirely - the existing value is preserved |
| 48 | +3. **Name-Based Check**: Only the secret name is checked; if a secret named `mySecret` exists, it won't be recreated regardless of its current value (check the secret version after two deployment runs to verify functionality.) |
| 49 | + |
| 50 | +### Full Template |
| 51 | + |
| 52 | +The complete `main.bicep` file includes: |
| 53 | + |
| 54 | +- Azure Key Vault deployment using the Azure Verified Modules (AVM) pattern |
| 55 | +- A secret resource with the `@onlyIfNotExists()` decorator |
| 56 | +- Metadata for resource documentation |
| 57 | +- Outputs for the Key Vault name, URI, and secret name |
| 58 | + |
| 59 | +### Scope Limitations |
| 60 | + |
| 61 | +The existence check is performed within the deployment scope (subscription, resource group, etc.). A resource in a different scope with the same name won't prevent creation. |
| 62 | + |
| 63 | +## 🚀 Deployment |
| 64 | + |
| 65 | +### Prerequisites |
| 66 | + |
| 67 | +- Azure subscription |
| 68 | +- Bicep CLI 0.38.0 or later |
| 69 | + |
| 70 | +### Deploy with Azure CLI |
| 71 | + |
| 72 | +```bash |
| 73 | +az group create --name rg-onlyIfNotExists-example --location uksouth |
| 74 | + |
| 75 | +az deployment group create \ |
| 76 | + --resource-group rg-onlyIfNotExists-example \ |
| 77 | + --template-file main.bicep \ |
| 78 | + --parameters kvSecretValue="<your-secret-value>" |
| 79 | +``` |
| 80 | + |
| 81 | +### Deploy with Azure PowerShell |
| 82 | + |
| 83 | +```powershell |
| 84 | +New-AzResourceGroup -Name rg-onlyIfNotExists-example -Location uksouth |
| 85 | +
|
| 86 | +New-AzResourceGroupDeployment ` |
| 87 | + -ResourceGroupName rg-onlyIfNotExists-example ` |
| 88 | + -TemplateFile main.bicep ` |
| 89 | + -kvSecretValue '<your-secret-value>' |
| 90 | +``` |
0 commit comments