Wednesday, 29 May 2024

How to deploy Azure Container Apps

 

How to deploy Azure Container Apps


Containerizing your application is the modern-day approach to application development. The most popular platform for hosting containers is Kubernetes. However, not everyone wants or needs to know how to operate a Kubernetes cluster. Some people just want to deploy their apps.

Azure Container Apps deploys containers to a Kubernetes cluster managed by Azure. This lets developers focus on what they do best, write code.

In this post, I show you how to deploy the eShopOnWeb application to Azure Container Apps with Octopus Deploy.

Read our white paper: A leader's guide to Kubernetes CD at scale

Learn how to overcome technical hurdles and business challenges and successfully implement Kubernetes.

Get the white paper 

Getting started

Before you can deploy to Azure Container Apps, you need to configure:

  • A container registry for your containers
  • A build server to push your containers to the registry
  • An Octopus Docker Container Registry external feed
  • An Azure Container Apps environment

Configuring the container registry

First, you need a place to push your containers. Octopus is compatible with a variety of Docker container registries, but this post uses an Azure Container Registry. If you already have a Docker Container Registry configured, you can skip to the next section.

To create an Azure Container Registry, click Create a resource in the Azure Portal.

Azure Create Resource

Type Azure Container Registry in the search box and choose Container Registry from the list.

Azure Create Container Registry

Fill in the required inputs and click Create.

Azure Create Container Registry Create screen

After you create the resource, copy the login server information. You need this information when you configure the Docker build task and the Octopus Deploy external feed.

Newly created ACR resource

Configuring the build server

Now that you have a container registry, you need to configure a build server to push your containers to the registry.

For this post, I use Azure DevOps to show building the eShopOnWeb containers and pushing them to an Azure Container Registry. eShopOnWeb consists of 2 containers:

  • API
  • Web

My build consists of 2 Docker build tasks, both using the buildAndPush command.

Adding the Docker build task

Filter the list of tasks by typing docker into the search bar. Then choose the Docker task.

Add Docker task to build

The Docker task needs a Docker Registry service connection. Select New and fill in the form details.

  • Docker Registry: The login server from your ACR in URL format = https://<Login server>, example https://octopusdeploy.azurecr.io.
  • Docker ID: User ID for logging into your ACR. I chose to use an app registration, so the value of the ID is the application (client) ID of the app registration.
  • Docker Password: Password for the User ID. If you're using an app registration, this is the secret for the app registration.
  • The rest of the fields can use the defaults.

New Azure DevOps Service Connection

For the API Docker build task, use the following values:

  • Container repository: eshop-api
  • Command: buildAndPush
  • Dockerfile: src/PublicApi/Dockerfile
  • Build context: .
  • Tags: $(Build.BuildNumber) (Optional, I set my build format number to $(Year:yyyy).$(Month).$(DayOfYear)$(Rev:r))

Docker build task

The Web Docker build task will be identical with the following differences:

  • Container repository: eshop-web
  • Dockerfile: src/Web/Dockerfile

After you queue a new build, it should push your containers into your registry.

Container images in ACR

Configuring the Octopus Deploy external feed

Now the containers are hosted in ACR, you need to configure an external feed in Octopus. Navigate to Library, then External Feeds, then click ADD FEED.

Navigate to Libary, External Feed

Select the feed type. For this post, I'm using Azure Container Registry.

Select Azure Container Registry

Similar to the Service Connection in Azure DevOps, add the feed details:

  • Name: A meaningful name for the External Feed
  • URL: https://<Login Server> - example: https://octopusdeploy.azurecr.io
  • Credentials:
    • Feed Username: User to connect to the registry. I used an app registration.
    • Feed Password: Password for the user account. Mine was the secret for the app registration.

Next, click SAVE AND TEST.

Enter the image name, full or partial, you want to search for.

Test External Feed

Configuring project variables

This post assumes you know how to create an Octopus project and won't cover that topic. For the eShopOnWeb Octopus project, configure the following variables:

  • Project.Azure.Account: An Azure Service Prinicipal account variable. (Optional, the templates used can use Managed Identity)
  • Project.Azure.ContainerApp.Api.Name: Value to set for the Container Name, example: #{Octopus.Environment.Name}-eshop-api
  • Project.Azure.ContainerApp.Environment.Name: Name of the Azure Container App environment to create/use, example: #{Octopus.Environment.Name | ToLower} Note: Azure Container App environment names must be lower case.
  • Project.Azure.ContainerApp.Web.Name: Value to set for the Container Name, example: #{Octopus.Environment.Name | ToLower}-eshop-web
  • Project.Azure.Region.Code: The short name for the Azure Region, example: westus3
  • Project.Azure.ResourceGroup.Name: Name of the Azure Resource Group to create the resources in.
  • Project.Catalog.Database.Name: Name of the Catalog database for eShopOnWeb, example: #{Octopus.Environment.Name}-eshop-catalog
  • Project.Identity.Database.Name: Name of the Identity database for eShopOnWeb, example: #{Octopus.Environment.Name}-eshop-identity
  • Project.SQL.DNS: The DNS name for the SQL database server, example: <YourAzureSQLServer>.database.windows.net
  • Project.SQL.User.Name: Name of the SQL account for database access, example: eShopUser
  • Project.SQL.User.Password: Password for the SQL account

