Insight Tech APAC Blog Logo

Import and Export feature across Bicep Templates

stephentulp
December 22, 2023

3 minutes to read

Bicep Import Export

Introduction

One of the guiding principles of software development is adopting the “Don’t repeat yourself” (DRY) approach to writing IaC which aims to reduce repetition of code by replacing it with abstractions. The export() and import capabilities in Bicep are experimental features that can help us achieve this goal.

The @export() decorator is used to indicate that a given value can be imported by another file across type, variable and function statements, while the import statement enables the exported values to be used across multiple Bicep templates.

The @export() decorator syntax is outlined below.

@export()
<statement_to_export>

Then we have a couple of ways that we can import these into other Bicep templates.

  • Import functionality to another Bicep file
import {<symbol_name>, <symbol_name>, ...} from '<bicep_file_name>'
  • Import using an alias to rename the symbol
import {<symbol_name> as <alias_name>, ...} from '<bicep_file_name>'
  • Using a wildcard to import all exported values
import * as <alias_name> from '<bicep_file_name>'

Bicep CLI version 0.23.X or higher is required to use the Import/Export features and the experimental feature compileTimeImports must be enabled from the Bicep config file.

Example Use Case

Lets have a look at an example where we will use both the export() and import feature across some Azure Landing Zone templates.

Export

A Bicep templates called shared.bicep is used that has the exported values defined as locPrefixes, tagsType, commonResourceGroups and namePrefixes, these values can now be imported into other Bicep templates.

@export()
var locPrefixes = {
  australiaEast: 'syd'
}

@export()
type tagsType = {
  environment: 'Platform Production' | 'prd' | 'dev' | 'test'
  applicationName: string
  owner: string
  criticality: 'Tier0' | 'Tier1' | 'Tier2' | 'Tier3'
  costCenter: string
  contactEmail: string
  dataClassification: 'Internal' | 'Confidential' | 'Secret' | 'Top Secret'
  iac: 'Bicep'
  *: string
}

@export()
var commonResourceGroups = ['ascExportRG', 'alertsRG', 'networkWatcherRG']

@export()
var namePrefixes = {
  platform: 'plat'
  platformIdam: 'idam'
  resourceGroup: 'arg'
  keyVault: 'akv'
}

@export()
var identityPrefixes = {
  argPrefix: toLower('${namePrefixes.resourceGroup}-${locPrefixes.australiaEast}-${namePrefixes.platform}-${namePrefixes.platformIdam}')
  akvPrefix: toLower('${namePrefixes.keyVault}${locPrefixes.australiaEast}${namePrefixes.platformIdam}')
}

Import

We can now import these values into the platformIdentity.bicep template, I have only included parts of the template relevant. We are using an alias for identityPrefixes as prefixes to help build out names for resources.

import { identityPrefixes as prefixes , tagsType, commonResourceGroups } from '../../configuration/shared/shared.bicep'

@description('The Azure Region to deploy the resources into.')
param location string = deployment().location

@description('Tags that will be applied to all resources in this module.')
param tags tagsType

var maxNameLength = 24
var uniquenameUntrim = '${prefixes.akvPrefix}${uniqueString(subscriptionId)}'

var resourceGroups = {
  security: '${prefixes.argPrefix}-security'
}

var resourceNames = {
  keyVault: (length(uniquenameUntrim) > maxNameLength ? substring(uniquenameUntrim, 0, maxNameLength) : uniquenameUntrim)
}

// Module: Resource Groups (Common)
module sharedResourceGroups '../../modules/resourceGroup/resourceGroups.bicep' = [for item in commonResourceGroups: {
  name: item
  scope: subscription(subscriptionId)
  params: {
    resourceGroupNames: commonResourceGroups
    location: location
    tags: tags
  }
}]

Conclusion

The Import and Export decorators in Bicep are a powerful feature that allows for greater modularity and reusability in your Bicep templates. By understanding and utilizing this feature, you can create more efficient and maintainable Bicep templates and remove the need to repeat values across templates.

Further Reading