0

I am facing an implementation issues with the below scenario using Azure DevOps pipelines

  1. Provision two resources in Azure Subscription using ARM templates
    • Azure Container Registry
    • Azure Kubernetes Services
  2. Deploy the containerized application code to the Kubernetes clusters

I am able to perform both of the steps in an individual pipelines. Need some help with combining/integrating two pipelines into one.

How can I automate both of the above steps without having any manual intervention in the process. The process must be robust enough to handle the Application deployment in the same ACR and AKS that was created in the previous step?

Both the Infrastructure and the Application code resides in the same GIT/ Azure Repository.

2 Answers2

0

First of all. I would like to recommend that you do not tie the two pipeline together.

While infrastructure as code is important and should be used. It is important to decouple the infrastructure provisioning from the application provisioning for many good reasons.

Regarding you ask, you should have a task that create the ACR/AKS, one task that gets the credentials to be used in another task which would deploy to the ore created AKS ans ACR

The flow could be.

ACR —AKS (if you want to configure your AKS with ACR integration, you need to have them sequential) — docker build/push to ACR — deploy container using shell script with KubeCTL leveraging the credentials from second step.

djsly
  • 1,522
  • 11
  • 13
0

You can use multiple stages in one yaml pipeline. See below simple example:

Below yaml pipeline has two stages. The first stage do the tasks to provision the Infrastructure. The second stage is dependsOn the first stage, and defined the ACR and AKS in the variables, then do the tasks to deploy to the Kubernetes clusters.

trigger: 
- master

stages:
- stage: Infrastructure Deployment
  pool:
    vmImage: windows-latest 
  jobs:
  - job: Infrastructure
    steps:

    - task: AzureResourceManagerTemplateDeployment@3
      inputs:
      .....

- stage: Application Deployment
  dependsOn: Infrastructure Deployment
  pool: 
    vmImage: windows-latest
  variables: 
    ACRName: "ACRName"
    AKSName: "ACRName"
    azureSubscriptionEndpoint: ..
    azureContainerRegistry: ..
    azureResourceGroup: ..
  jobs:
  - job: Application
    steps:

    # - task: Docker@2
    #   inputs:  
    #     containerRegistry: $(ACRName)
    #     ...

    - powershell: |
        # Log in to Docker with service principal credentials
        docker login $(ACRName).azurecr.io --username $SP_APP_ID --password $SP_PASSWD
        docker build
        docker push

    - task: Kubernetes@1
      displayName: kubectl apply
      inputs:
        connectionType: Azure Resource Manager
        azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
        azureResourceGroup: $(azureResourceGroup)
        kubernetesCluster: $(AKSName)
        ....

Update: dynamically capture the ACR and AKS name along with ACR login credentials

You can use azure powershell task to get above data. In order to use azure powershell task, you need to create a azure resource manager service connection.

Then you can write custom inline scripts in the task. See below example:

    - task: AzurePowerShell@5
      name: AzurePowershell
      inputs:
        azureSubscription: 'Microsoft Azure Internal Consumption (daaeef3e-d7fe-49e8-baaa-b3df9d072825)'
        ScriptType: InlineScript
        Inline: |
          $json = (Get-Content "$(system.defaultworkingdirectory)\template.json" -Raw) | ConvertFrom-Json
          
          $AKS = $json.resources | where {$_.type -eq "Microsoft.ContainerService/managedClusters"} | select name
          $ACR = $json.resources | where {$_.type -eq "Microsoft.ContainerRegistry/registries"} | select name
          
          echo "##vso[task.setvariable variable=ACRName;isOutput=true]$($ACR.name)"
          echo "##vso[task.setvariable variable=AKSName;isOutput=true]$($AKS.name)"
          
          $ACRCred = Get-AzContainerRegistryCredential -ResourceGroupName "MyResourceGroup" -Name $($ACR.name)
          
          echo "##vso[task.setvariable variable=UserName;isOutput=true]$($ACRCred.Username)"
          echo "##vso[task.setvariable variable=Password;isOutput=true]$($ACRCred.Password)"
         
        azurePowerShellVersion: LatestVersion

You can then get these variables in the following stage by referring to stageDependencies.stageName.jobName.outputs['stepName.variableName']

See here for more azure powershell cli.

Levi Lu-MSFT
  • 27,483
  • 2
  • 31
  • 43
  • Is there any way to dynamically capture the ACR and AKS name along with ACR login credentials, which can be passed to the Application Deployment stage of the pipelines ? – programmerP Jul 03 '20 at 04:40
  • Hi @programmerP You can use a azure powershell task to get the resource's name in the template.json. and using logging command to set the value to an output variable. Please check out above update: – Levi Lu-MSFT Jul 03 '20 at 07:14