Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
steps:
# Git Checkout
- name: Checkout Code
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
Expand All @@ -54,7 +54,7 @@ jobs:
# Upload MegaLinter artifacts
- name: Archive production artifacts
if: ${{ success() }} || ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: MegaLinter reports
path: |
Expand Down
22 changes: 9 additions & 13 deletions bicep-examples/consuming-modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ If you're new to Bicep understanding the different ways to consume modules can b

Please review the blog post to get an understanding on the pros & cons of each consumption method. These are based on real world experiences using all methods, straight from the battlefield.

## Public Bicep Registry
## Public Bicep Registry (Azure Verfieid Modules)

The public registry can be consumed directly from anywhere with ease and has quick adoption with no start up overhead as the modules are centrally stored by the team.

```javascript
module public_registry 'br/public:compute/function-app:2.0.1' = {
name: 'public_registry_example'
The concept of AVM allows these modules to accelerate teams to deploy with Bicep, using best practice & aligned to the Well-Architected Framework that is managed by Microsoft so you don't have to maintain the modules yourselves. Be sure to check out more on [AVM](https://azure.github.io/Azure-Verified-Modules/overview/introduction/).

```bicep
module KeyVault 'br/public:avm/res/key-vault/vault:0.7.0' = {
name: 'avm_exmple'
params: {
name: 'example-func-001'
name: 'kvName'
location: 'uksouth'
storageAccountName: 'stsomestorageaccount001'
storageAccountResourceGroup: 'rg-some-rg-here'
sku: 'standard'
enableSoftDelete: true
}
}
```
Expand Down Expand Up @@ -88,9 +90,3 @@ module inline_module 'modules/inline/customModule.bicep' = {
}
}
```

## Azure Verified Modules / Azure Bicep Public Registry

