From 44950547bb4bfe91572deb08c6a4b2ba4a26aba3 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:23:21 +0100 Subject: [PATCH 1/7] Lambda Function Example --- .../lambda-functions/bicepconfig.json | 16 +++++++ bicep-examples/lambda-functions/main.bicep | 48 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 bicep-examples/lambda-functions/bicepconfig.json create mode 100644 bicep-examples/lambda-functions/main.bicep diff --git a/bicep-examples/lambda-functions/bicepconfig.json b/bicep-examples/lambda-functions/bicepconfig.json new file mode 100644 index 0000000..c366696 --- /dev/null +++ b/bicep-examples/lambda-functions/bicepconfig.json @@ -0,0 +1,16 @@ +{ + // See https://aka.ms/bicep/config for more information on Bicep configuration options + // Press CTRL+SPACE/CMD+SPACE at any location to see Intellisense suggestions + "analyzers": { + "core": { + "rules": { + "no-unused-params": { + "level": "warning" + } + } + } + }, + "experimentalFeaturesEnabled": { + "symbolicNameCodegen": true +} +} \ No newline at end of file diff --git a/bicep-examples/lambda-functions/main.bicep b/bicep-examples/lambda-functions/main.bicep new file mode 100644 index 0000000..e8bdce6 --- /dev/null +++ b/bicep-examples/lambda-functions/main.bicep @@ -0,0 +1,48 @@ +targetScope = 'resourceGroup' + +metadata name = 'Lambda Function Examples' +metadata description = 'Showcasing Azure Bicep Lamba Functions' +metadata owner = 'func@example.com' + +@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: 'keyv-${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: 'keyvault-0-1234567890' + sku: 'standard' + softdelete: 'true' + } + { + keyvaultName: 'keyvault-1-1234567890' + sku: 'premium' + softdelete: 'true' + } + { + keyvaultName: 'keyvault-2-1234567890' + sku: 'premium' + softdelete: 'true' + } + { + keyvaultName: 'keyvault-3-1234567890' + 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') From e5979fe784d5b291a3aff98d1558bdac9f12394a Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:26:02 +0100 Subject: [PATCH 2/7] Spelling Corrections --- bicep-examples/lambda-functions/README.md | 0 bicep-examples/shared-variable-file-pattern/README.md | 2 +- bicep-examples/test-framework/README.md | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 bicep-examples/lambda-functions/README.md diff --git a/bicep-examples/lambda-functions/README.md b/bicep-examples/lambda-functions/README.md new file mode 100644 index 0000000..e69de29 diff --git a/bicep-examples/shared-variable-file-pattern/README.md b/bicep-examples/shared-variable-file-pattern/README.md index 259c55e..b72e502 100644 --- a/bicep-examples/shared-variable-file-pattern/README.md +++ b/bicep-examples/shared-variable-file-pattern/README.md @@ -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. diff --git a/bicep-examples/test-framework/README.md b/bicep-examples/test-framework/README.md index 81ce566..d179b8d 100644 --- a/bicep-examples/test-framework/README.md +++ b/bicep-examples/test-framework/README.md @@ -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 From 83a5a8d2a182b2313ee6098695132e36f5960f7e Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:59:39 +0100 Subject: [PATCH 3/7] README draft --- bicep-examples/lambda-functions/README.md | 60 +++++++++++++++++++++++ bicep-examples/loops/README.md | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/bicep-examples/lambda-functions/README.md b/bicep-examples/lambda-functions/README.md index e69de29..b1daf3d 100644 --- a/bicep-examples/lambda-functions/README.md +++ b/bicep-examples/lambda-functions/README.md @@ -0,0 +1,60 @@ +# 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 ` => ` 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') +``` + +## 🚀 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" +``` diff --git a/bicep-examples/loops/README.md b/bicep-examples/loops/README.md index 557afde..3b943e0 100644 --- a/bicep-examples/loops/README.md +++ b/bicep-examples/loops/README.md @@ -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. From f13e19566261ad8c5eae988adf5623167bd6ba93 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Wed, 1 May 2024 16:44:49 +0100 Subject: [PATCH 4/7] Update main.bicep Unique keyvault string Example readme updated --- bicep-examples/lambda-functions/main.bicep | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bicep-examples/lambda-functions/main.bicep b/bicep-examples/lambda-functions/main.bicep index e8bdce6..092a649 100644 --- a/bicep-examples/lambda-functions/main.bicep +++ b/bicep-examples/lambda-functions/main.bicep @@ -11,7 +11,7 @@ param location string = 'uksouth' 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: 'keyv-${i}-${uniqueString(subscription().id)}' + name: 'kv-${i}-${uniqueString(subscription().id)}' location: location sku: 'standard' } @@ -23,22 +23,22 @@ output keyVaultNames array = map(keyVaults, keyvault => keyvault.outputs.name) // filter function var kvProperties = [ { - keyvaultName: 'keyvault-0-1234567890' + keyvaultName: 'kv-${uniqueString(resourceGroup().id)}' sku: 'standard' softdelete: 'true' } { - keyvaultName: 'keyvault-1-1234567890' + keyvaultName: 'kv-${uniqueString(resourceGroup().id)}' sku: 'premium' softdelete: 'true' } { - keyvaultName: 'keyvault-2-1234567890' + keyvaultName: 'kv-${uniqueString(resourceGroup().id)}' sku: 'premium' softdelete: 'true' } { - keyvaultName: 'keyvault-3-1234567890' + keyvaultName: 'kv-${uniqueString(resourceGroup().id)}' sku: 'premium' softdelete: 'false' purge: 'off' From 65f67004f80152b998ac42a250a5187f095e54d8 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Wed, 1 May 2024 16:45:48 +0100 Subject: [PATCH 5/7] Update README.md --- bicep-examples/lambda-functions/README.md | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/bicep-examples/lambda-functions/README.md b/bicep-examples/lambda-functions/README.md index b1daf3d..3073873 100644 --- a/bicep-examples/lambda-functions/README.md +++ b/bicep-examples/lambda-functions/README.md @@ -36,6 +36,43 @@ Filter 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] From 6daccf29d7e05e675f005a2d7f9bab6b6dcec609 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Wed, 1 May 2024 16:46:45 +0100 Subject: [PATCH 6/7] Update README.md --- bicep-examples/lambda-functions/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bicep-examples/lambda-functions/README.md b/bicep-examples/lambda-functions/README.md index 3073873..f219c67 100644 --- a/bicep-examples/lambda-functions/README.md +++ b/bicep-examples/lambda-functions/README.md @@ -22,21 +22,21 @@ In the first example within the `main.bicep` file, there is a `map` expression f 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 +#### 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 +#### 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 +#### Output example ```json "outputs": { From 7423fa41fbb29ddad9a1d1a888bf547ff10771e3 Mon Sep 17 00:00:00 2001 From: Dan Rios <36534747+riosengineer@users.noreply.github.com> Date: Wed, 1 May 2024 17:03:15 +0100 Subject: [PATCH 7/7] megalinter errors fix --- .github/workflows/mega-linter.yml | 2 +- bicep-examples/lambda-functions/bicepconfig.json | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index e3090ff..aba8da3 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -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 diff --git a/bicep-examples/lambda-functions/bicepconfig.json b/bicep-examples/lambda-functions/bicepconfig.json index c366696..9fd42b1 100644 --- a/bicep-examples/lambda-functions/bicepconfig.json +++ b/bicep-examples/lambda-functions/bicepconfig.json @@ -1,6 +1,4 @@ { - // See https://aka.ms/bicep/config for more information on Bicep configuration options - // Press CTRL+SPACE/CMD+SPACE at any location to see Intellisense suggestions "analyzers": { "core": { "rules": {