Hello,
I’m relatively new to Jenkins, experimenting with operational CI/CD services for my company and have been happy with it thus far. I’d started with a single custom monolithic container that had jenkins and a bunch of other stuff installed for relative ease of use. Ran into some issues and I’ve recently shifted into a multi-container setup, using the Jenkins official container image from Docker hub with separate additional containers to act as dedicated agents for interactions with Ansible, AWS, etc.
I’m trying to make use of the SSH Pipeline Steps plugin to give myself some added granularity with my interactions between Jenkins and remote agents. I’ve got things working up to a point. When interacting with the Ansible agent container, I’m using the Jenkins Credentials vault to host both the ssh creds used by Jenkins to login to the Ansible remote agent container itself (username + ssh key) as well as the ssh service account creds (username and ssh key) used by Ansible (installed on the remote node) to login and interact with all of it’s assigned inventory.
I’m having a devil of a time getting the ansible service account user private key, stored in the Jenkins Credential vault, to be recognized and processed by the ansible-playbook binary on the remote Ansible agent container. Jenkins playbook code snippet as follows:
-----
ANSIBLE_INVENTORY = "ansible/inventory/non-prod/hosts"
echo "Running on non-production server. Using non-production inventory: ${ANSIBLE_INVENTORY}"
INVENTORY_FILE = ANSIBLE_INVENTORY.split('/')[-1]
echo "Inventory file: ${INVENTORY_FILE}"
PLAYBOOK_FILE = ANSIBLE_PLAYBOOK.split('/')[-1]
echo "Playbook file: ${PLAYBOOK_FILE}"
withCredentials([sshUserPrivateKey(credentialsId: 'secopsdev-ansible-agent', keyFileVariable: 'ANS_AGENT_KEY', usernameVariable: 'ANS_AGENT_USER'),
sshUserPrivateKey(credentialsId: 'secopsdev-ansible-svcaccount', keyFileVariable: 'ANS_SVC_KEY', usernameVariable: 'ANS_SVC_USER')]) {
def remote = [:]
remote.name = 'ansible'
remote.host = AGENT_HOST
remote.user = ANS_AGENT_USER
remote.identityFile = ANS_AGENT_KEY
remote.knownHosts = "${HOME}/.ssh/known_hosts"
// Define a work directory path using Jenkins environment variables
def workDir = "work/${JOB_NAME}/${BUILD_NUMBER}"
// Use sshCommand to create the work directory on the remote node
sshCommand remote: remote, command: "mkdir -p \"${workDir}\""
// copy the playbook and inventory file to the working directory
sshPut remote: remote, from: "${ANSIBLE_PLAYBOOK}", into: "${workDir}"
sshPut remote: remote, from: "${ANSIBLE_INVENTORY}", into: "${workDir}"
// show that the uploaded files are present in the workDir
sshCommand remote: remote, command: "ls -al '${workDir}'"
// Switch into the workDir and execute the playbook using the inventory file, playbook file and associated creds
sshCommand remote: remote, command: """
cd "${workDir}"
ansible-playbook -i ./${INVENTORY_FILE} ./${PLAYBOOK_FILE} -u ${ANS_SVC_USER} --private-key ${ANS_SVC_KEY}
"""
}
-----
From what I’ve been able to read up on thus far, the private key is supposed to be “auto-transferred” to the remote agent host automatically to a temp file and that the path to that temp file is then stored in the associated variable, in $(ANS_SVC_KEY) as referenced above. Try as I might though, I can’t seem to actually see/find that temporary key as having actually been transferred during the execution. I can see the tmp locale on the jenkins controller server and I can actually dive down into the workspace tmp path on the controller to actually see the private ssh key files in question.
Part of me is just thinking of bypassing this and just performing a fixed transfer of the private key separately and ahead of time into the service user’s ~/.ssh dir, but I’d like to see if I can get withCredentials working if possible to dynamically process the key at runtime and not leave it on the agent permanently.
From what I can tell, the transfer seems to attempt to use the pipeline job name as part of the tmp path to the creation of the temporary file. Not sure if this helps, but my pipeline jobs names tend to have spaces in them. Not sure if that’s relevant.
Any suggestions/recommendations on how I can get this working?