Recently while building a Pipeline as a Service implementation, I faced the challenge of adding credentials into Jenkins via a script.

Unfortunately there is no REST API for the Credentials Plugin, but the following snippet will do the trick with curl. Please note that this assumes Jenkins is running locally on its default port of 8080, and the username & password admin have permissions to create credentials.

JENKINS_CRUMB=$(curl -s 'http://admin:admin@127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')

curl -s -XPOST -H ${JENKINS_CRUMB} http://admin:admin@127.0.0.1:8080/credentials/store/system/domain/_/createCredentials \
--data-urlencode 'json={
  "": "0",
  "credentials": {
    "scope": "GLOBAL",
    "id": "credential_id_here",
    "username": "username_here",
    "password": "password_here",
    "description": "My new credentials",
    "$class": "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
  }
}'

And here are the tasks to accomplish the same with Ansible:

- uri:
    url: 'http://127.0.0.1:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
    user: admin
    password: admin
    force_basic_auth: yes
    return_content: yes
  register: crumb

- uri:
    method: POST
    url: 'http://127.0.0.1:8080/credentials/store/system/domain/_/createCredentials'
    user: admin
    password: admin
    force_basic_auth: yes
    headers:
      Jenkins-Crumb: "{{ crumb.content.split(':')[1] }}"
    body: |
      json={
        "": "0",
        "credentials": {
          "scope": "GLOBAL",
          "id": "credential_id_here",
          "username": "username_here",
          "password": "password_here",
          "description": "My new credentials",
          "$class": "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
        }
      }

For some of the common types of credentials, the corresponding $class values are as follows:

com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl: Username and password as in the above example. Required fields: id, scope, username, password

org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl: A secret text credential. Required fields: id, scope, secret

com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsImpl: AWS credentials as used by the EC2 plugin. Required fields: id, scope, accessKey, secretKey, iamRoleArn, iamMfaSerialNumber

Pro tip: The above way of adding credentials to Jenkins strips special characters off the values. This is problematic with credentials that contain special characters like the plus sign (+), such as SSH private keys or AWS access keys. To get around this, you can urlencode the value.

To do this with Ansible, you can use the jinja filter urlencode as follows:

"password": "{{ aws_secret_key|urlencode }}"

Releaseworks Academy has a free online training course on Docker & Jenkins best practices: https://www.releaseworksacademy.com/courses/best-practices-docker-jenkins