Microservice Application with Azure Container Apps, Dapr and Bicep

By:   |   Updated: 2024-11-19   |   Comments   |   Related: > Cloud Strategy


Problem

You have used microservice architecture techniques to design a microservice application, but bringing the design to life is a different and difficult task. One issue: difficulty managing the compute infrastructure hosting these microservices and the environment in the cloud.

Solution

You can use infrastructure as code (IaC) to manage and provision computer resources to cloud applications and services. This enables you to define, deploy, and manage infrastructure components (like servers, networks, databases, etc.) using descriptive coding languages or templates. One of the leading descriptive languages used is Bicep.

In this four-part series tutorial, you will learn how to create a microservice application with Azure container apps and Dapr. Since the application relies on Bicep to develop infrastructure code, this part of the series will focus on building infrastructure with Bicep and how to deploy templates.

Prerequisites

  • Azure free account (signup here)
  • Visual Studio Code (latest version)
  • Dapr CLI

Azure Resource Manager (ARM)

ARM is the service that enables you to create, update, audit, delete, and analyze resources in your Azure subscription. You can interact with ARM using tools like Azure web portal and Azure CLI/PowerShell or programmatically using JSON or Bicep. This article leans more towards interacting with ARM using Bicep.

You can read more about ARM: Azure Resource Management Templates to Simplify Cloud Entities. An important concept to understand about ARM operations is the control plane and the data plane. You should use:

  • Control Plane: Manages the resources in your subscription. The control plane is like having control to provision resources on a server, like an admin.
  • Data Plane: Accesses features or data that your resource exposes. The data plane is like an API exposed by an application on the server.

ARM basically acts as the middleman between your requests and Resource providers, like Azure data stores, container apps, or role assignments to ensure consistent, reliable, and secure deployments. This tutorial will show you how to interact with ARM using Bicep code.

What is Bicep?

Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources, i.e., Bicep can only be used to write scripts for ARM to process. This is done by defining the infrastructure you want to deploy to Azure using code that can be used repeatedly during the application's development lifespan to deploy consistent infrastructure multiple times.

When you write a Bicep file and deploy a resource, the Bicep code is first converted into JSON code through the transpilation process, then the JSON code is sent to ARM for processing. You'll define your resources within a Bicep file called a template, then submit the template to ARM. ARM then takes responsibility for deploying each resource within the template on your behalf.

Benefits of Bicep

Here are the advantages for using Bicep to code your infrastructure:

  • Modules: You can use macro codes to break down complex template deployments by using decoupled modules to build your final deployments. This is like having a box of differently shaped Lego that you can use to build different structures with. Plus, you can share these modules or Lego pieces with your team.
  • Simple Syntax: Bicep was made for deploying Azure resources to ARM, so the language has a simple syntax for interacting with ARM.
  • Azure Native: Bicep is native to Azure, which means that it is directly connected to Azure's ecosystem. Therefore, your code will always be up-to-date with the latest Azure new technologies, and you do not have to wait for the technologies to be adapted like you would in the case of third-party IaC languages.
  • No State Management: Bicep will keep state for you across its environment and you do not need to create a data storage account to log state.
  • Automation: You can automate tasks that manage your Azure resources by writing a template and adding it to a pipeline with custom triggers.

Parameters and Variables

Bicep templates are powerful because of their reusability. You can use Bicep to write templates that deploy multiple environments or deploy multiple applications and services to the same environment.

One way Bicep enables developers to create reusable code is by using parameters. Parameters enable you to get values from outside the template file. If you want to deploy to Azure manually using Azure CLI or Azure PowerShell, you ideally want to create a separate JSON file to contain all the parameter values. If the template will be deployed in an automated pipeline, the pipeline should provide the parameter values.

Using Bicep, this is how you declare a parameter:

param resourceGroupName string = ''

When declaring a parameter, you must specify the type, as shown above. You will use parameters in the next section.

Bicep also uses variables, which are defined and set inside the template file. This is how variables are declared:

var abbrs = loadJsonContent('./abbreviations.json')

When declaring a variable, you do not need to specify the type, as shown above.

Outputs

When developing your Bicep application, you will need to pass parameter values dynamically since the deployments are automated, and there is not a lot of room for user inputs. Some resources depend on other resources. For example, as part of this tutorial, you must create the environment resource for your container apps. But, you need to keep analyzing the environment and you decide to use the logAnalyticsConfiguration property. This property requires you to provide a customer ID. For you to get the customer ID dynamically, you must first create a workspace resource that can output the customer ID. In this case, the environment resource depends on the workspace resource, so you must create the workspace resource using the following Bicep code:

