Thursday, February 22, 2018
Home » Automation » Integrate Jenkins, Hashicorp Vault, and PowerShell

Integrate Jenkins, Hashicorp Vault, and PowerShell

Passwords, Secrets, and Credentials, stored in a Hashicorp Vault server, can easily be leveraged by Jenkins Projects. This includes projects that leverage PowerShell for the automation – for pure Microsoft shops. There is a common tension between automation and security, but here’s how they can co-exist.

The following steps will enable this automation:

  • Save a Vault access token as a Jenkins Credential
  • Bind the Jenkins Credential to a Jenkins Project
  • Access the Jenkins Secret as an environment variable from PowerShell
  • Run a Jenkins Project (PowerShell) that loads all of the Vault Secrets for the project

When a credential is stored in Jenkins, it is encrypted and the credential secret value cannot be viewed after the fact, outside of a Jenkins project. When the credential is bound to a Jenkins project, it’s loaded as an Environment Variable when the project is executed and can be accessed by the automation (PowerShell). If the credential or secret is exposed in the StdOut of the automation, Jenkins will mask the credential value when it logs the output (see below).

Step 1: Add the Credential (Vault Secret)

From the Jenkins home, select Credentials, hover over the down arrow next to the domain “(global),” and select “Add credentials.”

Step 2: Add the Credential (Vault Secret)

Add the credential as a “Secret text” item.

Step 3: Bind the Credential to the Project

Bind the credential (Vault Secret) to the Jenkins Project.

Step 4: Reference the Credential in PowerShell

Reference the Jenkins Secret via an environmental variable within the PowerShell automation.

The following PowerShell script is an example which will download and list all Vault Secrets within a particular path. Of course, displaying secrets used during automation is not advisable, but they serve as an example and launching point for using them in code.

Pull-Vault.ps1 (example):

# Version:: 0.1.5 (3/16/2017)
# Script Description:: Pulls Vault secrets into environmental variables.
#
# Author(s):: Otto Helweg
#
param($token,$vaultSvr,$path)

# Display help
if ($Args -match "-\?|--\?|-help|--help|/\?|/help") {
Write-Host "Usage: Pull-Vault.ps1"
Write-Host " -path [path to credentials] Path the list of credentials."
Write-Host " -token [Vault auth token] Authentication token for accesing the Vault server."
Write-Host " -vaultSvr [Vault server name or IP] Vault server name or IP address."
Write-Host ""
Write-Host "Examples:"
Write-Host " Pull-Vault.ps1 -token '770da5b6-eff1-6fd6-f074-1e2604987340'"
Write-Host " Pull-Vault.ps1 -token '770da5b6-eff1-6fd6-f074-1e2604987340' -vaultSvr '10.102.76.4'"
Write-Host ""
exit
}

if (!($env:VAULT_TOKEN) -or !($env:VAULT_ADDR)) {
if (!($token)) {
$token = Read-Host -Prompt "Enter Token for Vault authentication" -AsSecureString
$token = (New-Object PSCredential "token",$token).GetNetworkCredential().Password
}

if (!($vaultSvr)) {
$vaultSvr = Read-Host -Prompt "Enter Vault Server"
}

$env:VAULT_ADDR = "http://$($vaultSvr):8200"
$env:VAULT_TOKEN = $token
}

if (!($path)) {
$path = Read-Host -Prompt "Enter Secrets Path"
}

$keys = vault list -format=json $path | ConvertFrom-Json

foreach ($key in $keys) {
$vaultKey = "TF_VAR_$key"
$value = vault read -format=json "$($path)/$($key)" | ConvertFrom-Json
if ($Args -contains "-debug") {
Write-Host " $($path)/$($key) : $($value.data.value)"
}
Write-Host "Loading env var: $vaultKey"
Set-Item -path "env:$vaultKey" -value "$($value.data.value)"
}

Note: The output from the Jenkins Project will mask out any output that matches the Jenkins Secret.

...
VAULT_ADDR http://10.10.10.10:8200
VAULT_ROOT_TOKEN ****
VAULT_TOKEN ****
windir C:\Windows
WINSW_EXECUTABLE C:\Program Files (x86)
...

Enjoy!

About Otto Helweg

Otto Helweg
As Datapipe’s Lead Automation Engineer, Otto has unique insight into DevOps consulting, development and system engineering using several tools, such as Terraform, Chef, Ansible, Vault, Jenkins, and Powershell DSC. Otto writes about a wide variety of topics including DevOps and system engineering.

Check Also

The Real Value of Machine Learning

We tend to be afraid of things we don’t understand. With the proliferation of AI, people commonly lament that “the robots are taking over!” Luckily for us, we aren’t looking at a Terminator or Wall-E situation, but somewhere in between.