Search code examples
jenkinsautomationconfigurationdevopsjenkins-cli

Automate Setting Jenkins Credentials and Global Variables


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.

    1. Jenkins API.
    2. Jenkins CLI.
    3. 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. enter image description here

    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)