DEV Community

Cover image for Dynamic deployment of sonarqube in az container instance using Devops
Arindam Mitra
Arindam Mitra

Posted on • Edited on

Dynamic deployment of sonarqube in az container instance using Devops

Greetings my fellow Technology Advocates and Specialists.

In this Session, I will demonstrate how to Dynamically Deploy SONARQUBE in AZURE CONTAINER INSTANCE using AZURE DEVOPS PIPELINES

LIVE RECORDED SESSION:-
LIVE DEMO was Recorded as part of my Presentation in CLOUD LUNCH AND LEARN Forum/Platform
Duration of My Demo = 44 Mins 19 Secs
REQUIREMENTS:-
  1. Azure Subscription
  2. Azure DevOps Organisation and Project
  3. Azure Resource Manager Service Connection
CODE REPOSITORY:-

GitHub logo arindam0310018 / 24-Apr-2022-DevOps__Dynamic-Deployment-Of-SonarQube-In-ACI

DYNAMIC DEPLOYMENT OF SONARQUBE IN AZ CONTAINER INSTANCE USING DEVOPS

DYNAMIC DEPLOYMENT OF SONARQUBE IN AZ CONTAINER INSTANCE USING DEVOPS

Greetings my fellow Technology Advocates and Specialists.

In this Session, I will demonstrate how to Dynamically Deploy SONARQUBE in AZURE CONTAINER INSTANCE using AZURE DEVOPS PIPELINES

LIVE RECORDED SESSION:-
LIVE DEMO was Recorded as part of my Presentation in CLOUD LUNCH AND LEARN Forum/Platform
Duration of My Demo = 44 Mins 19 Secs
IMAGE ALT TEXT HERE
REQUIREMENTS:-
  1. Azure Subscription
  2. Azure DevOps Organisation and Project
  3. Azure Resource Manager Service Connection
Below follows the contents of the YAML File (Azure DevOps):-
trigger
  none

######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
  displayName: Please Provide the Subscription ID:-
  type: object
  default: 210e66cb-55cf-424e-8daa-6cad804ab604

- name: ServiceConnection
  displayName: Please Provide the Service Connection Name:-
  default: amcloud-cicd-service-connection
  values:
  - amcloud-cicd-service-connection

- name: RGName
  displayName: Please Provide the Name of the Resource Group:-
  type: object
  default: DemoRGSonarQube

- name: RGLocation
  displayName: Please Provide Location of Resource Group:-
  default: WestEurope
  values:
…
Below follows the contents of the YAML File (Azure DevOps):-
trigger:
  none

######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
  displayName: Please Provide the Subscription ID:-
  type: object
  default: 210e66cb-55cf-424e-8daa-6cad804ab604

- name: ServiceConnection
  displayName: Please Provide the Service Connection Name:-
  default: amcloud-cicd-service-connection
  values:
  - amcloud-cicd-service-connection

- name: RGName
  displayName: Please Provide the Name of the Resource Group:-
  type: object
  default: DemoRGSonarQube

- name: RGLocation
  displayName: Please Provide Location of Resource Group:-
  default: WestEurope
  values:
  - WestEurope

- name: validateIfRGExists
  displayName: Does the provided Resource Group Exists or do we create ?
  default: Existing
  values:
  - Existing
  - New

- name: ACIName
  displayName: Please Provide the Name of the Azure Container Instance:-
  type: object
  default: am-poc-sonarqube-aci

######################
#DECLARE VARIABLES:-
######################
variables:
  Artifact: AM
  cpu: 2 
  memory: 3.5
  port: 9000

#########################
# Declare Build Agents:-
#########################
pool:
  vmImage: windows-latest

###################
# Declare Stages:-
###################
stages:

- stage: VALIDATE_SELECTION_EXISTING
  condition: |
     and(eq('${{ parameters.validateIfRGExists }}', 'Existing'), 
       eq(variables['build.sourceBranch'], 'refs/heads/main')) 
  jobs:
  - job: IF_RG_EXISTS_DEPLOY_SONARQUBE 
    displayName: IF RG EXISTS DEPLOY SONARQUBE
    steps:
    - task: AzureCLI@2
      displayName: CHECK RG AND DEPLOY SONARQUBE
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show  
          $i = az group exists -n ${{ parameters.RGName }}
          if ($i -eq "true") {
          $j = az container list --query "[?contains(name, '${{ parameters.ACIName }}')].[provisioningState]" -o tsv
            if ($j -eq "Succeeded") {
            echo "##########################################################################################################################################"
            echo "${{ parameters.ACIName }} CONTAINER INSTANCE EXISTS IN THE ${{ parameters.RGName }} RESOURCE GROUP. CANNOT PROCEED WITH THE DEPLOYMENT"
            echo "##########################################################################################################################################"  
              }
            else {   
            az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)
              }
            }
          else {
          az group create -l ${{ parameters.RGLocation }} -n ${{ parameters.RGName }} 
          az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)    
            }

