Using vRA ABX actions to execute and monitor Jenkins jobs

I hit the requirement recently to execute a Jenkins job as part of a VM build within vRA. I wanted to execute the job and monitor it for completion. Once the Jenkins job was complete, I knew the VM was ready for usage so needed the action to wait for success.

To do this I used an ABX action within vRA Cloud, using an extensibility proxy to provide connectivity to a local Jenkins instance.

Step 1 – Configure a Jenkins job with parameter input

Create a Jenkins job which includes parameters. For me, this allowed each Jenkins run to be tailored to a particular VM that vRA was provisioning by allowing inputs such as the VM name, IP, OStype, Disk data etc.

Example parameter configuration in Jenkins

Step 2 – Create an ABX Action in Cloud Assembly

Few Notes:

  • jenkins_user is a base 64 string of jenkinsusername:apikey
  • All input variables are coming from the event broker [inputs] pipeline, which also include any custom properties inherrited from projects and/or blueprints.
  • I am utilising some additional modules in this code as can be seen from the ‘import xxx’. In terms of dependancies on the ABX action, only requests needs to be listed
  • If the Jenkins job completes successfully, I return an outputs array back to the VM with the URL of the completed Jenkins job, so if there is ever a problem with the build it can be traced.
  • *Disclaimer* – I’m pretty naff at coding so it probably could be written in a much neater way than this!!
import base64
import requests
import time
import json
def handler(context, inputs):
#Variable definition
for i in inputs['addresses']:
vmIp = i[0]
print(vmIp)
vmName = inputs['resourceNames'][0]
print(vmName)
#env = inputs['customProperties']['sdlc']
env = 'prod'
print(env)
osType = inputs['customProperties']['osType'][0:1].upper() + 
inputs['customProperties']['osType'][1:].lower()
print(osType)
disks = inputs['customProperties']['diskgrid']
print(disks)
print(customer)
version = 'v1'
role = 'Admin'
ANSIBLE_ssm_auto_patch = inputs['customProperties']['ssm_auto_patch'].lower()
print(ANSIBLE_ssm_auto_patch)
jenkins_url = "https://jenkins.local"
jenkins_crumb_url = 'https://jenkins.local/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)'
jenkins_job_path = "/job/jenkins_job_name"
jenkins_user = "base64placeholder"
jenkins_build_params = "/buildWithParameters?VMNAME=" + vmName + "&IPADDR=" + vmIp + "&ENVIRONMENT=" + env + "&VERSION=" + version + "&role=" + role + "&OSTYPE=" + osType 
jenkins_last_build = "/lastBuild/api/json"
jenkins_build_path = jenkins_url + jenkins_job_path + jenkins_build_params
jenkins_lastbuild_uri = jenkins_url + jenkins_job_path + jenkins_last_build
#Create requests header
session = requests.Session()
session.trust_env = False
session.headers.update({"Authorization" : "Basic " + jenkins_user})
session.headers.update({"Content-Type" : "application/json"})
#Get Crumb
response = session.post(jenkins_crumb_url, verify = False, proxies = None)
print('Request response code is: ' + str(response.status_code))
crumb = response.text.split(":")[1]
print('Crumb: ' + crumb)
#Update header with crumb
session.headers.update({"Jenkins-Crumb" : crumb})
#Execute POST request using variables
response = session.post(jenkins_build_path, verify = False, proxies = None)
print('Request response code is: ' + str(response.status_code))
if response.status_code == 201:
location = str(response.headers['location'])
print('Job Queue Found: ' + location)
jenkins_start_path = location + '/api/json'
response = session.post(jenkins_start_path, verify = False, proxies = None)
i = 0
while i < 20:
response = session.post(jenkins_start_path, verify = False, proxies = None)
if response.status_code == 200:
print(response.text)
if b"executable" in response.content:
json_content = json.loads(response.content)
job_url = json_content['executable']['url']
print("Job Identified: " + job_url)
break
else:
time.sleep(3)
i = i + 1
print("Loop ID: ")
print(i)
#Check job is successful
current_build_path = job_url + '/api/json'
i = 0
while i < 60:
response = session.post(current_build_path, verify = False, proxies = None)
json_response = json.loads(response.content)
print(json_response['result'])
if response.status_code == 200:
if json_response['result'] == "SUCCESS":
print("JOB COMPLETED " + job_url)
break
elif json_response['result'] == "FAILURE":
raise NameError("JOB FAILED " + job_url)
break
elif json_response['result'] == "ABORTED":
raise NameError("JOB ABORTED " + job_url)
break
else:
i = i+1
time.sleep(10)
outputs = {}
outputs['customProperties'] = inputs['customProperties']
outputs['customProperties']['jenkins_build'] = job_url
return outputs

The code loops every 10 seconds waiting for Jenkins to return ‘JOB COMPLETED’, before closing down.

If you make sure your vRA subscription is set to ‘Blocking’, then the VM will not show as available until the action completes.

Custom jenkins_build property against the VM

This job works incredibly well and could also be written in vRO, which would probably be preferable as you could hold all your credentials in a constants file as secure strings…this is functionality still missing for ABX within vRA Cloud.

References:

https://blogs.vmware.com/management/2020/03/vra-abx-powershell.html

https://docs.vmware.com/en/vRealize-Automation/8.1/Using-and-Managing-Cloud-Assembly/GUID-AB39FD64-7545-474E-9064-8553FADD0ECF.html

Synchronising VMware SDDC Manager Credentials to Hashicorp Vault with Python
Hashicorp Vault Python VCF

Synchronising VMware SDDC Manager Credentials to Hashicorp Vault with Python

VMware's SDDC has a great feature whereby it can manage credentials for all the applications and appliances within its scope,...
Read More
Configuring iDRAC using RedFish API via Ansible.
Ansible Hardware IDRAC

Configuring iDRAC using RedFish API via Ansible.

Having a large number of iDRAC out of band (OOB) interfaces to configure on Dell hardware can seem like a...
Read More
VMware VCF on Dell VxRail 4.2 to 4.3 – Tips & Tricks
VCF

VMware VCF on Dell VxRail 4.2 to 4.3 – Tips & Tricks

VMware VCF 4.3 is GA and not a moment too soon! The release of 4.3 brings the vRealize product set...
Read More
Using the vRA Plugin for vRO – Enabling Actions in custom forms which call the vRA API
Javascript vRealize Automation vRealize Orchestrator

Using the vRA Plugin for vRO – Enabling Actions in custom forms which call the vRA API

I haven't done a blog for a while due to an overload of work, but I'm getting back on the...
Read More
SDDC Manager – ‘SSO Ring Topology’ Error when rebuilding additional VCF 4.x Workload Domains
PSC / SSO VCF

SDDC Manager – ‘SSO Ring Topology’ Error when rebuilding additional VCF 4.x Workload Domains

I've recently been working on a large VCF rollout with Dell which comprised of a management cluster and multiple workload...
Read More
vRA 8.3 – Saltstack Config – Getting started. Part 1
DevOps Salt vRealize Automation

vRA 8.3 – Saltstack Config – Getting started. Part 1

Like many others, Ansible is my tool of choice for configuring endpoints once the VM is provisioned. With the introduction...
Read More
Using vRA 8.2 Terraform cloud templates to deploy AWS resources
AWS DevOps Terraform vRealize Automation

Using vRA 8.2 Terraform cloud templates to deploy AWS resources

VMware have jumped on the Terraform bandwagon and it is now fully integrated into vRA 8.2 onwards. In this blog...
Read More
vRA Cloud ABX – Manage Action Secrets
ABX Python vRealize Automation

vRA Cloud ABX – Manage Action Secrets

Not a moment too soon into 2021 and vRA Cloud has been updated with some essential functionality, the ability to...
Read More
Manual Sync of VMware Identity Manager (vIDM) via API
Identity Manager Python vRealize Automation

Manual Sync of VMware Identity Manager (vIDM) via API

VMware's Identity Manager. 🙁 A product which causes me more hassle than it's worth (in my opinion!). I get why...
Read More
Managing AWS S3 objects via Python & boto3
AWS DevOps Python S3

Managing AWS S3 objects via Python & boto3

I recently had a task which required updating a large number of JSON manifest files housed within S3 folders, so...
Read More
vRA 8.x Orchestrator validation in custom forms
DevOps Javascript vRealize Automation vRealize Orchestrator

vRA 8.x Orchestrator validation in custom forms

When configuring vRA service broker custom forms, it is often useful to validate user values prior to the data being...
Read More
Creating Hashicorp Vault Records with Ansible
Ansible DevOps Hashicorp Vault

Creating Hashicorp Vault Records with Ansible

Hasicorp Vault is a more and more popular choice for securing credentials / keys / certificates. The API is clear...
Read More
Using ldap3 python module to manage Active Directory
Active Directory DevOps Python

Using ldap3 python module to manage Active Directory

I have found myself in situations where I have needed to manage Active Directory objects programatically, but have not been...
Read More
Obtaining a VMware Cloud Services API token via vRO & ABX
ABX VMware VMware Cloud Services vRealize Automation vRealize Orchestrator

Obtaining a VMware Cloud Services API token via vRO & ABX

If you are working with VMware cloud services such as VMware on AWS (VMC) or vRA Cloud, you will likely...
Read More
Using vRA ABX actions to execute and monitor Jenkins jobs
ABX vRealize Automation

Using vRA ABX actions to execute and monitor Jenkins jobs

I hit the requirement recently to execute a Jenkins job as part of a VM build within vRA. I wanted...
Read More

Leave a Reply