Octopus project variables

Configuring the deployment process

With the External Feed and project variables configured, you can now configure the deployment process. For the eShopOnWeb application, the process consists of the following steps:

  • Azure - Create Container App environment
  • Azure - Deploy api Container App
  • Get API DNS
  • Azure Deploy web Container App

Azure - Create Container App Environment step

To deploy to Azure Container App, you must first have an Azure Container App environment.

Add the Azure - Create Container App Environment community step template to your process. The template will first check to see if it already exists, if not, create it.

This template takes the following input:

  • Azure Resource Group Name: #{Project.Azure.ResourceGroup.Name}
  • Azure Account Subscription Id: #{Project.Azure.Account.SubscriptionNumber}
  • Azure Account Client Id: #{Project.Azure.Account.Client}
  • Azure Account Tenant Id: #{Project.Azure.Account.TenantId}
  • Azure Account Password: #{Project.Azure.Account.Password}
  • Container App Environment Name: #{Project.Azure.ContainerApp.Environment.Name}
  • Azure Location: #{Project.Azure.Region.Code}

Azure - Create Container App Environment

The template sets an output variable called ManagedEnvironmentId which is the ID value of the environment it created or found if it already exists.

Azure - Deploy api Container App step

Add an Azure - Deploy Container App community step template to your process.

  • Azure Resource Group Name: #{Project.Azure.ResourceGroup.Name}
  • Azure Account Subscription Id: #{Project.Azure.Account.SubscriptionNumber}
  • Azure Account Client Id: #{Project.Azure.Account.Client}
  • Azure Account Tenant Id: #{Project.Azure.Account.TenantId}
  • Azure Account Password: #{Project.Azure.Account.Password}
  • Container App Environment Name: #{Octopus.Action[Azure - Create Container App Environment].Output.ManagedEnvironmentId} Note: This uses the output variable from the Azure - Create Container App Environment step
  • Azure Location: #{Project.Azure.Region.Code}
  • Container Name: #{Project.Azure.ContainerApp.Api.Name}
  • Container Image: Choose eshop-api from feed list.
  • Environment Variables:
[
  {
    "name": "ConnectionStrings__CatalogConnection",
    "value": "Server=#{Project.SQL.DNS},1433;Integrated Security=false;Initial Catalog=#{Project.Catalog.Database.Name};User Id=#{Project.SQL.User.Name};Password=#{Project.SQL.User.Password};Trusted_Connection=false;Trust Server Certificate=True;"
  },
  {
    "name": "ConnectionStrings__IdentityConnection",
    "value": "Server=#{Project.SQL.DNS},1433;Integrated Security=false;Initial Catalog=#{Project.Identity.Database.Name};User Id=#{Project.SQL.User.Name};Password=#{Project.SQL.User.Password};Trusted_Connection=false;Trust Server Certificate=True;"
  },
  {
    "name": "ASPNETCORE_URLS",
    "value": "http://+:80"
  },
  {
    "name": "MyTest",
    "secretref": "mysecret"
  },
  {
    "name": "ASPNETCORE_ENVIRONMENT",
    "value": "Development"
  }
]

Secrets:

[
  {
    "name": "mysecret",
    "value": "#{Project.SQL.User.Password}"
  }
]
  • Container Ingress Port: 80
  • External Ingress: Unchecked (False)

Azure - Deploy Container App

Get API DNS step

The eShopOnWeb web container needs the URL to the API container. This step runs the following code to retrieve that value and sets an output variable. This code assumes that the Az PowerShell modules aren't installed, so it does it dynamically.

$PowerShellModuleName = "Az.App"
$LocalModules = (New-Item "$PWD/modules" -ItemType Directory -Force).FullName

Save-Module -Name $PowerShellModuleName -Path $LocalModules -Force
$env:PSModulePath = "$LocalModules$([IO.Path]::PathSeparator)$env:PSModulePath"

# Import modules
Import-Module Az.App

