0

Well, everyone keeps saying to try to learn something new during this pandemic, so that's what I'm trying to do. I'm brand new to YAML and Docker, and fairly new to ARM templates.

I've been able to use YAML to build and publish .NET Core apps using the dotnet YAML commands. I've been able to use YAML to build a Docker image of a .NET Core 3.1 Web API app.

I'm publishing the docker image to an Azure Resource Container.

Where I'm stuck:

Ideally, I want to use ARM templates in the .NET Core project to be able to deploy my Azure Portal resources via code vs creating manually in the portal. This should include the Azure Resource Container.

It seems like what I need to do to accomplish this is build the docker image during the Build phase and then publish that to the $(System.ArtifactsDirectory) so that I can hold it there until the Azure Resources have been deployed via ARM templates.

I can't find anything about publishing the docker image as a pipeline artifact though. Only things about pushing to DockerHub, GitHub, and Azure Resource Containers, which isn't what I want to do right now.

Anyone have any ideas how I can pull this off?

Don Sartain
  • 557
  • 9
  • 25
  • You publish your container to an Azure Container Registry. Containers aren't build artifacts in the traditional sense. – Daniel Mann Jul 17 '20 at 22:33

2 Answers2

1

I actually found a way to pull this off. The article I read about this is over on dev.to

There are a few things that I needed to do to pull this off.

First, don't set the containerRegistry on build.

- task: Docker@2
  displayName: Build Docker Image
  inputs:            
    repository: $(imageName)
    command: build
    dockerfile: '**/Dockerfile'
    buildContext: 'HopefulMommaDesignsAPI'
    tags: $(Build.BuildId)

The reason for this is because if you set the container registry then, with ACR at least, it prefixes the ACR URL to the docker image name. However, that URL is encrypted when doing this in Azure DevOps. There's nothing wrong with that, but it causes confusion when you list images because it will show up as ***/ImageName.

Second, save the image as a TAR file in the artifact staging directory.

- task: Docker@2
  displayName: 'Save image to TAR'
  inputs:
    repository: '$(imageName)'
    command: save            
    arguments: '--output $(build.artifactstagingdirectory)/$(imageName).image.tar $(imageName):$(Build.BuildId)'
    addPipelineData: false   

That will include the .tar file when you publish your build.

The next steps are during the deploy jobs.

After you have downloaded the build artifact and deployed the ARM templates, you'll need to load the docker image from the .tar file.

- task: Docker@2
  displayName: 'Load Image from Tar'
  inputs: 
    command: load
    arguments: '--input $(build.artifactstagingdirectory)/$(buildArtifactName)/$(imageName).image.tar'

Now that the docker image has been loaded you'll want to ReTag the image and publish it.

- task: Docker@2
  displayName: 'ReTag Image with ACR URL - BuildId'
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'
    repository: $(imageName)
    command: tag
    arguments: '$(imageName):$(Build.BuildId) $(containerRegistryUrl)/$(imageName):$(Build.BuildId)'
- task: Docker@2
  displayName: 'ReTag Image with ACR URL - latest'
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'
    repository: $(imageName)
    command: tag
    arguments: '$(imageName):$(Build.BuildId) $(containerRegistryUrl)/$(imageName):latest'
      
- task: Docker@2
  displayName: push
  inputs:
    containerRegistry: 'Hopeful Momma Designs ACR'    
    repository: $(imageName)       
    command: push
    dockerfile: '**/Dockerfile'
    buildContext: 'HopefulMommaDesignsAPI'  
    tags: |
      $(Build.BuildId)
      latest

NOTE: If your Azure Container Registry is part of your ARM template, the Docker commands where you include the containerRegistry will fail because you have to manually set up the service connection from Azure DevOps to the Azure Container Registry before you can reference it in your YAML files as the containerRegistry.

This isn't a huge deal for me because I will normally work on pipelines in sections anyway. I'll make sure the build works, then I'll make sure the ARM templates work, then I'll make sure the docker images pushes to the ACR. If you're rebuilding an environment from scratch, just comment out the deployment steps after the ARM template step to deploy the infrastructure and then uncomment the remaining steps. It isn't the cleanest solution, but I like that better than having a separate pipeline just to deploy infrastructure.

Don Sartain
  • 557
  • 9
  • 25
0

You publish your container to an Azure Container Registry. Containers aren't build artifacts in the traditional sense.

I suspect that you have a chicken/egg problem. You want to create the registry during your deployment process, but you don't have a registry during the build process. So how can you deploy your container to a registry that won't exist until the next phase, right? In fact, you'll discover that you need to create a service connection for the ACR before you can publish resources to it. The ARM template isn't going to be able to do that for you.

This is a case where it's common to separate the application's requirements from larger infrastructural requirements. The ACR is a supporting piece of infrastructure. It's common in cases like this to have a separate pipeline that creates required supporting infrastructure to solve the chicken-and-egg problem.

Also, please be aware of correct terminology. There's nothing called an "Azure Resource Container". There is something called an "Azure Container Registry", which is what I assume you're talking about.

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
  • Yes, I meant the Azure Container Registry. I can see how I may need to create the ACR first manually or through a different pipeline. What about the App Service that I would load the docker image into though, or is that just something that is completely different that I haven't come across yet? – Don Sartain Jul 18 '20 at 03:21
  • @DonSartain https://blog.ehn.nu/2019/01/deploy-azure-web-app-for-containers-with-arm-and-azure-devops/ – Daniel Mann Jul 18 '20 at 04:08