Saturday, February 11, 2023

Azure Bicep

 Install VS extension - Bicep


AZ powershell - set exec policy unrestricted Install-module az allowclobber -scope currentuser

Bicep structure and concepts

  • parameters (param)
  • variables (var)
  • resource declarations
  • existing resources
  • parent/child resource relationship
  • modules/ reusable
  • dependencies
  • outputs
  • loops
  • conditions
  • scope

Deploying Bicep code

sql
Connect-azaccount Get-azsubscription Set-azcontext -subscriptionid xxxxx Get-azcontext New-azsubscriptiondeployment or new-azmanagementgroupdeployment New-azresourcegroupdeployment -name Rgtest -resourcegroupname decomrg -templatefile c:\path\main.bicep

Training resources

Variables

javascript
var storageAccountSkuName = (environmentType == 'prod') ? 'Standard_GRS' : 'Standard_LRS' var appServicePlanSkuName = (environmentType == 'prod') ? 'P2V3' : 'F1'

Installing Bicep

choco install bicep
python
winget install -e --id Microsoft.Bicep

Installing Bicep CLI

bash
# Create the install folder $installPath = "$env:USERPROFILE\.bicep" $installDir = New-Item -ItemType Directory -Path $installPath -Force $installDir.Attributes += 'Hidden' # Fetch the latest Bicep CLI binary (New-Object Net.WebClient).DownloadFile("https://github.com/Azure/bicep/releases/latest/download/bicep-win-x64.exe", "$installPath\bicep.exe") # Add bicep to your PATH $currentPath = (Get-Item -path "HKCU:\Environment" ).GetValue('Path', '', 'DoNotExpandEnvironmentNames') if (-not $currentPath.Contains("%USERPROFILE%\.bicep")) { setx PATH ($currentPath + ";%USERPROFILE%\.bicep") } if (-not $env:path.Contains($installPath)) { $env:path += ";$installPath" } # Verify you can now access the 'bicep' command. bicep --help # Done!

Azure Architecture Center

