Introduction
Employers want engineers who can automate deployments, not just run them by hand, and fix the pipeline when it breaks.
The scenario: At Fabrikam Inc., the container app is running, but every release is still manual. The DevOps team wants an Azure Pipeline that deploys the image from Azure Container Registry to Azure Container Apps on a self-hosted agent, and the deployment has to succeed at least once to prove it works.
In Part 4, I configure Pipeline1 to use the self-hosted agent pool and add the Azure Container Apps deployment task. The first run failed, so I troubleshoot the errors and rerun the pipeline until the deployment succeeds. I then verify it in the pipeline's run history and the container app's activity log.
The following Azure resources must be available in your Resource group named RG1:
- A Container registry instance that contains one image.
- A Virtual network with subnets.
- A Service Bus Namespace
- A Managed Identity
- A Private endpoint
- A Container App
- A Container Apps Environment
You've been asked to configure a continuous integration environment for Container Apps that meets the following requirements:
- You need an Azure Container Apps deployment task in your Azure DevOps environment.
-
Pipeline1must deploy a container image from your container registry to your container app using a self-hosted agent pool. - You must ensure that the pipeline successfully deploys the image at least once.
You complete the following tasks during this exercise:
1.Configure Pipeline1 to use the self-hosted agent pool.
2.Configure Pipeline1 with an Azure Container Apps deployment task.
3.Run the Pipeline1 deployment task.
4.Verify the configuration.
Configure Pipeline1 to use the self-hosted agent pool
1.Open a browser window, navigate to https://dev.azure.com, and then open your Azure DevOps organization.
2.On your Azure DevOps page, to open your DevOps project, select Project1.
3.In the left-side menu, select Pipelines.
4.Select Pipeline1, and then select Edit.
5.To use the self-hosted agent pool, update the azure-pipelines.yml file as shown in the following example:
trigger:
- main
pool:
name: default
steps:
Recall that the pool section specifies the agent pool to use for the pipeline. The name property specifies the name of the agent pool. In this case, the name is default, which is the pool you configured as a self-hosted agent pool.
6.Under Validate and save, select Save without validating.
7.Enter a commit message, and then select Save.
Configure Pipeline1 with an Azure Container Apps deployment task
1.Ensure that you have Pipeline1 open for editing.
2.On the right side under Tasks, in the Search tasks field, enter azure container
3.In the filtered list of tasks, select Azure Container Apps Deploy
4.Under Azure Resource Manager connection, select the Subscription you're using, and then select Authorize.
5.In the Azure portal tab, open your Container App resource, and then open the Containers page.
6.Use the information on the Containers page to configure the following Pipeline1 Task information:
- Docker Image to Deploy:
<Registry>/<Image>:<Image tag> - Azure Container App name:
<Name>
7.Configure the following Pipeline1 Task information:
- Azure Resource group name: RG1
Note
If you need to verify the resource group name, you can find it on the Overview page of your Container App resource.
8.On the Azure Container Apps Deploy page, select Add.
The Yaml file for your pipeline should now include the AzureContainerApps tasks as follows:
trigger:
- main
pool:
name: default
steps:
- task: AzureContainerApps@1
inputs:
azureSubscription: '<Subscription>(<Subscription ID>)'
imageToDeploy: '<Registry>/<Image>:<Image tag>' from Container App resource
containerAppName: '<Name>' from Container App resource
resourceGroup: '<resource group name>'
Here's an example that shows a YAML configuration snippet:
trigger:
- main
pool:
name: default
steps:
- task: AzureContainerApps@1
inputs:
azureSubscription: 'Visual Studio Enterprise(1111aaaa-22bb-33cc-44dd-555555eeeeee)'
imageToDeploy: 'acraz2003cah12oct.azurecr.io/aspnetcorecontainer:latest'
containerAppName: 'aca-az2003'
resourceGroup: 'RG1'
9.Select Validate and save, and then select Save again to commit directly to the main branch.
The contents of the YAML file must be formatted correctly, including indentation. If you encounter an error, review the YAML file and correct any indentation issues.
10.Navigate back to the main page of your pipeline.
Run the Pipeline1 deployment task
1.Ensure that you have Pipeline1 open in Azure DevOps.
2.On the Runs tab of the Pipeline1 page, select Run pipeline.
A Run pipeline page opens to display the associated job.
3.Select Run.
The Jobs section displays job status, which progresses from Queued to Waiting.
It can take a couple minutes for the status to transition from Queued to Waiting.
4.If a 'Permission needed' message is displayed ("This pipeline needs permission to access 2 resources before this run can continue"), select View and then provide the required permissions.
5.Monitor the status of the run operation and verify that the run is successful.
It wasn't successful, so I updated the yaml file to include the subscription.
The Azure connection now works. The log shows the login succeeded and containerapp show found aca-az2026. The error "spawnSync az ENOENT" means the task tried to run az to log in to your registry, and Windows couldn't find it. The task runs az in a way that doesn't work with the Windows az.cmd file.
The solution is to give the task your registry username and password, so it logs in with those and skips az for that step. I'll get the Registry credential from the Azure portal.
- Go to Settings → Access keys.
- Then Switch Admin user on.
- Copy the Username (usually the same as the registry name) and one of the Passwords.
Then store the password as a secret:
- In Pipeline1, click Edit, then Variables → New variable.
- Name: acrPassword
- Value: paste the password.
- Tick Keep this value secret, then click OK and Save.
Docker permissions issue:
- Open Computer Management → Local Users and Groups → Groups → docker-users.
- Click Add, add your Windows user, and click OK.
- Sign out of Windows and sign back in.
Start Docker Desktop, then start the agent again from PowerShell as administrator (cd C:\agents, then .\run.cmd).
Then click Run pipeline.
This Screenshot of Azure Pipelines is showing a successful run of Pipeline1.
Check your work
In this task, you examine your pipeline and container app to verify successful pipeline runs.
1.Ensure that you have Project1 open in Azure DevOps.
2.On the left side menu, select Pipelines, and then select Pipeline1.
3.The Runs tab displays individual runs that can be selected to review details.
4.Open your Azure portal, and then open your Container App.
5.On the left side menu, select Activity Log.
6.Verify that a Create or Update Container App operation succeeded as a result of running your pipeline.
Summary
Cloud and DevOps practitioner building hands-on Azure skills through a five-part series on Azure Container Apps.
Part 4 covers continuous integration with Azure Pipelines:
Configured an Azure Pipeline to run on a self-hosted Windows agent pool
Added the Azure Container Apps deployment task to deploy an image from Azure Container Registry to the container app
Troubleshot a failed run, including the "spawnSync az ENOENT" error and Docker permission issues on the agent, until the deployment succeeded
Verified the result in the pipeline run history and the container app's activity log.
Skills practiced:
Azure DevOps, Azure Pipelines, YAML pipelines, CI/CD, self-hosted agents, Azure Container Apps, Docker, troubleshooting




















Top comments (2)
My first pipeline run failed, and that turned out to be the most useful part of this project. I traced a spawnSync az ENOENT error on the Windows self-hosted agent, fixed the Docker permissions, and reran until the deployment to Azure Container Apps succeeded. I documented the fixes so others don't lose the same time.
Part 4 automates deployments from Azure Container Registry to Azure Container Apps with Azure Pipelines and a self-hosted agent. I used the registry's admin credentials as a lab workaround. For production, would you use a managed identity or a service connection instead? I'd like to hear what's worked for your team. One part left in the series.