Installing HashiCorp Vault on Ubuntu and Integrating with Jenkins

    This consolidated guide covers installing HashiCorp Vault from scratch on an Ubuntu server, configuring it for a local network, and securely integrating it with a Jenkins CI/CD pipeline using the AppRole authentication method. (NOTE: use secure tls way for production)


    Part 1: Install and Configure Vault on Ubuntu

    1. Install HashiCorp Vault

    Add the official HashiCorp package repository and install Vault:

    https://developer.hashicorp.com/vault/install

    # Install prerequisites
    sudo apt update && sudo apt install -y curl gnupg software-properties-common lsb-release
    
    # Add HashiCorp GPG key
    wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    
    # Add official repository
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    
    # Install Vault
    sudo apt update && sudo apt install vault
    Bash

    2. Configure the Vault Server (HTTP Mode)

    Edit the configuration file to allow network connections via HTTP.

    sudo vim /etc/vault.d/vault.hcl
    Bash

    Update the configuration to match this block (replace 192.168.195.175 with your actual Ubuntu server IP):

    storage "file" {
      path = "/opt/vault/data"
    }
    
    # Bind to all interfaces and explicitly disable TLS for local environments
    listener "tcp" {
      address     = "0.0.0.0:8200"
      tls_disable = "true"
    }
    
    # Use HTTP protocol to match the listener configuration
    api_addr     = "http://192.168.195.175:8200"
    cluster_addr = "https://127.0.0.1:8201"
    ui           = true
    HCL

    Set up directory permissions and start the service:

    # Create storage directory and set permissions
    sudo mkdir -p /opt/vault/data
    sudo chown -R vault:vault /opt/vault
    
    # Restart and enable Vault service
    sudo systemctl daemon-reload
    sudo systemctl enable vault --now
    Bash

    3. Initialize and Unseal Vault

    Set your environment variables to ensure the CLI matches the server configuration.

    # Configure environment variables for the current session and persistence
    export VAULT_ADDR="http://192.168.195.175:8200"
    echo 'export VAULT_ADDR="http://192.168.195.175:8200"' >> ~/.bashrc
    
    # Initialize Vault (Saves unseal keys and root token)
    vault operator init
    Bash

    ⚠️ CRITICAL SECURITY NOTE: Save the generated Unseal Keys and Initial Root Token in a secure location.

    Unseal the Vault by running the following command 3 separate times, providing a unique unseal key each time:

    vault operator unseal
    Bash

    Verify the status:

    vault status
    Bash

    Part 2: Provision Access for Jenkins (AppRole Setup)

    Log in to Vault using your root token to create a policy and an AppRole identity for Jenkins.

    # Log in to Vault CLI
    vault login <YOUR_ROOT_TOKEN>
    
    # 1. Enable Key-Value (KV version 2) Secrets Engine
    vault secrets enable -path=secret kv-v2
    
    # 2. Enable AppRole Authentication Method
    vault auth enable approle
    
    # 3. Create a restrictive read-only policy for Jenkins secrets
    vault policy write jenkins-policy - <<EOF
    path "secret/data/myapp/*" {
      capabilities = ["read"]
    }
    EOF
    
    # 4. Create the AppRole for Jenkins linked to the policy
    vault write auth/approle/role/jenkins-role \
        secret_id_ttl=0 \
        token_num_uses=0 \
        token_ttl=1h \
        token_max_ttl=2h \
        token_policies="jenkins-policy"
    
    # 5. Retrieve credentials for Jenkins (Save these for the next part)
    vault read auth/approle/role/jenkins-role/role-id
    vault write -f auth/approle/role/jenkins-role/secret-id
    Bash

    Part 3: Configure Jenkins

    1. Install the Plugin

    1. Open the Jenkins dashboard.
    2. Navigate to Manage Jenkins > Plugins > Available Plugins.
    3. Search for HashiCorp Vault.
    4. Select it and click Install. Restart Jenkins if prompted.

    2. Save Vault AppRole Credentials in Jenkins

    1. Go to Manage Jenkins > Credentials > System > Global credentials (unrestricted).
    2. Click Add Credentials.
    3. Configure the following fields:
      • Kind: Vault AppRole Credential
      • Path: approle
      • Role ID: (Paste the Role ID from Part 2)
      • Secret ID: (Paste the Secret ID from Part 2)
    1. ID: jenkins-vault-approle
    2. Click Create.

    3. Configure Global Vault Integration

    1. Go to Manage Jenkins > System.
    2. Scroll down to the Vault Plugin section.
    3. Configure the engine parameters:
      • Vault URL: http://192.168.195.175:8200
      • Vault Credential: Select jenkins-vault-approle from the dropdown list.
    4. Click Save.

    Part 4: Add Secrets and Test the Pipeline

    1. Inject a Test Secret into Vault

    Run this command from your Vault server to populate a credential path:

    vault kv put secret/myapp/db password="my-super-secure-db-password"
    Bash

    2. Create the Jenkins Pipeline

    Use the withVault block inside your Jenkinsfile to retrieve and mask the secret programmatically:

    pipeline {
        agent any
    
        stages {
            stage('Fetch Credentials from Vault') {
                steps {
                    withVault(vaultSecrets: [[
                        path: 'secret/myapp/db', 
                        secretValues: [
                            [envVar: 'DB_PASSWORD', vaultKey: 'password']
                        ]
                    ]]) {
                        // Jenkins automatically replaces secret variables with **** in console logs
                        sh 'echo "The retrieved database password is: $DB_PASSWORD"'
                    }
                }
            }
        }
    }
    Groovy

    When using Key-Value (KV) Version 2 in Vault:

    1. Vault Engine Policy Path: Vault forces the /data/ prefix inside the policy rules (secret/data/myapp/*).
    2. The Jenkins Plugin Behavior: The HashiCorp Vault Plugin for Jenkins is built to know this rule. When it talks to Vault, it automatically inserts the /data/ string into the API request path on its own.

    If you want to customize this tech blog further, let me know:

    • Do you want to add a section for automatic Vault unsealing using a script or transit auto-unseal?
    • Should we expand the pipeline code to include multi-secret injection examples?

    Discover more from Altgr Blog

    Subscribe to get the latest posts sent to your email.

    Leave a Reply

    Your email address will not be published. Required fields are marked *