Issue
I have Terraform+Ansible script that automates the deployment of a Jenkins server. However, I'd also like to pre-load that server with "Global" environment variables (Found in "Manage Jenkins" > "Configure System" > "Global Properties" > "Environment Variables"). I'm also looking to automatically set a few Jenkins credentials (found in "Manage Jenkins" > "Manage Credentials").
From what I understand, the credentials are stored encrypted in a file called /var/lib/jenkins/credentials.xml
. And the global properties might be stored in config.xml
in the same Jenkins directory, though the variables don't look very structured. I might be able to parse out the config.xml
and add some values. But I'm wondering how I can create an encrypted secret that can be added to the credentials.xml
.
Are there any tools or strategies for automating the creation of secrets and environment variables in Jenkins? I'm hoping that there's a better way to automate this other than parsing the xml documents. Any advice is much appreciated.
Solution
You shouldn't be manually altering these files. You can use one of the following options to automate Credential and Global variable creation.
- Jenkins API.
- Jenkins CLI.
- Python-jenkinsapi. (Python wrapper for Jenkins API)
How to use Jenkins API to create credentials
Following commands need curl and jq. Execute in the same session.
# Change the following appropriately
JENKINS_URL="http://localhost:8080"
JENKINS_USER=admin
JENKINS_USER_PASS=admin
Get the Crumb
JENKINS_CRUMB=$(curl -u "$JENKINS_USER:$JENKINS_USER_PASS" -s --cookie-jar /tmp/cookies $JENKINS_URL'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
Get the Access token
ACCESS_TOKEN=$(curl -u "$JENKINS_USER:$JENKINS_USER_PASS" -H $JENKINS_CRUMB -s \
--cookie /tmp/cookies $JENKINS_URL'/me/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken' \
--data 'newTokenName=GlobalToken' | jq -r '.data.tokenValue')
Create Credentials
curl -u $JENKINS_USER:$ACCESS_TOKEN \
-H $JENKINS_CRUMB \
-H 'content-type:application/xml' \
"$JENKINS_URL/credentials/store/system/domain/_/createCredentials" \
-d '<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<id>TestCredentials</id>
<description>This is sample</description>
<username>admin2</username>
<password>admin2</password>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>'
Note: The credential create URL format is /credentials/store/CREDENTIALS_STORE_NAME/domain/DOMAIN_NAME/
Change this appropriately if you want to create the Credential in a custom location. The easiest way to get this URL is by navigating to a existing credential from the UI and copying the URL.
How to create Credentials from Jenkins CLI
# Change the following appropriately
JENKINS_URL="http://localhost:8080"
JENKINS_USER=admin
JENKINS_USER_PASS=admin
Download the Jenkins CLI Jar
wget $JENKINS_URL/jnlpJars/jenkins-cli.jar
Create a file named cred.xml
with the following content.
<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<scope>GLOBAL</scope>
<id>PassID</id>
<username>Username</username>
<password>password</password>
<description>Description</description>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
Create credentials
java -jar jenkins-cli.jar -s $JENKINS_URL -auth $JENKINS_USER:$JENKINS_USER_PASS create-credentials-by-xml system::system::jenkins _ < cred.xml
How to create credentials with Jenkins Python API
Following is a simple sample to create Global credentials using Jenkins Python API.
from api4jenkins import Jenkins
j = Jenkins('http://localhost:8080', auth=('admin', 'admin'))
xmlPayload = '''<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
<id>user-id</id>
<username>user</username>
<password>upassword</password>
<description>user id for testing</description>
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>'''
j.credentials.create(xmlPayload)
Answered By - ycr
Answer Checked By - Marilyn (JavaFixing Volunteer)