Search code examples
azureazure-devopsadoazure-cliazure-bicep

How to get values from Azure DevOps variables library into a Bicep template at run time


Morning All,

I'm currently creating a template for creating a sql server and database. I have managed to get a parameter from the pipeline at run time for the environment name. However my next issue is that I want to use the same template for four different environments. Three of them have the same subscription id and then prod has a different one. So I thought it might be best to create a library for each environment and then in my azure devops pipeline, link the libraries to the pipeline.

What I now want to do, is for example take three values from the library and place them into the Bicep template when the pipeline is run.

Can anyone advise how to do this?

Thanks,

Darren

Here is the Bicep template:

targetScope = 'resourceGroup'

// input parameters
param Environment string
param sqladminlogin string = '${SqlAdminLogin}'
param sqladminpassword string = '{SqlAdminPassword}'
param SqlServerName string = 'SQL-${Environment}01'
param location string = resourceGroup().location
param Sql_DB_Name string = 'SQL-${Environment}'

resource SqlServerName_resource_tst 'Microsoft.Sql/servers@2022-05-01-preview' = {
  name: toLower(SqlServerName)
  location: location
  tags: {
    Service: 'TESTING'
    Environment: Environment
    'Business Owner': 'TBC'
  }
  kind: 'v12.0'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    administratorLogin: sqladminlogin
    administratorLoginPassword: sqladminpassword
    version: '12.0'
    minimalTlsVersion: '1.2'
    publicNetworkAccess: 'Enabled'
    administrators: {
      administratorType: 'ActiveDirectory'
      principalType: 'Group'
      login: 'NSG-AG-SQL-RW-TST'
      sid: '********'
      tenantId: '**********'
      azureADOnlyAuthentication: false
    }
    restrictOutboundNetworkAccess: 'Disabled'
  }
}

The pipeline looks like this:

name: bicep-deployment

trigger:
- main

pool:
  vmImage: 'windows-latest'

parameters:
  - name: Environment
    displayName: Environment
    type: string
    default: 'TST'
    values:
      - DEV
      - TST
      - UAT
      - PRD

  - name: Action
    displayName: Action
    type: string
    default: 'Plan'
    values:
      - Plan
      - Apply

variables:
  - name: Environment
    value: '${{ parameters.Environment }}'

  - name: System.Debug
    value: true

  - name: Action
    value: '${{ parameters.Action }}'

  - name: serviceConnection
    ${{ if eq( parameters['Environment'], 'DEV') }}:
      value: "AG-Dev"
    ${{ if eq( parameters['Environment'], 'TST') }}:
      value: "AG-TST"
    ${{ if eq( parameters['Environment'], 'UAT' ) }}:
      value: "AG-UAT"
    ${{ if eq( parameters['Environment'], 'PRD' ) }}:
      value: "AG-PRD"

  - name: resourceGroupName
    ${{ if eq( parameters['Environment'], 'DEV') }}:
      value: "RG-AG-DEV"
    ${{ if eq( parameters['Environment'], 'TST') }}:
      value: "RG-AG-TST"
    ${{ if eq( parameters['Environment'], 'UAT') }}:
      value: "RG-AG-UAT"
    ${{ if eq( parameters['Environment'], 'PRD') }}:
      value: "RG-AG-PR"

  # Select Variable Library to use for the environment.
  - group: ${{parameters.Environment}}

stages:
  # SQL Stages
  - stage: Preview_SQL
    jobs:
    - job: Preview
      steps:
      - task: AzureCLI@2
        inputs:
          azureSubscription: $(serviceConnection)
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: |
            az deployment group what-if \
              --resource-group '$(resourceGroupName)' \
              --template-file Bicep/SQL/SQL-tst.bicep \
              --parameters Environment="${{ parameters.Environment }}"

  # The deployment only runs if Apply action is selected when running the pipeline and if the validate job succeeds.
  - stage: Deploy_SQL
    dependsOn: Preview_SQL
    jobs:
      - deployment: Deploy_SQL
        displayName: Deploy_SQL
        environment: $(Environment)
        condition: and(succeeded(), eq(variables['Action'], 'Apply'))
        strategy:
          runOnce:
            deploy:
              steps:
                - checkout: self
                - task: AzureCLI@2
                  displayName: Bicep deployment
                  inputs:
                    azureSubscription: $(serviceConnection)
                    scriptType: bash
                    scriptLocation: inlineScript
                    inlineScript: |
                      set -e

                      echo '##[Section]Deploy SQL'

                      az deployment group create \
                        --resource-group $(resourceGroupName) \
                        --name "SQL-deployment" \
                        --template-file Bicep/SQL/SQL-tst.bicep \
                        --parameters Environment="${{ parameters.Environment }}"

When running the pipeline it will run, however the deployment into Azure will fail. When i look into the deployment history within the Azure portal it has a bad request but if i check the inputs I can see that the sql admin login and password aren't copied over but the string of $(SqlAdminLogin) & $(SqlAdminPassword) is instead. How do I get the value of those variables to appear here?


Solution

  • Your bicep does not define all parameters:

    param Environment string
    param sqladminlogin string = '${SqlAdminLogin}'
    param sqladminpassword string = '{SqlAdminPassword}'
    param SqlServerName string = 'SQL-${Environment}01'
    param location string = resourceGroup().location
    param Sql_DB_Name string = 'SQL-${Environment}'
    

    When you pass Environment = UAT, that will be as

    Environment='UAT'
    sqladminlogin = ''
    sqladminpassword = ''
    SqlServerName = 'SQL-UAT01'
    location = your_location
    Sql_DB_Name = 'SQL-UAT'
    

    You should pass all parameters here:

     az deployment group create \
        --resource-group $(resourceGroupName) \
        --name "SQL-deployment" \
        --template-file Bicep/SQL/SQL-tst.bicep \
        --parameters Environment="${{ parameters.Environment}}" sqladminlogin=Some_value sqladminpassword=Some_value
    

    and you may update your parameters to:

    param Environment string
    param sqladminlogin string
    param sqladminpassword string
    param SqlServerName string = 'SQL-${Environment}01'
    param location string = resourceGroup().location
    param Sql_DB_Name string = 'SQL-${Environment}'
    

    https://learn.microsoft.com/en-us/cli/azure/deployment/group?view=azure-cli-latest#az-deployment-group-create()-examples

    https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameters