Wednesday, April 1, 2020

Integrate Jenkins with Azure Key Vault


Jenkins has been one of the most used CI/CD tools. For every tool which we are using in our daily life, it becomes really challenges when it comes to handling secret information. I know there are lots of tools available provided with PAAS or in house hosting solution. But we need those tools to support integration with different toolsets without many efforts. 

In this particular blog, we will be discussing the integration of Jenkins with the Azure Key Vault. Thanks to all the guys who are continuously working for different communities and spending time to make product more flexible and enhancing the product capabilities.


We are going to use Azure Key Vault plugin for this. There are multiple ways to use this. But in this post, we'll go through the integration and then testing using declarative pipelines.

Pre-Requisites-

  • Make sure you have running Jenkins setup
  • You have valid Azure subscription
Implementation Steps-

     1. Create an Azure Key Vault using the below steps:


kulsharm2@WKMIN5257929:~$ ⚙️  $az login
You have logged in. Now let us find all the subscriptions to which you have access...
[
  {
    "cloudName": "AzureCloud",
    "id": "dd019fb5-db8a-4e4f-96ec-fc8decd2db8b",
    "isDefault": true,
    "name": "<>",
    "state": "Enabled",
    "tenantId": "d52c9ea1-7c21-47b1-82a3-33a74b1f74b8",
    "user": {
      "name": "<>",
      "type": "user"
    }
  }
]



kulsharm2@WKMIN5257929:~$ ⚙️  $az ad sp create-for-rbac --name http://local-jenkins
Found an existing application instance of "7e575c9b-b902-4510-8a06-8cbe1639aba3". We will patch it
Creating a role assignment under the scope of "/subscriptions/dd019fb5-db8a-4e4f-96ec-fc8decd2db8b"
  Role assignment already exits.

{
  "appId": "7e575c9b-b902-4510-8a06-8cbe1639aba3",
  "displayName": "local-jenkins",
  "name": "http://local-jenkins",
  "password": "e7157115-6e35-46f9-a811-c856ba9bb5c0",
  "tenant": "d52c9ea1-7c21-47b1-82a3-33a74b1f74b8"
}
kulsharm2@WKMIN5257929:~$ ⚙️  $RESOURCE_GROUP_NAME=my-resource-group
kulsharm2@WKMIN5257929:~$ ⚙️  $az group create  --name $RESOURCE_GROUP_NAME -l "East US"
{
  "id": "/subscriptions/dd019fb5-db8a-4e4f-96ec-fc8decd2db8b/resourceGroups/my-resource-group",
  "location": "eastus",
  "managedBy": null,
  "name": "my-resource-group",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}
kulsharm2@WKMIN5257929:~$ ⚙️  $az group show --name $RESOURCE_GROUP_NAME -o table
Location    Name
----------  -----------------
eastus      my-resource-group

kulsharm2@WKMIN5257929:~$ ⚙️  $VAULT=jenkins-local
kulsharm2@WKMIN5257929:~$ ⚙️  $az keyvault create --resource-group $RESOURCE_GROUP_NAME --name $VAULT
{
  "id": "/subscriptions/dd019fb5-db8a-4e4f-96ec-fc8decd2db8b/resourceGroups/my-resource-group/providers/Microsoft.KeyVault/vaults/jenkins-local",
  "location": "eastus",
  "name": "jenkins-local",
  "properties": {
    "accessPolicies": [
      {
        "applicationId": null,
        "objectId": "fd5bcd48-13d1-40c5-98a3-d46442c5194e",
        "permissions": {
          "certificates": [
  .          
  .       
  <>

kulsharm2@WKMIN5257929:~$ ⚙️  $az keyvault list -o table
Location    Name           ResourceGroup
----------  -------------  -----------------
eastus      jenkins-local  my-resource-group
kulsharm2@WKMIN5257929:~$ ⚙️  $az keyvault set-policy --resource-group $RESOURCE_GROUP_NAME --name $VAULT    --secret-permissions get list --spn http://local-jenkins
{
  "id": "/subscriptions/dd019fb5-db8a-4e4f-96ec-fc8decd2db8b/resourceGroups/my-resource-group/providers/Microsoft.KeyVault/vaults/jenkins-local",
  "location": "eastus",
  "name": "jenkins-local",
  "properties": {
    "accessPolicies": [
      {
        "applicationId": null,
        "objectId": "fd5bcd48-13d1-40c5-98a3-d46442c5194e",
        "permissions": {
          "certificates": [
            "get",
            "list",
            "delete",
            "create",
            "import",
            "update",
            "managecontacts",
            "getissuers",
            "listissuers",
            "setissuers",
            "deleteissuers",
            "manageissuers",
 <>
      2. Create one secret in the Azure Key Vault :

kulsharm2@WKMIN5257929:~$ ⚙️  $az keyvault secret set --vault-name $VAULT --name secret-key --value my-super-secret
{
  "attributes": {
    "created": "2020-04-01T05:18:37+00:00",
    "enabled": true,
    "expires": null,
    "notBefore": null,
    "recoveryLevel": "Purgeable",
    "updated": "2020-04-01T05:18:37+00:00"
  },
  "contentType": null,
  "id": "https://jenkins-local.vault.azure.net/secrets/secret-key/85a36fe61ba34f53b60217c5e08f1774",
  "kid": null,
  "managed": null,
  "tags": {
    "file-encoding": "utf-8"
  },
  "value": "my-super-secret"
}

      3. Let's make changes on Jenkins side to complete the integration:
          1. Install the plugin as below:



        2. Add the Azure Key Vault URL to Jenkins Configuration following "Manage Jenkins --> Configure System" as below :


       
       4. Add credentials by going through "Credentials --> System --> Global Credentials(unrestricted)" as below:

       
       5. Create new credential as below-
 

    6. Now, let's create a pipeline and try to fetch the secret we stored in AKV:


*** Pipeline Code ***
pipeline {
  agent any
  environment {
    SECRET_KEY = credentials('secret-key')
  }
  stages {
    stage('Foo') {
      steps {
        echo SECRET_KEY
        echo SECRET_KEY.substring(0, SECRET_KEY.size() -1) // shows the right secret was loaded, don't do this for real secrets unless you're debugging 
      }
    }
  }
}






Happy Learning!!

Integrate Jenkins with Azure Key Vault

Jenkins has been one of the most used CI/CD tools. For every tool which we are using in our daily life, it becomes really challenges when ...