DEV Community

Cover image for Reset service principal secret and store in key vault using Az Devops
Arindam Mitra
Arindam Mitra

Posted on • Updated on

Reset service principal secret and store in key vault using Az Devops

Greetings to my fellow Technology Advocates and Specialists.

In this Session, I will demonstrate How to Reset Service Principal Secret and Store in Key Vault Using Azure DevOps.

I had the Privilege to talk on this topic in TWO Azure Communities:-

NAME OF THE AZURE COMMUNITY TYPE OF SPEAKER SESSION
Journey to the Cloud 9.0 Virtual
Festive Tech Calendar 2022 Virtual
LIVE RECORDED SESSION:-
LIVE DEMO was Recorded as part of my Presentation in JOURNEY TO THE CLOUD 9.0 Forum/Platform
Duration of My Demo = 55 Mins 42 Secs
LIVE DEMO was Recorded as part of my Presentation in FESTIVE TECH CALENDAR 2022 Forum/Platform
Duration of My Demo = 1 Hour 05 Mins 08 Secs
USE CASE:-
Cloud Engineer DOES NOT have access to Azure Active Directory (AAD) to Reset Service Principal Secret.
Cloud Engineer CANNOT ELEVATE rights using PIM (Privileged Identity Management) to Reset Service Principal Secret.
AUTOMATION OBJECTIVE:-
Validate If the Service Principal Exists. If No, Pipeline will FAIL.
Validate If Resource Group Containing Key Vault Exists. If No Resource Group Found, Pipeline will FAIL.
Validate If Key Vault Exists inside the Specified Resource Group. If No Key Vault Found, Pipeline will FAIL.
If All of the above validation is SUCCESSFUL, Pipeline will then Reset the Service Principal Secret and Store it in the Key Vault.
IMPORTANT NOTE:-

The YAML Pipeline is tested on WINDOWS BUILD AGENT Only!!!

REQUIREMENTS:-
  1. Azure Subscription.
  2. Azure DevOps Organisation and Project.
  3. Service Principal either assigned Global Administrator Privileged Identity Management (PIM) Azure AD Role or Required Microsoft Graph API Rights (Directory.ReadWrite.All: Read and Write Directory Data).
  4. Service Principal with Required RBAC ( Contributor) applied on Subscription or Resource Group(s).
  5. Azure Resource Manager Service Connection in Azure DevOps.
CODE REPOSITORY:-

GitHub logo arindam0310018 / 17-Aug-2022-DevOps__Reset-SPI-Secret-Store-In-KV

RESET SERVICE PRINCIPAL SECRET AND STORE IN KEY VAULT USING AZ DEVOPS

RESET SERVICE PRINCIPAL SECRET AND STORE IN KEY VAULT USING AZ DEVOPS

Greetings to my fellow Technology Advocates and Specialists.

In this Session, I will demonstrate How to Reset Service Principal Secret and Store in Key Vault Using Azure DevOps.

I had the Privilege to talk on this topic in TWO Azure Communities:-

NAME OF THE AZURE COMMUNITY TYPE OF SPEAKER SESSION
Journey to the Cloud 9.0 Virtual
Festive Tech Calendar 2022 Virtual
LIVE RECORDED SESSION:-
LIVE DEMO was Recorded as part of my Presentation in JOURNEY TO THE CLOUD 9.0 Forum/Platform
Duration of My Demo = 55 Mins 42 Secs
IMAGE ALT TEXT HERE
LIVE DEMO was Recorded as part of my Presentation in FESTIVE TECH CALENDAR 2022 Forum/Platform
Duration of My Demo = 1 Hour 05 Mins 08 Secs
IMAGE ALT TEXT HERE
USE CASE:-
Cloud Engineer DOES NOT have access to Azure Active Directory (AAD) to Reset Service Principal Secret.
Cloud Engineer CANNOT ELEVATE rights
HOW DOES MY CODE PLACEHOLDER LOOKS LIKE:-
Image description
PIPELINE CODE SNIPPET:-
AZURE DEVOPS YAML PIPELINE (azure-pipelines-spi-reset-secret-v1.0.yml):-
trigger:
  none