metadata description = 'Creates a Log Analytics workspace.'
param name string
param location string = resourceGroup().location
param tags object = {}
 
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
  name: name
  location: location
  tags: tags
  properties: any({
    retentionInDays: 30
    features: {
      searchVersion: 1
    }
  })
}
 
output logAnalyticsWorkspaceId string = logAnalytics.outputs.id
output name string = logAnalytics.name

Notice how this file outputs the customer id and name for other resources to use as parameters.

And this is how you can use this customer id output when you define the environment resource:

@description('Name of the Log Analytics workspace')
param logAnalyticsWorkspaceName string
 
resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2024-03-01' = {
  name: name
  location: location
  tags: tags
  properties: {
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalyticsWorkspace.properties.customerId
        sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
      }
    }
    daprAIInstrumentationKey: daprEnabled && !empty(applicationInsightsName) ? applicationInsights.properties.InstrumentationKey : ''
  }
}
 
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' existing = {
  name: logAnalyticsWorkspaceName
}

As you can see, this file uses a parameter logAnalyticsWorkspaceName to indicate that this value is expected by the file. The resource is defined using the "existing" keyword to specify that the resource has already been created. Its name in the Bicep application's domain is logAnlayticsWorkspaceName, then you can reference the resource.

Grouping Resources Using Modules

Now that you have created Bicep files to deploy different resources, you have to group all the individual resources and make the code more modularized. You can do this using modules. Bicep modules allow you to organize and reuse your Bicep code by creating smaller units that can be composed into a template.

All the Bicep templates we created in the previous section can now be used as modules by other Bicep templates. This will help to make the code more reusable, plus we can chain related templates and use outputs from one template as a parameter for another template. This is how you define a module:

module myModule 'modules/mymodule.bicep' = {
  name: 'MyModule'
  params: {
    location: location
  }
}

Module use a module keyword and instead of including a resource type and API version, you'll use the module's file name with its path.

Activating Sandbox for Azure

Microsoft Learn has a Sandbox which allows you to use Azure resources for development and testing. The Sandbox assigns a Concierge subscription to an account you register the sandbox with for a limited time:

After you register for the sandbox, go to your terminal and use this Azure CLI command to log in to your account:

Az login

Select a Microsoft account. Ensure that you select and confirm the account you used to register for Sandbox:

Activating Sandbox for Azure

If issues arise while setting up your subscription to the sandbox account, copy the subscription ID from the output shown above and use the following command:

az account set --subscription <subscription-id>

Deploy Application to Azure

Now, let's use Azure CLI to deploy the workspace template we defined earlier. First, create a file named log-analytics.Bicep and add the following code:

metadata description = 'Creates a Log Analytics workspace.'
param name string
param location string = resourceGroup().location
param tags object = {}
 
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
  name: name
  location: location
  tags: tags
  properties: any({
    retentionInDays: 30
    features: {
      searchVersion: 1
    }
  })
}
 
output id string = logAnalytics.id
output name string = logAnalytics.name
 

Azure's sandbox account has a default resource group named learn-84c03279-b255-4b76-b98d-de362668cf5c and we can set this as our default resource group for the Bicep operations when we run the templates using Azure CLI:

az configure --defaults group="learn-84c03279-b255-4b76-b98d-de362668cf5c"

After running the command, ensure you navigate to your log-analytics.Bicep file's directory and run the following command to deploy the resource in the Bicep template:

az deployment group create --template-file log-analytics.bicep

To confirm your deployment, you will get an output with information about the resource on your terminal or you can log into your Azure portal. Click on your avatar after and change the directory to the Sandbox to see if the resource was created:

Deploy Application to Azure

Great work! You successfully deployed your first resource using Bicep templates.

Conclusion

This tip serves as the foundation for a series of articles aiming to create a microservice application on Azure using container apps. These container apps will be used as a decoupled microservice that will communicate with other container apps/microservices. Being able to deploy container apps and other related resources in a reliable, secure, and dynamic manner are crucial to the application.

This article covers how Bicep templates can be used to create these resources, and breaks down the basic principles for coding in Bicep and how to deploy these templates to ARM. This is a good starting point if you want to understand the application in detail. The next article will add another layer to integrate your container apps with Dapr and, later, to build the application.

Next Steps


sql server categories

sql server webinars

subscribe to mssqltips

sql server tutorials

sql server white papers

next tip



About the author
MSSQLTips author Levi Masonde Levi Masonde is a developer passionate about analyzing large datasets and creating useful information from these data. He is proficient in Python, ReactJS, and Power Platform applications. He is responsible for creating applications and managing databases as well as a lifetime student of programming and enjoys learning new technologies and how to utilize and share what he learns.

This author pledges the content of this article is based on professional experience and not AI generated.

View all my tips


Article Last Updated: 2024-11-19

Comments For This Article

















get free sql tips
agree to terms