diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml index 1418c30..8b8080f 100644 --- a/.github/workflows/mega-linter.yml +++ b/.github/workflows/mega-linter.yml @@ -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 @@ -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: | diff --git a/bicep-examples/consuming-modules/README.md b/bicep-examples/consuming-modules/README.md index d348920..71d4247 100644 --- a/bicep-examples/consuming-modules/README.md +++ b/bicep-examples/consuming-modules/README.md @@ -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 } } ``` @@ -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. diff --git a/bicep-examples/imports-exports/README.md b/bicep-examples/imports-exports/README.md new file mode 100644 index 0000000..02a0ae9 --- /dev/null +++ b/bicep-examples/imports-exports/README.md @@ -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" +``` \ No newline at end of file diff --git a/bicep-examples/imports-exports/main.bicep b/bicep-examples/imports-exports/main.bicep new file mode 100644 index 0000000..4f4f57a --- /dev/null +++ b/bicep-examples/imports-exports/main.bicep @@ -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' + } + ] + } + } +} diff --git a/bicep-examples/imports-exports/shared.bicep b/bicep-examples/imports-exports/shared.bicep new file mode 100644 index 0000000..687f540 --- /dev/null +++ b/bicep-examples/imports-exports/shared.bicep @@ -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'