######################
#DECLARE PARAMETERS:-
######################
parameters:
- name: SubscriptionID
  displayName: Subscription ID Details Follow Below:-
  type: string
  default: 210e66cb-55cf-424e-8daa-6cad804ab604
  values:
  - 210e66cb-55cf-424e-8daa-6cad804ab604

- name: RGNAME
  displayName: Please Provide the Resource Group Name:-
  type: object
  default: 

- name: KVNAME
  displayName: Please Provide the Keyvault Name:-
  type: object
  default: 

- name: SPINAME
  displayName: Please Provide the Service Principal Name:-
  type: object
  default:

######################
#DECLARE VARIABLES:-
######################
variables:
  ServiceConnection: amcloud-cicd-service-connection
  BuildAgent: windows-latest

#########################
# Declare Build Agents:-
#########################
pool:
  vmImage: $(BuildAgent)

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

stages:

- stage: RESET_SECRET_SERVICE_PRINCIPAL 
  jobs:
  - job: RESET_SECRET_SERVICE_PRINCIPAL 
    displayName: RESET SECRET SERVICE PRINCIPAL
    steps:
    - task: AzureCLI@2
      displayName: Reset SPI Secret
      inputs:
        azureSubscription: $(ServiceConnection)
        scriptType: ps
        scriptLocation: inlineScript
        inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show
          $i = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appDisplayName -o tsv
          if ($i -eq "${{ parameters.SPINAME }}") {
            $j = az group exists -n ${{ parameters.RGNAME }}
                if ($j -eq "true") {
                  $k = az keyvault list --resource-group ${{ parameters.RGNAME }} --query [].name -o tsv        
                      if ($k -eq "${{ parameters.KVNAME }}") {
                        $spiappid = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appId -o tsv
                        $spireset = az ad sp credential reset --id $spiappid --query "password" -o tsv
                        az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spireset
                        echo "##################################################################"
                        echo "The Reset of Service Principal ${{ parameters.SPINAME }} secret was successful. The New Secret was then Stored inside Key Vault ${{ parameters.KVNAME }} in the Resource Group ${{ parameters.RGNAME }}!!!"
                        echo "##################################################################"
                        }               
                      else {
                      echo "####################################################################################################"
                      echo "Key Vault ${{ parameters.KVNAME }} DOES NOT EXISTS in Resource Group ${{ parameters.RGNAME }}!!!"
                      echo "####################################################################################################"
                      exit 1
                          }
                }
                else {
                echo "##################################################################"
                echo "Resource Group ${{ parameters.RGNAME }} DOES NOT EXISTS!!!"
                echo "##################################################################"
                exit 1
                    }
          }
          else {
          echo "####################################################################################################################"
          echo "Service Principal ${{ parameters.SPINAME }} DOES NOT EXISTS and hence Cannot Proceed with the Reset of Secret!!!"
          echo "####################################################################################################################"
          exit 1
              }

Enter fullscreen mode Exit fullscreen mode

Now, 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: Subscription ID Details Follow Below:-
  type: string
  default: 210e66cb-55cf-424e-8daa-6cad804ab604
  values:
  - 210e66cb-55cf-424e-8daa-6cad804ab604

- name: RGNAME
  displayName: Please Provide the Resource Group Name:-
  type: object
  default: 

- name: KVNAME
  displayName: Please Provide the Keyvault Name:-
  type: object
  default: 

- name: SPINAME
  displayName: Please Provide the Service Principal Name:-
  type: object
  default:

Enter fullscreen mode Exit fullscreen mode
PART #2:-
BELOW FOLLOWS PIPELINE VARIABLES CODE SNIPPET:-
######################
#DECLARE VARIABLES:-
######################
variables:
  ServiceConnection: amcloud-cicd-service-connection
  BuildAgent: windows-latest

