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/README.md b/bicep-examples/lambda-functions/README.md new file mode 100644 index 0000000..f219c67 --- /dev/null +++ b/bicep-examples/lambda-functions/README.md @@ -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 ` => ` 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" +``` diff --git a/bicep-examples/lambda-functions/bicepconfig.json b/bicep-examples/lambda-functions/bicepconfig.json new file mode 100644 index 0000000..9fd42b1 --- /dev/null +++ b/bicep-examples/lambda-functions/bicepconfig.json @@ -0,0 +1,14 @@ +{ + "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..092a649 --- /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: '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') 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. 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