Tips & Tricks

  • Front door is considered a difficult resource to create in Bicep
  • Bicep Build and Deployment

    The following steps are required to build and deploy the module:

    1. Create an Azure resource group using the New-AzResourceGroup command.
    sql
    New-AzResourceGroup -Name 'Bicep-modules-01' -Location 'westus' -Force
    1. Define the deployment parameters in a hash table.
    makefile
    @Parameters = @{ Name ='"ainDeployment" + (get-date).ToString("yyyyMMddHHmmss") TemplateFile = '01 Use modules.bicep' ResourceGroupName = 'Bicep-Modules-01' appServiceAppName = 'bicepmodulExample' }
    1. Deploy the resources using the New-ResourceGroupDeployment command.
    sql
    New-ResourceGroupDeployment @Parameters -verbose

    It's also important to follow a naming convention for Azure services. You can find more information on this topic at the following links:





  • Azure Service Abbreviations

    https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations

    Microsoft's Bicep project offers a naming convention open-source tool that can be deployed in different ways, such as a container or web app on a basic tier SKU, or hosted as a docker image locally. Please refer to the GitHub repository with Creative Commons Attribution to deploy the tool for personal reference while planning naming convention for different resources in Azure as there are bunch of resources in Azure with text length and text type limitations. I have deployed https://github.com/pchettri3/AZNamingCAF as web apps using GitHub action and GitHub pipeline. AS recommended in the Grepo. I had to create SP with secrets like AZUREAPPSERVICE_PUBLISHPROFILE, Azure Credentials, Azure_webapp_name and published profile to successfully complete the deployment on web app.

    The following example skips the specified number of elements in the array, and the specified number of characters in a string.

    Param

    testArray array = [

      'one'

      'two'

      'three'

    ]

    param elementsToSkip int = 2

    param testString string = 'one two three'

    param charactersToSkip int = 4


    output arrayOutput array = skip(testArray, elementsToSkip)

    output stringOutput string = skip(testString, charactersToSkip)


    SPLIT

    param firstString string = 'one,two,three'

    param secondString string = 'one;two,three'

    var

    delimiters = [

      ','

      ';'

    ]

    output

    firstOutput array = split(firstString, ',')

    output secondOutput array = split(secondString, delimiters)

    https://aka.ms/learnlive-2022405A

    From Barbara Forbes video module -


  •  Object


    Array

    Decorators




  • Good idea to have a parameter json file for each environment


  • Override with parameter file


    Az deployment group create --template-file main. Bicep --parameter parameters.json appservicePlanInstanceCount = 5 (highest priority overwriting at deployment)

    @secure decorator if you really need to use secrets directly


    Avoid using parameters file for secrets and output for secrets

    Integrate with KV and can be used in parameter file if used with KV



    --enabled-for-template-deployment for Keyvault secret





  • The Bicep language also provides features such as split and skip for manipulating arrays and strings. You can find more information on this topic at the following link: Azure Learn Live 2022405A

    It's a good idea to have a parameter JSON file for each environment, which can be used to override values in the main deployment file. To deploy the module using a parameter file, you can use the following command:

    sql
    Az deployment group create --template-file main.bicep --parameter parameters.json appservicePlanInstanceCount = 5 (highest priority overwriting at deployment)

    Note that it's recommended to use the @secure decorator if you need to use secrets directly in your Bicep code. It's also important to avoid using parameters files for secrets and outputs for secrets. Instead, you can integrate with Azure Key Vault and use it in your parameter file if needed.

    Deploying Azure Resources with Bicep

    Deploying Keyvault secrets

    To deploy Keyvault secrets with --enabled-for-template-deployment flag, use the following command:

    css
    az keyvault secret set --vault-name <vault_name> --name <secret_name> --value <secret_value> --enabled-for-template-deployment

    Deploying Azure Resources with Bicep

    We will use the following variables in the deployment script:

    makefile
    resourceGroupName=$(az group list --query "[].{name:name}" --output tsv) deploymentName="parameterfiledeployment" templateFile="webApp.bicep" templateParameterFile="webApp.parameters.json"

    We will also use the following environment configuration map to configure the deployment:

    css
    var environmentConfigurationMap = { Production: { appServicePlan: { sku: { name: 'P2V3' capacity: 3 } } storageAccount: { sku: { name: 'ZRS' } } } Test: { appServicePlan: { sku: { name: 'S2' capacity: 1 } } storageAccount: { sku: { name: 'LRS' } vnet : { name: replace(names.outputs.resourceNameShort, '[PC]', 'vnetp') addressPrefix: '10.0.0.0/20' snet : { [for i in range(1, number): { name: 'subnet-${i}' properties: { addressPrefix: '10.0.${i}.0/24' } }] } } } } }

    To connect to Azure, use the following commands:

    sql
    Connect-AzAccount $context = Get-AzSubscription -SubscriptionId 0bc16f10-xxxxxx Set-AzContext $context Set-AzDefault -ResourceGroupName learn-635-a627-2cfd3xxxxxx

    If you encounter the error New-AzResourceGroupDeployment: Cannot retrieve the dynamic parameters for the cmdlet. Cannot find path ‘.json’ because it does not exist, you can fix it by installing the vscode package with chocolatey by running the following commands:

    sql
    Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) choco install vscode

    Deploying Resources Conditionally with Bicep

    We can deploy resources conditionally using Bicep. You can refer to the article [Use Bicep to deploy your Azure infrastructure as code Ep4: Build flexible Bicep templates by using conditions and loops](https://docs

    Deploy to Azure using PowerShell Module with Splatting

    To deploy resources to Azure using the PowerShell module, you can use the New-AzResourceGroupDeployment cmdlet with the @parameters splatting technique. To deploy the environment to production, you can use the following code:

    sql
    New-AzResourceGroupDeployment @parameters -environment production -verbose

    Deploying Azure Infrastructure as Code using Bicep

    You can use Bicep to deploy your Azure infrastructure as code. To build flexible Bicep templates, you can use conditions and loops. The Microsoft Learn course "Use Bicep to deploy your Azure infrastructure as code" has an episode that covers this topic in detail.

    Using For Loop in Bicep

    In Bicep, you can use the for loop to repeat the same operations multiple times. The range of the loop can start from 0 or any other number.

    Using Conditions in Bicep

    Conditions can be used in Bicep to make decisions based on certain conditions. For example, you can use a condition to deploy a SQL database only if the environment is production, and not deploy it otherwise.

    Controlling Loop Execution with @batchsize

    In Bicep, you can control the execution of a loop by using the @batchsize parameter.

    Connecting to the Azure Account and Subscription

    To deploy resources to Azure using the PowerShell module, you need to connect to your Azure account and subscription. You can do this using the following code:

    perl
    # Connect to the Azure account and subscription connect-azaccount # Get Context and set the context for the deployment $context = get-azsubscription -subscriptionName 'xxxx' set-azcontext $context

    Deploying Resources

    Once you are connected to your Azure account and subscription, you can deploy resources using the New-AzResourceGroupDeployment cmdlet. You can use splatting to assign the parameters for the deployment, as shown in the following code:

    sql
    # Create the main resource group if needed ## New-AzResourceGroup -name 'rrr' -location 'location' -force # Splat expression to assign parameters for deployment $Parameters = @{ Name = "deploymentName"+ (get-date).ToString("yyyyMMddHHmmss") TemplateFile = 'Name of the main templaete file' TemplateParameterFile = "env specific template parameter file " } New-AzResourceGroupDeployment @parameters -verbose

    Using Template Specs in Bicep

    In Bicep, you can use template specs to publish libraries of reusable infrastructure code. Microsoft Learn has a course on this topic, "Use Bicep to deploy your Azure infrastructure as code".

    YAML in Bicep

    Bicep supports YAML as a format for writing templates.

    Awesome Azure Bicep Resource

    There are many great resources available for learning about Azure Bicep. Here are some of the best:






Deploy to Azure powershell module with splatting . Ps1



Information on Azure Naming Tool

Azure Naming Tool is a project developed by Microsoft to help organizations adopt a consistent and standardized naming convention for their Azure resources. The tool generates names for resources based on a set of predefined naming conventions, making it easier to manage and identify resources in large environments.

Overview of the Azure Naming Tool

The Azure Naming Tool is part of the Cloud Adoption Framework for Azure, and it is available as an open-source project on GitHub. The tool is a PowerShell script that generates names for Azure resources based on a set of rules and patterns defined in a JSON file.

CloudAdoptionFramework/ready/AzNamingTool at master · microsoft/CloudAdoptionFramework (github.com)

The tool supports a wide range of resource types, including virtual machines, virtual networks, storage accounts, and more. It also allows for customizations to the naming convention, enabling organizations to adapt the tool to their specific needs.

Parameterized Deployment and Naming Convention

To simplify deployment and management of Azure resources, it is important to use a consistent naming convention. This can be achieved through parameterized deployment, where parameters are defined in a separate file that specifies the values for resource names.

The YouTube video linked in the introduction provides guidance on parameterized deployment and naming convention, showing how to use PowerShell splatting or automate deployment with GitHub action YAML workflow.

Another good example of abstracting module by passing value from parameter is the learn module deployment with GitHub action. This method involves having a different parameter file for each environment, which allows for the deployment of respective resources manually using PowerShell command or splatting to simplify deployment with ps1 file. Alternatively, the workflow can be plugged into the GitHub action to deploy the same parameter source automatically.

Microsoft offers a training module on how to manage multiple environments using Bicep and GitHub actions, which includes a section on handling differences between environments using Bicep parameters. You can access this module at the following link:

https://learn.microsoft.com/en-us/training/modules/manage-multiple-environments-using-bicep-github-actions/6-handle-differences-between-environments-using-bicep-parameters

Naming Standards

Naming standards are critical to ensuring consistency and ease of management for Azure resources. A good naming standard should be intuitive, easy to remember, and provide enough information to identify the resource's purpose.

The Azure Naming Tool provides a set of predefined naming conventions that organizations can use as a starting point, but it also allows for customization of the naming standard. Two great resources for best practices on Azure naming standards are provided in the links below:

Azure Naming Tool in Action

In the Microsoft Learn Live module linked in the introduction, a demonstration of how to abstract a template with a parameter file is provided. This is an excellent resource to get started with the Azure Naming Tool.

Additionally, the GitHub repository linked below provides a set of advanced deployments using the Azure Naming Tool:

Another great resource for understanding how to create a separate module for naming convention using Bicep is provided in the link below:


Azure naming tool on github -

Conclusion

The Azure Naming Tool is a powerful tool that can help organizations adopt a standardized naming convention for their Azure resources. With a few simple steps, the tool can generate consistent names for resources, making it easier to manage and identify resources in large environments. Whether you're new to Azure or an experienced user, the Azure Naming Tool is a great resource to have in your toolbox.


Bicep project design workflow -



Starting my git repo after the step 5 of the process -




Updated Bicep Code for Idempotent Deployment of Log Analytics module

To make a Bicep deployment idempotent and fail-free for subsequent deployments, the "dependsOn" property can be used to ensure that resources are created or updated in the correct order, and the "exists" function can be used to check if a resource already exists before attempting to create it.

Here is an updated version of the Bicep code with these changes:

bicep
resource pclaw 'Microsoft.OperationalInsights/workspaces@2022-10-01' =  if (resourceExists) {
  properties: {
 //   source: 'Azure'
    sku: {
      name: 'pergb2018'
    }
    retentionInDays: 30
    features: {
      legacy: 0
      searchVersion: 1
      enableLogAccessUsingOnlyResourcePermissions: true
    }
    workspaceCapping: {
      dailyQuotaGb: json('-1.0')
    }
    publicNetworkAccessForIngestion: 'Enabled'
    publicNetworkAccessForQuery: 'Enabled'
  }
  name: 'laW${namingConvention}'
  location: location
 
}


resource runPowerShellInlineWithOutput 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
  name: 'runPowerShellInlineWithOutput'
  location: location
  kind: 'AzurePowerShell'
  identity: {
    type: 'UserAssigned'
    userAssignedIdentities: {
      '${UserAssignedIdentity}': {}
    }
  }
  properties: {
    forceUpdateTag: utcValue
    azPowerShellVersion: '9.0'
        arguments:  '-resourceName ${resourceName} -resourceGroupName  ${resourceGroupName} -aaLinkedName ${aaLinkedName}'
    scriptContent: '''
   
    param(
      [string] $resourceName,
      [string] $ResourceGroupName
      [string] $aaLinkedName
         )
         if (Get-AzResource -ResourceName $resourceName -ResourceType 'Microsoft.OperationalInsights/workspaces' -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue | Select-Object -First 1) {
          # Resource found
          $ResourceExists = $true
            }
          else {
              # Resource not found
              $ResourceExists = $false
       
     
     

         Write-Output $ResourceExists
       
         Write-Output $resourceName
           Write-Host $ResourceExists
           Write-Host  $resourceName
          }
         
          if (Get-AzResource -ResourceName $aaLinkedName -ResourceType 'Microsoft.OperationalInsights/workspaces/linkedServices' -ResourceGroupName $ResourceGroupName -ErrorAction SilentlyContinue | Select-Object -First 1) {
            # Resource found
            $linkedResourceExists = $true
              }
            else {
                # Resource not found
                $linkedResourceExists = $false
            }    
            Write-Output $linkedResourceExists
            Write-Output $aaLinkedName
     
    $DeploymentScriptOutputs = @{}
    $DeploymentScriptOutputs['Result'] = $ResourceExists
    $DeploymentScriptOutputs['aalResult'] = $linkedResourceExists
    $DeploymentScriptOutputs['nameOutput'] = $resourceName
    '''
   
    timeout: 'PT1H'
    cleanupPreference: 'OnSuccess'
    retentionInterval: 'PT2H'
  }
}

In this updated version of the code, the "pclaw" resource uses the "existing" keyword to check if the workspace already exists before attempting to create it. The "resPcLawSolutions" and "resLawLinkedServiceForAutomationAccount" resources use the "dependsOn" property to ensure that they are created or updated after the "pclaw" resource.

The "exists" property is used to check if the resource already exists before attempting to create it. This ensures that subsequent deployments do not create duplicate resources, and that the deployment is idempotent.

With these changes, the deployment should be idempotent and fail-free for subsequent deployments.



Another good repo I found today in Bicep Landing zone vending module with IPAM -

stalejohnsen/lzvendingipam: Bicep landing zone vending module for Azure + Azure IPAM example (github.com)

No comments:

Post a Comment