- stage: VALIDATE_SELECTION_NEW
  condition: |
     and(eq('${{ parameters.validateIfRGExists }}', 'New'), 
       eq(variables['build.sourceBranch'], 'refs/heads/main')) 
  jobs:
  - job: CREATE_RG_AND_DEPLOY_SONARQUBE 
    displayName: CREATE RG AND DEPLOY SONARQUBE
    steps:
    - task: AzureCLI@2
      displayName: CHECK RG AND DEPLOY SONARQUBE
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show  
          $i = az group exists -n ${{ parameters.RGName }}
          if ($i -eq "true") { 
          $j = az container list --query "[?contains(name, '${{ parameters.ACIName }}')].[provisioningState]" -o tsv
            if ($j -eq "Succeeded") {
            echo "##########################################################################################################################################"
            echo "${{ parameters.ACIName }} CONTAINER INSTANCE EXISTS IN THE ${{ parameters.RGName }} RESOURCE GROUP. CANNOT PROCEED WITH THE DEPLOYMENT"
            echo "##########################################################################################################################################"  
              }
            else {   
            az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)
              }
            }             
          else {
          az group create -l ${{ parameters.RGLocation }} -n ${{ parameters.RGName }} 
          az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)    
            }

Enter fullscreen mode Exit fullscreen mode

Let me explain each part of YAML Pipeline for better understanding.

PART #1:-
BELOW FOLLOWS PIPELINE RUNTIME VARIABLES CODE SNIPPET:-
######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
  displayName: Please Provide the Subscription ID:-
  type: object
  default: 210e66cb-55cf-424e-8daa-6cad804ab604

- name: ServiceConnection
  displayName: Please Provide the Service Connection Name:-
  default: amcloud-cicd-service-connection
  values:
  - amcloud-cicd-service-connection

- name: RGName
  displayName: Please Provide the Name of the Resource Group:-
  type: object
  default: DemoRGSonarQube

- name: RGLocation
  displayName: Please Provide Location of Resource Group:-
  default: WestEurope
  values:
  - WestEurope

- name: validateIfRGExists
  displayName: Does the provided Resource Group Exists or do we create ?
  default: Existing
  values:
  - Existing
  - New

- name: ACIName
  displayName: Please Provide the Name of the Azure Container Instance:-
  type: object
  default: am-poc-sonarqube-aci
Enter fullscreen mode Exit fullscreen mode
THIS IS HOW IT LOOKS WHEN YOU EXECUTE THE PIPELINE FROM AZURE DEVOPS:-
Image description
NOTE:-
Please feel free to change the name of the RESOURCE GROUP NAME and the NAME OF THE AZURE CONTAINER INSTANCE.
PART #2:-
BELOW FOLLOWS PIPELINE VARIABLES CODE SNIPPET:-
######################
#DECLARE VARIABLES:-
######################
variables:
  Artifact: AM
  cpu: 2 
  memory: 3.5
  port: 9000

Enter fullscreen mode Exit fullscreen mode
NOTE:-
Please feel free to change the values of the variables.
The entire YAML pipeline is build using Parameters and variables. No Values are Hardcoded.
PART #3:-
PIPELINE STAGES:-
There are 2 Stages in the Pipeline 1) When User selects "EXISTING" Pipeline Runtime Environment 2) When User selects "NEW" Pipeline Runtime Environment
Pipeline Stage gets SKIPPED or EXECUTED based on the User Choice
BELOW FOLLOWS PIPELINE STAGE "EXISTING" CODE SNIPPET:-
- stage: VALIDATE_SELECTION_EXISTING
  condition: |
     and(eq('${{ parameters.validateIfRGExists }}', 'Existing'), 
       eq(variables['build.sourceBranch'], 'refs/heads/main')) 
  jobs:
  - job: IF_RG_EXISTS_DEPLOY_SONARQUBE 
    displayName: IF RG EXISTS DEPLOY SONARQUBE
    steps:
    - task: AzureCLI@2
      displayName: CHECK RG AND DEPLOY SONARQUBE
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show  
          $i = az group exists -n ${{ parameters.RGName }}
          if ($i -eq "true") {
          $j = az container list --query "[?contains(name, '${{ parameters.ACIName }}')].[provisioningState]" -o tsv
            if ($j -eq "Succeeded") {
            echo "##########################################################################################################################################"
            echo "${{ parameters.ACIName }} CONTAINER INSTANCE EXISTS IN THE ${{ parameters.RGName }} RESOURCE GROUP. CANNOT PROCEED WITH THE DEPLOYMENT"
            echo "##########################################################################################################################################"  
              }
            else {   
            az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)
              }
            }
          else {
          az group create -l ${{ parameters.RGLocation }} -n ${{ parameters.RGName }} 
          az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)    
            }

