How to use the `this` namepsace in Bicep to check resources

Learn how to prevent common deployment failures from immutable property changes

How to use the `this` namepsace in Bicep to check resources

Often you face challenges when deploying Azure resources against existing one: templates behave differently for new resources versus existing ones.

Some properties can only be set during creation, whilst others should be preserved during updates. You can't always know which scenario will happen until runtime. The this namespace solves this problem by enabling runtime checks and conditional logic based on the resource's existence.

In this guide, you will:

  • Use this.exists() to determine if a resource already exists at deployment time.
  • Access existing resource properties with this.existingResource().
  • Set different values for new resources versus updates.
  • Enable the experimental this namespace feature in your Bicep environment.

Prerequisites

Before you dive in, you need to have:

  • Bicep CLI nightly build installed.
  • A bicepconfig.json file in your project.

To install the nightly CLI build, you can use:

iex "& { $(irm https://aka.ms/bicep/nightly-cli.ps1) }"

You can enable the experimental feature by creating or updating your bicepconfig.json file in your project root:

{
  "experimentalFeaturesEnabled": {
    "thisNamespace": true
  }
}

Check resource existence

The this.exists() function is newly introduced in Bicep and returns a boolean value. This boolean value indicates whether the resource already exists in Azure at deployment time.

You can use this.exists() to set different default values for new versus existing resources:

resource storage 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    // New storage accounts default to disabled public access
    // Existing accounts keep their current configuration
    allowBlobPublicAccess: this.exists() ? false : true
  }
}

The function only works at deployment time, not compilation time. Azure examines the current state of your subscription and then returns the result. The Bicep compiler translates this.exists() to [not(empty(target('full')))] in the generated ARM template.

Access existing resource properties

The other function newly introduced is the this.existingResource() function. This returns the complete resource object if it exists, or returns null if it doesn't. With this function, you can read the current property values and preserve them during updates.

By combining this.existingResource() with the safe navigation operator (?.), you can access nested properties without causing errors:

resource storage 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    // Preserve the existing retention policy if it exists
    deleteRetentionPolicy: this.existingResource().?properties.deleteRetentionPolicy
  }
}

Using the ?. operator prevents Azure from throwing errors when the resource doesn't exist. If this.existingResource() returns null, the whole expression evaluates to null.

Combine existence checks with property access

It's also possible to use both in combination for more complex scenarios. The following pattern is useful when you want to apply different configurations based on the current resource state.

In the following template, both this.exists() and this.existingResource() are used:

resource storage 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: 'mystorageaccount'
  location: 'westus'
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    // New accounts get secure defaults
    // Existing accounts preserve their current settings
    allowBlobPublicAccess: this.exists() 
      ? this.existingResource().?properties.allowBlobPublicAccess 
      : false
  }
  
  resource fileService 'fileServices' = {
    name: 'default'
    properties: {
      // Always preserve existing retention policies
      shareDeleteRetentionPolicy: this.existingResource().?properties.shareDeleteRetentionPolicy
    }
    
    resource fileShare 'shares' = {
      name: 'exampleshare'
      properties: {
        // Keep the current access tier if it exists
        accessTier: this.existingResource().?properties.accessTier
      }
    }
  }
}

Using the above pattern works with nested resources. Each resource independently checks the existence and accesses the current state. The template adapts to the presence or absence of the parent storage account and its nested resources.

Understand function limitations

The this namespace functions have specific limitations (or constraints) that you should understand before implementing.

These functions only work inside resource property blocks. You cannot use them in:

  • Resource names
  • Module parameters
  • Top-level loop expressions

This restriction exists because the functions depend on the resource context.

// ✓ Valid - inside properties block
resource storage 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: storageAccountName
  properties: {
    allowBlobPublicAccess: this.exists() ? false : true
  }
}

// ✗ Invalid - in resource name
resource storage 'Microsoft.Storage/storageAccounts@2025-06-01' = {
  name: this.exists() ? 'existing' : 'new'  // Error
  properties: {}
}

Summary

This quick guide demonstrated how to use the this namespace in Bicep templates. You've covered:

  • Enable the experimental feature thisNamespace in the bicepconfig.json file.
  • Used this.exists() to determine if resources already exist at deployment time.
  • Accessed existing configurations with this.existingResource() and safe navigation operators
  • Implemented different behaviors for new versus existing resources

By leveraging the this namespace, you eliminate the need for separate create and update templates while preventing deployment failures from immutable property changes. To learn more, check out the official documentation in the Bicep repository.