# Get reference to the container
$apiContainerApp = Get-AzContainerApp -Name "$($OctopusParameters["Project.Azure.ContainerApp.Api.Name"])" -ResourceGroupName $OctopusParameters["Project.Azure.ResourceGroup.Name"]

Set-OctopusVariable -name "DNS" -value $apiContainerApp.IngressFQDN

Azure - Deploy web Container App step

  • Azure Resource Group Name: #{Project.Azure.ResourceGroup.Name}
  • Azure Account Subscription Id: #{Project.Azure.Account.SubscriptionNumber}
  • Azure Account Client Id: #{Project.Azure.Account.Client}
  • Azure Account Tenant Id: #{Project.Azure.Account.TenantId}
  • Azure Account Password: #{Project.Azure.Account.Password}
  • Container App Environment Name: #{Project.Azure.ContainerApp.Environment.Name}
  • Azure Location: #{Project.Azure.Region.Code}
  • Container Name: #{Project.Azure.ContainerApp.Web.Name}
  • Container Image: Choose eshop-web from feed list.
  • Environment Variables:
[
  {
    "name": "ConnectionStrings__CatalogConnection",
    "value": "Server=#{Project.SQL.DNS},1433;Integrated Security=false;Initial Catalog=#{Project.Catalog.Database.Name};User Id=#{Project.SQL.User.Name};Password=#{Project.SQL.User.Password};Trusted_Connection=false;Trust Server Certificate=True;"
  },
  {
    "name": "ConnectionStrings__IdentityConnection",
    "value": "Server=#{Project.SQL.DNS},1433;Integrated Security=false;Initial Catalog=#{Project.Identity.Database.Name};User Id=#{Project.SQL.User.Name};Password=#{Project.SQL.User.Password};Trusted_Connection=false;Trust Server Certificate=True;"
  },
  {
    "name": "ASPNETCORE_URLS",
    "value": "http://+:80"
  },
  {
    "name": "baseUrls__apiBase",
    "value": "https://#{Octopus.Action[Get API DNS].Output.DNS}"
  },
  {
    "name": "ASPNETCORE_ENVIRONMENT",
    "value": "Development"
  }
]

  • Secrets: (blank)
  • Container Ingress Port: 80
  • External Ingress: Checked (True)

When done, your process should look like this:

Octopus Deployment Process

Deployment

After the deployment is complete, it should create the following Azure resources:

  • Catalog database
  • Identity database
  • Azure Container App environment
  • eshop-api container app
  • eshop-web container app

Azure resources

Implement Azure Container Apps(LAB)

 

 Implement Azure Container Apps

Lab introduction

In this lab, you learn how to implement and deploy Azure Container Apps.

This lab requires an Azure subscription. Your subscription type may affect the availability of features in this lab. You may change the region, but the steps are written using East US.

Estimated timing: 15 minutes

Lab scenario

Your organization has a web application that runs on a virtual machine in your on-premises data center. The organization wants to move all applications to the cloud but doesn’t want to have a large number of servers to manage. You decide to evaluate Azure Container Apps.

Interactive lab simulations

There are no interactive lab simulations for this topic.

Architecture diagram

Diagram of the tasks.

Job skills

  • Task 1: Create and configure an Azure Container App and environment.
  • Task 2: Test and verify deployment of the Azure Container App.

Task 1: Create and configure an Azure Container App and environment

Azure Container Apps take the concept of a managed Kubernetes cluster a step further and manages the cluster environment as well as provides other managed services on top of the cluster. Unlike an Azure Kubernetes cluster, where you must still manage the cluster, an Azure Container Apps instance removes some of the complexity to setting up a Kubernetes cluster.

  1. From the Azure portal, search for and select Container Apps.

  2. From Container Apps, select Create.

  3. Use the following information to fill out the details on the Basics tab.*.

    SettingAction
    SubscriptionSelect your Azure subscription
    Resource groupaz104-rg9
    Container app namemy-app
    RegionEast US (Or a region available near you)
    Container Apps EnvironmentLeave default
  4. On the Container tab, ensure that Use quickstart image is enabled and that the quickstart image is set to Simple hello world container.

  5. Select the Review and create and then Create.

    Note: Wait for the container app to deploy. This will take a couple of minutes.

Task 2: Test and verify deployment of the Azure Container App

By default, the Azure container app that you create will accept traffic on port 80 using the sample Hello World application. Azure Container Apps will provide a DNS name for the application. Copy and navigate to this URL to ensure that the application is up and running.

  1. Select Go to resource to view your new container app.

  2. Select the link next to Application URL to view your application.

    Screenshot of the ACA overview page in the portal.

  3. Verify you receive the Your Azure Container Apps app is live message.

Cleanup your resources