Enter fullscreen mode Exit fullscreen mode
BELOW FOLLOWS PIPELINE STAGE "NEW" CODE SNIPPET:-
- stage: VALIDATE_SELECTION_NEW
  condition: |
     and(eq('${{ parameters.validateIfRGExists }}', 'New'), 
       eq(variables['build.sourceBranch'], 'refs/heads/main')) 
  jobs:
  - job: CREATE_RG_AND_DEPLOY_SONARQUBE 
    displayName: CREATE RG AND DEPLOY SONARQUBE
    steps:
    - task: AzureCLI@2
      displayName: CHECK RG AND DEPLOY SONARQUBE
      inputs:
        azureSubscription: ${{ parameters.ServiceConnection }}
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show  
          $i = az group exists -n ${{ parameters.RGName }}
          if ($i -eq "true") { 
          $j = az container list --query "[?contains(name, '${{ parameters.ACIName }}')].[provisioningState]" -o tsv
            if ($j -eq "Succeeded") {
            echo "##########################################################################################################################################"
            echo "${{ parameters.ACIName }} CONTAINER INSTANCE EXISTS IN THE ${{ parameters.RGName }} RESOURCE GROUP. CANNOT PROCEED WITH THE DEPLOYMENT"
            echo "##########################################################################################################################################"  
              }
            else {   
            az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)
              }
            }             
          else {
          az group create -l ${{ parameters.RGLocation }} -n ${{ parameters.RGName }} 
          az container create -g ${{ parameters.RGName }} --name ${{ parameters.ACIName }} --image sonarqube --ports $(port) --dns-name-label ${{ parameters.ACIName }} --cpu $(cpu) --memory $(memory)    
            }

Enter fullscreen mode Exit fullscreen mode
PART #4:-
PIPELINE STAGE VALIDATE_SELECTION_EXISTING CONDITIONS:-
## CONDITIONS APPLIED
1. When User selects "Existing" Pipeline Runtime Environment, it means that the mentioned RESOURCE GROUP (RG) Exists in the Subscription.
2. Pipeline when executed first validates if RG Exists.
3. If RG EXISTS, it will then validate if the mentioned Azure Container Instance (ACI), provided using Pipeline Runtime Variables exists. If ACI exists, No Action to be Taken. If ACI does not Exists, Deploy ACI with SonarQube Image
4. If RG DOES NOT EXISTS, it will first deploy RG and then ACI with SonarQube Image
PART #5:-
PIPELINE STAGE VALIDATE_SELECTION_NEW CONDITIONS:-
## CONDITIONS APPLIED
1. When User selects "New" Pipeline Runtime Environment, it means that the mentioned RESOURCE GROUP (RG) does not Exists in the Subscription.
2. Pipeline when executed first validates if RG Exists.
3. If RG EXISTS, it will then validate if the mentioned Azure Container Instance (ACI), provided using Pipeline Runtime Variables exists. If ACI exists, No Action to be Taken. If ACI does not Exists, Deploy ACI with SonarQube Image
4. If RG DOES NOT EXISTS, it will first deploy RG and then ACI with SonarQube Image
PART #6:-

VALIDATE THE YAML DEPLOYMENT WITH BELOW TEST CASES.

TEST CASE #1: SELECT "NEW" (There is No RG and ACI with SonarQube Image):-
Desired Output: RG + ACI with SonarQube Image Gets Deployed.
PIPELINE VARIABLES:
Image description
PIPELINE RESULTS:
Image description
Image description
SonarQube URL: http://am-poc-sonarqube-aci.westeurope.azurecontainer.io:9000/
Image description
TEST CASE #2: SELECT "EXISTING" (RG and ACI with SonarQube Image already Exists):-
Desired Output: No Action Performed.
PIPELINE VARIABLES:
Image description
PIPELINE RESULTS:
Image description
Image description
Image description
SonarQube URL: http://am-poc-sonarqube-aci.westeurope.azurecontainer.io:9000/
Image description
TEST CASE #3: SELECT "NEW" (RG and ACI with SonarQube Image already Exists):-
Desired Output: No Action Performed.
PIPELINE VARIABLES:
Image description
PIPELINE RESULTS:
Image description
Image description
Image description
SonarQube URL: http://am-poc-sonarqube-aci.westeurope.azurecontainer.io:9000/
Image description
TEST CASE #4: SELECT "EXISTING" (RG Exists but there is No ACI with SonarQube Image):-
Desired Output: ACI with SonarQube Image gets Deployed Only.
PIPELINE VARIABLES:
Image description
PIPELINE RESULTS:
Image description
Image description
Image description
SonarQube URL: http://am-poc-sonarqube-aci.westeurope.azurecontainer.io:9000/
Image description
TEST CASE #5: SELECT "NEW" (RG Exists but there is No ACI with SonarQube Image):-
Desired Output: ACI with SonarQube Image gets Deployed Only.
PIPELINE VARIABLES:
Image description
PIPELINE RESULTS:
Image description
Image description
Image description
SonarQube URL: http://am-poc-sonarqube-aci.westeurope.azurecontainer.io:9000/
Image description

Hope You Enjoyed the Session!!!

Stay Safe | Keep Learning | Spread Knowledge

Top comments (0)