Skip to content

Commit

Permalink
Lambda functions / expression examples (#17)
Browse files Browse the repository at this point in the history
Azure Bicep lambda function/express example with map & filter showcasing with key vault resource. Supporting readme doc for explanation and deployment steps.
  • Loading branch information
riosengineer authored May 1, 2024
1 parent a6aefb7 commit 4ee3b5c
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ADD YOUR CUSTOM ENV VARIABLES HERE OR DEFINE THEM IN A FILE .mega-linter.yml AT THE ROOT OF YOUR REPOSITORY
DISABLE: COPYPASTE,SPELL # Uncomment to disable copy-paste and spell checks
DISABLE_LINTERS: YAML_V8R,YAML_YAMLLINT,YAML_PRETTIER,REPOSITORY_CHECKOV,POWERSHELL_POWERSHELL,ACTION_ACTIONLINT
DISABLE_LINTERS: YAML_V8R,YAML_YAMLLINT,YAML_PRETTIER,REPOSITORY_CHECKOV,POWERSHELL_POWERSHELL,ACTION_ACTIONLINT,REPOSITORY_GITLEAKS
REPOSITORY_KICS_DISABLE_ERRORS: true

# Upload MegaLinter artifacts
Expand Down
97 changes: 97 additions & 0 deletions bicep-examples/lambda-functions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Azure Bicep - Lambda Functions

## Introduction

Lambda Functions in Azure Bicep can be a good way to create an argument based on multiple parameters. These are defined as `<lambda var> => <expression>` and consist of multiple functions such as `filter()` `map()` `sort()` `reduce()` `toObject()`.

This can be useful when wanting to output an array of Azure resource names for example. This example will be expanded over time to include more real world use cases.

However, it is worth noting there are some [limitations](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-lambda?WT.mc_id=MVP_319025#limitations) with lambda functions.

You can read more from the official Microsoft Learn documentation on Lambda Functions [here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions-lambda?WT.mc_id=MVP_319025).

## 📃 Benefits of Lambda Functions

1. ✅ Abstraction. Allows you to define custom data structures for your use cases.

2. ✅ Consistency with other programming languages. Many popular languages use the `=>` to represent the functions so it's familiar for devs.

## Lambda Function Examples

In the first example within the `main.bicep` file, there is a `map` expression from an array output. Using the `map` expression in this example you're able to extrapolate all the Key vault resource names from a loop in the output.

In the second example within the `main.bicep` file, there is a `filter` expression from an array output. This enables you to manipulate the array and filter the output using the `filter` expression to only show those that match your expression statement in the output.

#### Map

```javascript
@description('Output all Key Vault names from the loop using a map function expression.')
output keyVaultNames array = map(keyVaults, keyvault => keyvault.outputs.name)
```

#### Filter

```javascript
@description('Output all Key Vaults with premium SKUs that have soft delete disabled.')
output kvFilter array = filter(kvProperties, kv => kv.sku == 'premium' && kv.softdelete == 'true')
```

#### Output example

```json
"outputs": {
"keyVaultNames": {
"type": "Array",
"value": [
"kv-0-7jf67vploiowy",
"kv-1-7jf67vploiowy",
"kv-2-7jf67vploiowy",
"kv-3-7jf67vploiowy",
"kv-4-7jf67vploiowy",
"kv-5-7jf67vploiowy",
"kv-6-7jf67vploiowy",
"kv-7-7jf67vploiowy",
"kv-8-7jf67vploiowy",
"kv-9-7jf67vploiowy"
]
},
"kvFilter": {
"type": "Array",
"value": [
{
"keyvaultName": "kv-of3g6trcnh2ak",
"sku": "premium",
"softdelete": "true"
},
{
"keyvaultName": "kv-of3g6trcnh2ak",
"sku": "premium",
"softdelete": "true"
}
]
}
},
```

## 🚀 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'
```

or PowerShell

```powershell
Connect-AzAccount
Set-AzContext -Subscription "subscription name or id"
New-AzResourceGroupDeployment -Confirm -ResourceGroup "your-rg -TemplateFile "main.bicep"
```
14 changes: 14 additions & 0 deletions bicep-examples/lambda-functions/bicepconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"analyzers": {
"core": {
"rules": {
"no-unused-params": {
"level": "warning"
}
}
}
},
"experimentalFeaturesEnabled": {
"symbolicNameCodegen": true
}
}
48 changes: 48 additions & 0 deletions bicep-examples/lambda-functions/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
targetScope = 'resourceGroup'

metadata name = 'Lambda Function Examples'
metadata description = 'Showcasing Azure Bicep Lamba Functions'
metadata owner = '[email protected]'

@description('Azure region for deployments chosen from the resource group.')
param location string = 'uksouth'

// map function
module keyVaults 'br/public:avm/res/key-vault/vault:0.4.0' = [ for i in range(0,10): {
name: 'kvdeploy-${i}${uniqueString(resourceGroup().id)}'
params: {
name: 'kv-${i}-${uniqueString(subscription().id)}'
location: location
sku: 'standard'
}
}]

@description('Output all Key Vault names from the loop using a map function expression.')
output keyVaultNames array = map(keyVaults, keyvault => keyvault.outputs.name)

// filter function
var kvProperties = [
{
keyvaultName: 'kv-${uniqueString(resourceGroup().id)}'
sku: 'standard'
softdelete: 'true'
}
{
keyvaultName: 'kv-${uniqueString(resourceGroup().id)}'
sku: 'premium'
softdelete: 'true'
}
{
keyvaultName: 'kv-${uniqueString(resourceGroup().id)}'
sku: 'premium'
softdelete: 'true'
}
{
keyvaultName: 'kv-${uniqueString(resourceGroup().id)}'
sku: 'premium'
softdelete: 'false'
purge: 'off'
}
]
@description('Output all Key Vaults with premium SKUs that have soft delete disabled.')
output kvFilter array = filter(kvProperties, kv => kv.sku == 'premium' && kv.softdelete == 'true')
2 changes: 1 addition & 1 deletion bicep-examples/loops/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ You can go through the Microsoft Learn training module for this which is great [

## For Loop Example

In the basic example within the `main.bicep` file, we can using the `for` property to state for each `vnet` resource, loop through and create the virtual network with subnets.
In the basic example within the `main.bicep` file, we can use the `for` property to state for each `vnet` resource, loop through and create the virtual network with subnets.

As the variable (refer to the `main.bicep` file) also contains the required subnets, we're further looping the sub-property within the `vnet` to loop for each `subnet` within the `vnet` as it deploys.

Expand Down
2 changes: 1 addition & 1 deletion bicep-examples/shared-variable-file-pattern/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Building on the Microsoft Documentation on this I've expanded and created some more examples where this can be useful for you or your organisation. I've broken these down into three example chunks. I would advise first going over the documentation to familiarise yourself with the concept here:

[MS Learn - Shared variable file pattern](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/patterns-shared-variable-file)
[MS Learn - Shared variable file pattern](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/patterns-shared-variable-file?WT.mc_id=MVP_319025)

Each example should be simple to understand and translate to real world scenarios these could help you with.

Expand Down
6 changes: 3 additions & 3 deletions bicep-examples/test-framework/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ In the example `main.bicep`, we can see the `locationUk` assert statement is use

For the testing file we're able to draw on our assertion statements to conclude if they match the parameter values that we want to validate with from their true or false statements.

In the example we can see a successful test block and a failure test block for demostatration purposes.
In the example we can see a successful test block and a failure test block for demonstration purposes.

If we are to try and deploy a resource in the `northeurope` region the test block would validate that it does not match the boolen true/false statement from the assertion and fail the test.
If we are to try and deploy a resource in the `northeurope` region the test block would validate that it does not match the boolean true/false statement from the assertion and fail the test.

## 💡 How to get started

Make sure your Azure Bicep version is up to date.

Azure CLI (recomended approach as Bicep CLI is built-in):
Azure CLI (recommended approach as Bicep CLI is built-in):

```bash
az bicep upgrade
Expand Down

0 comments on commit 4ee3b5c

Please sign in to comment.