[AVM](https://azure.github.io/Azure-Verified-Modules/faq/#what-is-happening-to-existing-initiatives-like-carml-and-tfvm)

This is still in development at the time of writing. However, there is a new initiative by the IaC teams at Microsoft to present what good Infrastructure-as-Code looks like. The idea here will be these modules will accelerate teams to deploy with Bicep, using best practice & aligned to the Well-Architected Framework.
117 changes: 117 additions & 0 deletions bicep-examples/imports-exports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Azure Bicep - Imports and Exports

## Introduction

The import and export feature in Bicep allows you to reuse commonly used variables and types efficiently. Exports enable you to define variables that can be imported for use in other templates, while imports allow you to pull in pre-defined variables—eliminating the need to duplicate code across multiple Bicep files.

Instead of manually defining a variable in every new Bicep file, such as:

`var budgetAlertEmail = 'dan@rios.engineer'`

You can store this value centrally and simply import it into your template when needed.

This functionality extends beyond just variables (and types). It can be applied to various use cases, such as subscription IDs, service principal IDs, app registrations, and private DNS zone FQDNs and tons more. Helping maintain consistency and reducing repetitive code.

## 📃 Benefits of User Defined Types

✅ Centraliation: Allows you to define commonly repeated variables and user defined types in one file that many Bicep templates can reuse.

✅ Reduces repetition: Variables you may be repeating in each Bicep template can now be moved centrally, reducing repetition and streamlining templates.

✅ Resuability: The exports can now be used across multiple projects and templates allowing much greater resuability for standards and common values. This can also help reduce configuration errors.

## Export Examples

In the exports example, you can define what variables or types you want to be available to be imported by defining an @export() decorator next to them.

For example, a `shared.bicep` file could reside in the root of your Bicep folder within your repository, with these commonly used variables as an example:

```bicep
// shared.bicep with common vars
@export()
@description('The Primary Azure Region location')
var location = 'uksouth'

@export()
@description('Branch Office Public IP')
var branchOfficePublicIP = '82.110.72.90'
```

### Entra example:

```bicep
@export()
@description('Common Entra Security Group(s) for RBAC')
var entraSecurityGroups = {
SG_Cloud_Team: {
displayName: 'SG_Cloud_Team'
objectId: '11111111-1111-1111-1111-111111111111'
}
SG_Security_Team: {
displayName: 'SG_Security_Team'
objectId: '22222222-2222-2222-2222-222222222222'
}
SG_Dev_Team: {
displayName: 'SG_Dev_Team'
objectId: '33333333-3333-3333-3333-333333333333'
}
}
```
## Import Examples
### Entra ObjectId
```bicep
import * as shared from 'shared.bicep'

module rg 'br/public:avm/res/resources/resource-group:0.4.1' = {
...
roleAssignments: [
{
principalId: shared.entraSecurityGroups.SG_Cloud_Team.objectId // Using imported Entra Security Group Object ID
roleDefinitionIdOrName: 'Contributor'
}
]
```

### ACL IP Example:
```bicep
import * as shared from 'shared.bicep'
// or you can only import the required variable vs all available via
// import { branchOfficePublicIP } as branchOfficePublicIP from 'shared.bicep' as an example
module keyVault 'br/public:avm/res/key-vault/vault:0.12.1' = {
....
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: [
{
value: shared.branchOfficePublicIP // using central import value from shared.bicep
action: 'Allow'
}
]
}
}
```

## 🚀 Deployment

> [!NOTE]
> You need to have a resource group deployed before trying this out.

In VisualStudio Code open a terminal and run:

CLI

```bash
az login
az account set --subscription 'subscription name or id'
az deployment group create -g 'your-rg' --confirm-with-what-if -f '.\main.bicep' -p 'main.bicepparam'
```

or PowerShell

```powershell
Connect-AzAccount
Set-AzContext -Subscription "subscription name or id"
New-AzResourceGroupDeployment -Confirm -ResourceGroup "your-rg" -TemplateFile "main.bicep" -TemplateParameterFile "main.bicepparam"
```
49 changes: 49 additions & 0 deletions bicep-examples/imports-exports/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

targetScope = 'subscription'

// MARK: Imports
import * as shared from 'shared.bicep'
// import { location } as location from 'shared.bicep' to only import a specific var or type from the file.

// MARK: Variables
var location = shared.location // using central value from shared.bicep
var rgName = 'rg-bicepify-demo'
var keyVaultName = 'kv-bicepify-demo'

// MARK: RBAC Entra import example
module resourceGroupShared 'br/public:avm/res/resources/resource-group:0.4.1' = {
name: '${uniqueString(deployment().name, location)}-${rgName}'
params:{
name: rgName
location: location
roleAssignments: [
{
principalId: shared.entraSecurityGroups.SG_Cloud_Team.objectId // Using imported Entra Security Group Object ID
roleDefinitionIdOrName: 'Contributor'
}
]
}
}

// MARK: Key Vault
module keyVault 'br/public:avm/res/key-vault/vault:0.12.1' = {
name: '${uniqueString(deployment().name, location)}-${keyVaultName}'
scope: resourceGroup(rgName)
params: {
name: keyVaultName
location: location
sku: 'standard'
publicNetworkAccess: 'Disabled' // Selected Networking
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: [
{
value: shared.branchOfficePublicIP // using central import value from shared.bicep
action: 'Allow'
}
]
}
}
}
28 changes: 28 additions & 0 deletions bicep-examples/imports-exports/shared.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@export()
@description('Common Entra Security Group(s) for RBAC')
var entraSecurityGroups = {
SG_Cloud_Team: {
displayName: 'SG_Cloud_Team'
objectId: '11111111-1111-1111-1111-111111111111'
}
SG_Security_Team: {
displayName: 'SG_Security_Team'
objectId: '22222222-2222-2222-2222-222222222222'
}
SG_Dev_Team: {
displayName: 'SG_Dev_Team'
objectId: '33333333-3333-3333-3333-333333333333'
}
}

@export()
@description('The Primary Azure Region location')
var location = 'uksouth'

@export()
@description('Branch Office Public IP')
var branchOfficePublicIP = '82.110.72.90'

@export()
@description('Azure Websites Private DNS Zone FQDN')
var azureWebsitesPrivateDnsZone = 'privatelink.azurewebsites.net'