Enter fullscreen mode Exit fullscreen mode
NOTE:-
Please change the values of the variables accordingly.
The entire YAML pipeline is build using Runtime Parameters and Variables. No Values are Hardcoded.
PART #3:-
BELOW FOLLOWS THE CONDITIONS AND LOGIC DEFINED IN THE PIPELINE (AS MENTIONED ABOVE IN THE "AUTOMATION OBJECTIVE"):-
inlineScript: |
          az --version
          az account set --subscription ${{ parameters.SubscriptionID }}
          az account show
          $i = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appDisplayName -o tsv
          if ($i -eq "${{ parameters.SPINAME }}") {
            $j = az group exists -n ${{ parameters.RGNAME }}
                if ($j -eq "true") {
                  $k = az keyvault list --resource-group ${{ parameters.RGNAME }} --query [].name -o tsv        
                      if ($k -eq "${{ parameters.KVNAME }}") {
                        $spiappid = az ad sp list --display-name ${{ parameters.SPINAME }} --query [].appId -o tsv
                        $spireset = az ad sp credential reset --id $spiappid --query "password" -o tsv
                        az keyvault secret set --name ${{ parameters.SPINAME }} --vault-name ${{ parameters.KVNAME }} --value $spireset
                        echo "##################################################################"
                        echo "The Reset of Service Principal ${{ parameters.SPINAME }} secret was successful. The New Secret was then Stored inside Key Vault ${{ parameters.KVNAME }} in the Resource Group ${{ parameters.RGNAME }}!!!"
                        echo "##################################################################"
                        }               
                      else {
                      echo "####################################################################################################"
                      echo "Key Vault ${{ parameters.KVNAME }} DOES NOT EXISTS in Resource Group ${{ parameters.RGNAME }}!!!"
                      echo "####################################################################################################"
                      exit 1
                          }
                }
                else {
                echo "##################################################################"
                echo "Resource Group ${{ parameters.RGNAME }} DOES NOT EXISTS!!!"
                echo "##################################################################"
                exit 1
                    }
          }
          else {
          echo "####################################################################################################################"
          echo "Service Principal ${{ parameters.SPINAME }} DOES NOT EXISTS and hence Cannot Proceed with the Reset of Secret!!!"
          echo "####################################################################################################################"
          exit 1
              }

Enter fullscreen mode Exit fullscreen mode

NOW ITS TIME TO TEST !!!...

TEST CASES:-
TEST CASE #1: SERVICE PRINCIPAL NAME EXISTS, RESOURCE GROUP AND KEY VAULT EXISTS:-
DESIRED OUTPUT: PIPELINE EXECUTED SUCCESSFULLY. SERVICE PRINCIPAL SECRET GOT RESET AND STORED IN KEY VAULT.
SERVICE PRINCIPAL IN PLACE:-
Image description
PIPELINE RUNTIME VARIABLES VALUE:-
Image description
PIPELINE EXECUTED SUCCESSFULLY:-
Image description
Image description
SERVICE PRINCIPAL RESET SECRET STORED IN KEY VAULT:-
Image description
Image description
TEST CASE #2: SERVICE PRINCIPAL DOES NOT EXISTS, RESOURCE GROUP AND KEY VAULT EXISTS:-
DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE SERVICE PRINCIPAL DOES NOT EXISTS.
PIPELINE FAILED:-
Image description
Image description
TEST CASE #3: SERVICE PRINCIPAL AND KEYVAULT EXISTS BUT RESOURCE GROUP DOES NOT EXISTS:-
DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE RESOURCE GROUP DOES NOT EXISTS.
PIPELINE FAILED:-
Image description
Image description
TEST CASE #4: SERVICE PRINCIPAL AND RESOURCE GROUP EXISTS BUT KEY VAULT DOES NOT EXISTS:-
DESIRED OUTPUT: PIPELINE FAILS STATING THAT THE KEY VAULT DOES NOT EXISTS.
PIPELINE FAILED:-
Image description
Image description
IMPORTANT OBSERVATION:-
The Service Principal Reset Secret Entry Does Not appear in Azure Portal though available in Key Vault.
SECRET DETAILS IN KEY VAULT AFTER RESET:-
Image description
SECRET DETAILS IN AZURE PORTAL APP REGISTRATION GUI AFTER RESET:-
Image description

Hope You Enjoyed the Session!!!

Stay Safe | Keep Learning | Spread Knowledge

Top comments (0)