If you are working with your own subscription take a minute to delete the lab resources. This will ensure resources are freed up and cost is minimized. The easiest way to delete the lab resources is to delete the lab resource group.

  • In the Azure portal, select the resource group, select Delete the resource groupEnter resource group name, and then click Delete.
  • Using Azure PowerShell, Remove-AzResourceGroup -Name resourceGroupName.
  • Using the CLI, az group delete --name resourceGroupName.

Extend your learning with Copilot

Copilot can assist you in learning how to use the Azure scripting tools. Copilot can also assist in areas not covered in the lab or where you need more information. Open an Edge browser and choose Copilot (top right) or navigate to copilot.microsoft.com. Take a few minutes to try these prompts.

  • Summarize the steps to create and configure an Azure Container App.
  • Compare and contrast Azure Container Apps to Azure Kubernetes Service.

Introducing Azure Container Apps

 Introducing Azure Container Apps: a serverless container service for running modern apps at scale


The fast pace of innovation today requires businesses to focus on differentiated business logic and high velocity delivery to maximize impact. Business logic is often encapsulated in modern cloud native applications represented as microservices with multiple application components that are independently developed and interconnected. Many cloud hosting options for microservices and containerized applications require infrastructure management and orchestration that can increase solution complexity, overall cost, and time to market.

 

At Ignite, we announced Azure Container Apps, a serverless application centric hosting service where users do not see or manage any underlying VMs, orchestrators, or other cloud infrastructure. Azure Container Apps enables executing application code packaged in any container and is unopinionated about runtime or programming model. Applications can scale in response to HTTP requests, events (e.g. storage queue messages, Kafka topics, etc.), or simply run as always-on background jobs. Azure Container Apps addresses specific requirements for microservices including encrypted service to service communication and the independent versioning and scaling of services.

 

Azure Container Apps is built on the foundation of powerful open-source technology in the Kubernetes ecosystem . The open-source centric approach enables a path for teams to build microservices without having to overcome the concept and operational overhead of working with Kubernetes directly and enables continued application portability by leveraging open standards and APIs. Behind the scenes, every application runs on Azure Kubernetes Service, with Kubernetes Event Driven Autoscaling (KEDA)Distributed Application Runtime (Dapr), and Envoy deeply integrated in the hosting service.

 

Getting started with Azure Container Apps

Multiple individual Container Apps can be deployed to a single Container Apps environment, which acts as an isolation and observability boundary between a group of Container Apps. Container Apps deployed to the same environment write logs to the same Log Analytics workspace. This structure enables easy communication between microservices that compose the overall solution. Additionally, multiple containers can be deployed to the same container app and in that case, they’ll be deployed and scaled together as a single unit or pod of containers. To get started with Azure Container Apps see Quickstart: Deploy an HTTP application to Azure Container Apps.

 

thumbnail image 1 captioned Create a container appCreate a container app

You can use the Azure CLI to create and manage Container Apps.

 

thumbnail image 2 captioned Create a new Container App using the Azure CLICreate a new Container App using the Azure CLI

 

Horizontal autoscaling and scale triggers

Azure Container Apps manages horizontal autoscaling through a set of declarative scaling rules. By default, Azure Container Apps scale to zero and pause billing when not in use. As a Container App scales out, new instances of the Container App are created on-demand. Container Apps supports many scale triggers including HTTP and event-based triggers using Kubernetes Event Driven Autoscaling (KEDA). KEDA is a rich autoscaler with many event scaler options continuously contributed by the community. For more information about supported scale triggers, see KEDA Scalers. See How-to – Set scaling rules in Azure Container Apps for more details.

 

thumbnail image 3 captioned Add a scale ruleAdd a scale rule

 

Making microservices development easier with Distributed Application Runtime (Dapr)

Dapr is an open-source event-driven runtime that codifies best practices for building portable microservice applications into independent platform agnostic building blocks using the development language and framework of your choice. Azure Container Apps offers a fully managed version of the Dapr APIs. With Dapr for Azure Container Apps, sidecars can be enabled to run next to your application instances and provide a rich set of capabilities and productivity gains. You can use the following Dapr APIs: Service to Service callsPub/SubEvent BindingsState Stores, and Actors. See Tutorial – Use Dapr in Azure Container Apps for more details.

 

thumbnail image 4 captioned Dapr integrationDapr integration

App lifecycle management

Azure Container Apps streamlines the application lifecycle management by supporting multiple revisions to manage application versions, enabling traffic splitting and balancing across application versions, securing application secrets, connecting different applications, and delivering integrated monitoring via Log Analytics. See Concepts - Application lifecycle management in Azure Container Apps for more details.

 

thumbnail image 5 captioned Revision management