(Part-1) Leverage Bicep: Standard model to Automate Azure IaaS deployment
Published Apr 28 2023 12:19 PM 7,633 Views
Microsoft

Chapter 1

Chapter 2 >>     Chapter 3 >>

 

  • What is Bicep ?

 

  1. Bicep is an IaC language for automating Azure infrastructure construction.
    -- IaC means Infrastructure as Code.
  2. Bicep simplify Azure Resource Manager templates as a wrapper. Bicep files are converted to JSON format internally, then the files communicate via Azure REST API
  3. This is a language provided by Microsoft that is wrapped in Bicep to make it simple to write.
    JSON is a structural definition that is difficult to handle and requires a level of craftsmanship to describe.
  • What is the difference between ARM templates and Bicep

  1. Bicep can allow you to use comments on the scripts as follows.
    // comments
    /*
        comments 1
        comments 2
    */
  2. You can modularize and separate processes by bicep file.
    Bicep can be handled in a local environment, whereas Linked-Templates requires that the file be placed in a location accessible to the Public Endpoint.
  3. Bicep allows you to use more dependency setting than ARM templates as follows:

    - dependsOn
    - parent
    - scope
    - Implicit dependencies
  4. Bicep simplifies scripts by reducing "comma" and "double quotation" than JSON.

  5. Bicep can set scope of Azure environments easily for each level as follows:

    AkiraKoike_0-1682425337264.png

     

  • Bicep fundamental features 
  1. Bicep inherits the basic functionality of ARM templates.
    The default deployment mode is Incremental Deploy.
  2. The maximum file size of ARM templates generated by Bicep is 4 MB.
  3. You can convert both ways Bicep to JSON and JSON to Bicep.

    Note that it's not recommended to directly use JSON file, which is exported from Azure Portal because such JSON file is redundant even if you will convert it to Bicep file. Use such JSON file as reference.

 

  • Bicep fundamental syntax and basic terminology 
  •  

      AkiraKoike_0-1682440403771.png

  1. param
    It means that we are going to declare a parameter variable. It is the initial value of the variable. This corresponds to the "parameters": {} in JSON.
  2. location
    Variable name. The name can be any string. It is case-sensitive.
    In this example, we use "location" because we want to treat it as a variable that stores the region name.
  3. string
    Type. The type must be specified in the declaration of a Param variable. Other types include int and object. In this example, the region name is a string because we want to store it as a string.
  4. resourceGroup().location
    The resouceGroup function is used to call the region name set in the target resource group.
    In the case of a resource group created by specifying the East Japan region, this is synonymous with 'japaneast'.
    Of course, you can hard coat this part as 'japaneast' without any problem.
    It is also possible to declare only the type without any value.

 

 

      AkiraKoike_0-1682443727840.png

  1. var
    The difference from "param" is that it is treated as a variable whose value cannot be changed when deployed. You can set "param" variable via az commands or others from out of script files but "var" variable is internal one of Bicep script, thus you can't configure "var" variable without changing the file.

  2. VNET_HUB_NAME
    This is the name of the variable. Any string can be used. Case is also distinguished. In this example, we use this name because we want the variable to handle the name of the Virtual Network.
  3. string
    The type of the variable handled by "var" is not specified.
  4. vnet-poc-hub-stag-001
    It is a value. It is just a string. When dealing with strings, enclose them in single quotes. When a string is combined with a function, it is also enclosed in single quotes.

 

     AkiraKoike_1-1682443948078.png

  1. resource
    It is called the resource keyword. It means that the resource to be deployed is to be described. In JSON, it corresponds to the "resources":{} part. This is the part where the body of the process is described.
  2. hubVnet
    This is called a symbolic name. Any string can be used, but only alphanumeric characters and underscores can be used. The symbolic name is an important part that is treated as an identifier when calling this name from various resources.
  3. Microsoft.Network/xxxx
    The resource provider. The hubVnet decides here what resource to define. Here we specify the resource provider for virtualNetwork.
  4. @2020-05-01
    API version is specified after @. Here it means use the May 1, 2020 version of vNET API.

 

      AkiraKoike_0-1682488493336.png

 

  • Target Resource -> Virtual Network
  • API Version -> 2020-05-01
  • Virtual Network Name -> Value in variable named VNET_HUB_NAME
  • Region of virtual network -> Value in the variable named location
  • Tags of virtual network -> Value in the variable TAG_VALUE

 

      AkiraKoike_0-1682496300928.png

  • When you want to refer to a resource that has already been deployed to Azure, add "existing" after the API version. For example, in the above example, since we are referring to Log Analytics Workspace, we can specify "existingloganalyticsworkspace.id" in this bicep file to handle the LAW resource ID. If you want to handle resource ID in another bicep file, you can either declare existing in another bicep file or use the "ouput" keyword to pass the variable.

 

      AkiraKoike_1-1682496464929.png

 

  • The module keyword can be used to pass a process to another process described in another bicep file. The passed bicep file is identified as vnet.bicep, which is located under the Modules directory in this bicep file.
  • The params property here specifies the name of the variable to be passed to vnet.bicep. This way, the variables and values handled in this bicep file can be passed to another bicep file.
  • The variable name logAnalyticsWorkspaceName is passed to the vnet.bicep file. The value is the value received from the variable name OUTPUT_LAW_NAME specified ouput in the loganalyticsmodule.
  • dependsOn is a way to describe the dependencies of a loganalyticsmodule, saying that the processing of this vnetmodule should be performed after the processing described by the symbolic name of the loganalyticsmodule has been completed.

 

      AkiraKoike_0-1682502739925.png

 

  • The scope property is also a dependency property, and there are two patterns for dealing with scope.
  1. The case where the scope is specified here, such as "scope: resourceGroup(exampleRG)" without declaring the scope by targetScope.
  2. The case where extensions dependent on the symbolic name of spokeVnet are set as above.

    1 is often added when you want to refer to a resource that already exists in another resource group, as in "scope: resourceGroup(exampleRG)".
    For a separate resource group with a separate subscription, the following is also used.

    2 is used when describing extensions attached to Azure resources, such as roles, permission settings, locking functions, diagnostic logs, etc. In such cases, the value should be the symbol of the resource you want to target.

    In such cases, the value should be the symbolic name of the resource you wish to target (in this case, spokeVnet).


    In other words, in the above example, you can see that we are describing a diagnostic setting to be attached to spokeVnet.

     

      AkiraKoike_0-1682505346215.png

  • The parent property is also a dependency property. In other words, it specifies the parent resource. Since the vNET Peering resource is described here, it is meant to be linked to the vNET creation process described by the symbolic name of huvVnet. The parent is basically made to depend on the resource linked to the symbolic name described in the same bicep file.

    - dependsOn has no parent-child relationship. It is simply used to define the order of dependent resources. 
      Example: Deployment of Azure Firewall after deployment of Hub-vNET/Subnet is complete.
    - In some cases, bicep and the target resource are linked behind the scenes, called implicit dependencies. In such cases, there is no need to specify the dependency.

      AkiraKoike_0-1682510295607.png

  • The "output" keyword refers to the standard output or passing of a variable.
    When a bicep file is executed and deployed, Azure Portal keeps a deployment history.
    From that history, the value of the specified variable is displayed as an output result (for debugging).
  • You can also use the output keyword to pass variables to another bicep file.
    Here, the variables (values) VNET_HUB_NAME and VNET_SPOKE_NAME are returned after the bicep file is executed. Of course, these two values are displayed in the deployment history of Azure Portal as output results.
  • The output keyword should be listed at the end in the bicep file.

 

  • Other Writing Methods
    - How to combine variables with each other or with functions

    var testvalue string = '${prefix}-And-${uniqueString(resourceGroup().id)}’

    - Nested writing method with resource inside the resource keyword

    resource hogehoge ‘Microsoft.xxx@202x-xx-xx’ = {
        name: xx

        properties: {

        }

        resource fugafuga = {
          name: yy


    # In the case of nesting, use "::" for reference.
       For example,  hogehoge::fugafuga.id.

  • Order of syntax (try to write in a way that is easy to read)
    AkiraKoike_0-1682513964791.png

 

Enjoy bicep!!

 

>> Next Chapter (Bicep Development Environment, Sample Code and Explanation)

Version history
Last update:
‎May 11 2023 10:23 PM
Updated by: