Create Blueprints in vRA 7 via REST and via vRO
A significant pain point on a recent project of mine was automating the creation of blueprints in vRA 6.2 with vRO. There was very little information around on how this could be achieved and even with the method that we eventually came up with still required some manual effort and was not always the most reliable.
Enter vRA 7 and some hope that things may have gotten better.
First of all I looked through the vRA 7 Programming Guide and found some examples on exporting content from vRA 7. I’d heard in some of the conversations around the release of version 7 that blueprints would be able to be manipulated in YAML files, so the first thing to do was to create a blueprint through the new Design interface and then get it exported out into a YAML file.
Create a Blueprint through the Design Interface
Here’s my Centos-Small blueprint created through the Blueprint Designer. A simple vCenter template clone connected to a single network and basic resource values (make sure to publish the blueprint):
Get an Authentication Token for vRA REST Queries
Using the Postman REST client, I first of all need to get an authentication token. I have previously detailed how to do this from vRO, however from Postman I need to set the following:
URL: https://vraapliance.fqdn/identity/api/tokens
Type: POST
Headers: Accept: application/json and Content-Type: application/json
Body:
[code language=“javascript”]
{ “username”:“[email protected]”, “password”:“P@ssw0rd1”, “tenant”:“Tenant01” }
[/code]
Sending that request should give me a response with a token to use which is valid for up to 8 hours; it will look something like this:
[code language=“javascript”]
{ “expires”: “2016-01-19T18:37:42.000Z”, “id”: “MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=”, “tenant”: “Tenant01” }
[/code]
Get a List of Blueprints
Now we can use that token to get a list of available blueprints that token has permission to view:
URL: https://vraapliance.fqdn/content-management-service/api/contents
Type: GET
Headers: Accept: application/json and Authorization: Bearer MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=
This will give us a JSON response, including some details of our Centos-Small Blueprint:
[code language=“javascript”]
{ “links”: [], “content”: [ { “@type”: “Content”, “id”: “78f27bc8-dd51-4c10-97cf-fb5770f0836b”, “contentId”: “cfa3b28a-6a59-4a85-8355-ff70c6fd3332”, “name”: “IaaS VC VirtualMachine”, “description”: null, “contentTypeId”: “xaas-resource-mapping”, “mimeType”: null, “tenantId”: “_internal”, “subtenantId”: null, “dependencies”: [], “createdDate”: “2016-01-05T11:05:21.673Z”, “lastUpdated”: “2016-01-05T11:05:21.673Z”, “version”: 0 }, { “@type”: “Content”, “id”: “3ac8d4ed-1bc0-45d7-a54a-edb44a2fdeae”, “contentId”: “9fd01109-c9ab-4ce7-9b9d-4d1c06bccdb9”, “name”: “IaaS vCD VM”, “description”: null, “contentTypeId”: “xaas-resource-mapping”, “mimeType”: null, “tenantId”: “_internal”, “subtenantId”: null, “dependencies”: [], “createdDate”: “2016-01-05T11:05:21.868Z”, “lastUpdated”: “2016-01-05T11:05:21.868Z”, “version”: 0 }, { “@type”: “Content”, “id”: “2359c8c9-1ec1-4162-a9e0-aa2c5121815d”, “contentId”: “CentosSmall-12345”, “name”: “Centos - Small”, “description”: “Centos - Small”, “contentTypeId”: “composite-blueprint”, “mimeType”: null, “tenantId”: “Tenant01”, “subtenantId”: null, “dependencies”: [], “createdDate”: “2016-01-19T10:56:14.398Z”, “lastUpdated”: “2016-01-19T10:56:14.398Z”, “version”: 0 } ], “metadata”: { “size”: 20, “totalElements”: 3, “totalPages”: 1, “number”: 1, “offset”: 0 } }
[/code]
Create a Content Package Containing our Blueprint
Now we need to create a Content Package containing our Blueprint, so that it can be exported. We will only add a single item, but multiple items can be added to the Package. The id of the Blueprint retrieved above needs to be used in the JSON body as ‘contents’ .
URL: https://vraapliance.fqdn/content-management-service/api/packages
Type: POST
Headers: Accept: application/json, Content-Type: application/json and Authorization: Bearer MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=
Body:
[code language=“javascript”]
{ “name”:“Test package”, “description”:“Test package for export”, “contents”:[ “2359c8c9-1ec1-4162-a9e0-aa2c5121815d” ] }
[/code]
All being well, we should receive a 201 Created response:
Listing Existing Content Packages
We can see what Content Packages are available with:
URL: https://vraapliance.fqdn/content-management-service/api/packages
Type: GET
Headers: Accept: application/json and Authorization: Bearer MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=
which should give us a response like the following, including our newly created ‘Test package’:
[code language=“javascript”]
{ “links”: [], “content”: [ { “@type”: “Package”, “id”: “736562b2-c991-449a-999d-6d25f2ff05c5”, “name”: “demo package”, “description”: “this is the description”, “tenantId”: “Tenant01”, “subtenantId”: null, “contents”: [ “7e9bf69c-a4ec-44dd-98f5-6408f074a1db” ], “createdDate”: “2016-01-14T15:28:26.323Z”, “lastUpdated”: “2016-01-14T15:28:26.323Z”, “version”: 0 }, { “@type”: “Package”, “id”: “339aeb0d-a15a-4ee1-84b7-87389d05c428”, “name”: “demo package 2”, “description”: “demo package 2”, “tenantId”: “Tenant01”, “subtenantId”: null, “contents”: [ “241fe601-5f15-4749-a6cb-f0bfdb9c97b9”, “7e9bf69c-a4ec-44dd-98f5-6408f074a1db” ], “createdDate”: “2016-01-14T17:05:47.458Z”, “lastUpdated”: “2016-01-14T17:05:47.458Z”, “version”: 0 }, { “@type”: “Package”, “id”: “04fb81ce-9da1-46f6-b98f-fd48e8ce0e2c”, “name”: “Test package”, “description”: “Test package for export”, “tenantId”: “Tenant01”, “subtenantId”: null, “contents”: [ “2359c8c9-1ec1-4162-a9e0-aa2c5121815d” ], “createdDate”: “2016-01-19T11:28:30.507Z”, “lastUpdated”: “2016-01-19T11:28:30.507Z”, “version”: 0 } ], “metadata”: { “size”: 20, “totalElements”: 3, “totalPages”: 1, “number”: 1, “offset”: 0 } }
[/code]
Export the Content Package to a Zip File
Now we want to export the Content Package to a zip file so that we can have a look at the YAML file that details the blueprint:
URL: https://vraapliance.fqdn/content-management-service/api/packages/packageid
Type: GET
Headers: Accept: application/zip and Authorization: Bearer MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=
This time in Postman click on Send and download
This will prompt us where to save the package and what to call it; make sure you create a zip file…
Have a look inside the zip file and you will see the following structure; a metadata.yaml file and a composite-blueprint folder containing individual yaml files for each blueprint that was part of the package:
The contents of each YAML file are listed here for reference:
metadata.yaml
[javascript]
name: “Test package” productVersion: “7.0.0-SNAPSHOT” data: - locator: “composite-blueprint/CentosSmall-12345.yaml” name: “Centos - Small” description: “Centos - Small” exportTime: “2016-01-19T11:46:13.614Z”
[/javascript]
CentosSmall-12345.yaml
[xml]
id: CentosSmall-12345 name: Centos - Small description: Centos Small - 1 vCPU - 1GB RAM status: PUBLISHED components: Tenant01: type: Infrastructure.Network.Network.Existing data: name: fixed: Tenant01 network_profile: fixed: Tenant01 vSphere_Machine_1: type: Infrastructure.CatalogItem.Machine.Virtual.vSphere data: _cluster: fixed: 1 min: 1 action: fixed: FullClone allow_storage_policies: fixed: false blueprint_type: fixed: ‘1’ cpu: fixed: 1 min: 1 disks: - capacity: 16 id: 1452533069864 initial_location: ’’ is_clone: true label: Hard disk 1 storage_reservation_policy: ’’ userdate: false volumeId: 0 display_location: fixed: false machine_prefix: fixed: id: Tenant01 max_network_adapters: {} max_volumes: {} memory: default: 1024 max: 1024 min: 1024 nics: - address: ’’ assignment_type: Static id: 0 load_balancing: ’’ network: ${_resource~Tenant01} network_profile: Tenant01 provisioning_workflow: fixed: id: CloneWorkflow label: CloneWorkflow security_groups: [] security_tags: [] source_machine: fixed: id: 51784cf9-fc3a-4939-abf7-2e2965523036 label: template-centos06b source_machine_name: fixed: template-centos06b storage: default: 16 max: 40 min: 16 layout: Tenant01: 0,0 vSphere_Machine_1: 1,0
[/xml]
Create Blueprints from Postman
We can now manipulate the YAML files to create Blueprints back in vRA. Say for instance we want to add Centos-Medium and Centos-Large Blueprints. All we need to do is create additional YAML files for those two templates, update the metadata.yaml file and send back to vRA.
So the composite-blueprint folder now looks like this:
And the metadata.yaml file has been updated to contain the new files:
[javascript]
name: “Test package” productVersion: “7.0.0-SNAPSHOT” data: - locator: “composite-blueprint/CentosSmall-12345.yaml” name: “Centos - Small” description: “Centos - Small” - locator: “composite-blueprint/CentosMedium-12345.yaml” name: “Centos - Medium” description: “Centos - Medium” - locator: “composite-blueprint/CentosLarge-12345.yaml” name: “Centos -Large” description: “Centos - Large” exportTime: “2016-01-19T11:46:13.614Z”
[/javascript]
We then create a new zip file with the updated content:
To create the Blueprints in vRA we send the following REST request via Postman:
URL: https://vraapliance.fqdn/content-management-service/api/packages
Type: POST
Headers: Accept: application/zip, and Authorization: Bearer MTQ1MzE5OTg2MjYzMTo3MThjNGFiNDVmMjE4MjZiMzgxNjp0ZW5hbnQ6VGVuYW50MDF1c2VybmFtZTp0ZW5hbnRhZG1pbjAxQHZyYWRlbW8ubG9jYWxleHBpcmF0aW9uOjE0NTMyMjg2NjIwMDA6ZmJmZjU2ZmNjOTFkMDE3ODhkNjJmMzM3ZGMwMzM3NjRhMjQxNjJlMjhjMGU3YjU0YzNlZjUwYTlkYWFjNDAxYTBkODVlYzVkYWQ1YzY4ZDc0MTQ3NjBlM2Q3MDk1OGU5OTg1NjNiMTI4OWQwMGMzMzExMDAxNmEyOGY0M2MxYTk=
Body: set to form data and select the TestPackageUpdated.zip file
We should receive a 200 OK response with details of Blueprints created:
[javascript]
{ “operationType”: “IMPORT”, “operationStatus”: “WARNING”, “operationResults”: [ { “contentId”: “CentosMedium-12345”, “contentName”: “Centos - Medium”, “contentTypeId”: “composite-blueprint”, “operationStatus”: “SUCCESS”, “messages”: null, “operationErrors”: null }, { “contentId”: “CentosLarge-12345”, “contentName”: “Centos -Large”, “contentTypeId”: “composite-blueprint”, “operationStatus”: “SUCCESS”, “messages”: null, “operationErrors”: null }, { “contentId”: “CentosSmall-12345”, “contentName”: “Centos - Small”, “contentTypeId”: “composite-blueprint”, “operationStatus”: “WARNING”, “messages”: [ “Found matching content, import will overwrite this content.” ], “operationErrors”: null } ] }
[/javascript]
Now login to vRA and you will see the three Blueprints:
and if we look at the details of the medium template it is showing additional vCPU and RAM resource that were specified in the YAML file:
Obviously, there are many other changes that could be made within the YAML file to make different templates.
Create Blueprints from vRO
While researching this topic I initially looked at a similar approach to the above with Postman when moving on to do the same for vRO. However, looking at the updated vRA 7 plugin for vRO showed a folder of workflows for working with Composite Blueprints:
Rather than try and re-invent the wheel I decided to see what these could do, specifically the Import a composite blueprint workflow. It has inputs of a vCACCAFE:VCACHost and a MimeAttachement, so is pretty straightforward to use:
Thinking slightly further ahead, rather than just run this single workflow, I would more likely use this as part of a vRA Tenant Creation workflow and would store multiple YAML files within Resource Elements and possibly update them on the fly before using them to create Blueprints. For this example though I have stored one for CentosXLarge in a Resource Element to illustrate the possibility. This is exactly the same type of YAML file for a Blueprint used in the above example with Postman, just has different values for id, name, vCPU and memory to make it XLarge:
So we then make a top-level workflow with two elements; a scriptable task to retrieve the YAML file from a resource element and the built-in Import a composite blueprint workflow:
[javascript]
var yamlMimeAttachment = yamlResourceElement.getContentAsMimeAttachment()
[/javascript]
Now we can pass this MimeAttachement into the Import a composite blueprint workflow and set the vCACHost to be the host for the required vRA Tenant. From this workflow it will output the BlueprintId:
So we are ready to run the top level workflow. Specify a vCACHost and a YAML file in a ResourceElement and run the workflow:
Hopefully a successful run:
and here’s the Centos - XLarge Blueprint: