Create Resource Actions for any vCAC resource with ASD

One of the coolest new features in the Advanced Service Designer in vCAC 6.1 is the “Resource mappings”. Resource mappings is the way to tell ASD how to map a resource from vCAC’s catalog, that was provisioned by a provider other than ASD, to an inventory item in vCO, so that you can execute custom ASD resource actions over this resource. Basically this we already had this in 6.0 but only for IaaS types Virtual Machine, vCD vApp and vCD VM, but it was only for these types without the ability to map other resource types. Now if you open the resource mappings view, you will se those 3 built-in there and you will be able to add others for any resource type and this is what we will do.

Resource mappings list

Let’s go over how this thing works with an actual example. We request an IaaS blueprint that provisions an Amazon Virtual Machine. After the blueprint succeeds, IaaS register this resource in the catalog, so that we can manage it. When it registers it, it also provides some valuable metadata for the resource like id (internal and/or external), name, description and anything other that it finds interesting. IaaS has also published a set of day 2 operations for this resource. Now, we want to be able to execute other day 2 operations based on a vCO workflow. For the example we will use something as simple as the “Start Instances” workflow that comes with the AWS plugin. Of course you will be able to use any other workflow and write your own.

So at this point on one side we have a Cloud Machine resource, representing the Amazon Machine in vCAC, and on the other side we have a vCO workflow that accepts an inventory item of type AWS:EC2Instance. Now we need to define how are we going to map one to the other.

In ASD this is enabled by the so called “Mapping workflow”. A mapping workflow should have one input of type Properties – a collection of key value pairs and one output – the inventory item we want to map to of type AWS:EC2Instance. The Properties input will be populated by ASD, with the data it can retrieve from vCAC for the specified resource, the metadata that I wrote about above, that IaaS provides. So based on these properties, we need to pick something relevant that we can use to find the vCO inventory item, being from a specific plugin like AWS, or a generic one like the REST plugin. The tricky part is that for different resource types, different properties will be provided, so you will not be able to assume that if you create one mapping for one item type, you will be able to use the same properties to create another workflow to map it to another type. So if you will be developing such workflow it will be good at the beginning this workflow to just return null for the output and print out all properties so that you can see what is available and decide how you will find the vCO inventory item from the other system.

Mapping workflow schema

Mapping workflow schema

In our case, mapping the Cloud Machine of type Amazon, we see that there is this property “ExternalReferenceId” that holds the id as it is in the external system, i.e. the instance id in Amazon. So now, having this id the workflow can query the AWS plugin to find a Instance with this id in Amazon. It is important to know that vCO should be configured to use the same Amazon account as vCAC. You can see sample code of the “Find instance” scripting activity bellow, but please have in mind that I don’t guarantee this is the best approach to find an amazon instance, as this solution is a bit slow, because it queries all Amazon clients in sequence.

var result = null;

var instanceId = properties.get('EXTERNAL_REFERENCE_ID');
var allInstances = [];

// Create a request for finding instances with this instanceId
var instancesRequest = new EC2DescribeInstancesRequest();
instancesRequest.withInstanceIds([instanceId]);

// Retrieve all Amazon clients
var clients = Server.findAllForType("AWS:AWSClient");
for (var i = 0; i < clients.length; i++)
{
    var client = clients[i];

    var ec2Client = client.getAmazonEC2Client();

    var request = new EC2DescribeAvailabilityZonesRequest();
    var describedInstances;
    try {
        describedInstances = ec2Client.describeInstances(instancesRequest);
    } catch (e) {
        // Error is thrown if the client cannot find instances with the specified instanceId
        continue;
    }
    var reservations = describedInstances.getReservations();
    for (var j = 0; j < reservations.length; j++) {
        var reservation = reservations[j];
        allInstances = allInstances.concat(reservation.getInstances());
    }
}

if (allInstances.length == 0) {
    Server.error("Could not find any instances with instanceId [" + instanceId + "]");
} else {
    if (allInstances.length > 1) {
        Server.warn("More than one instance with instanceId [" + instanceId + "] found, returning the first.");
    }

    result = allInstances[0];
}

return result;

Now that we have the workflow, we can create the mapping, if you are not sure it works, don’t worry you can always edit the workflow later.
So now to create a new Resource mapping we go to Advanced Services -> Resource Mappings and click the “+” button. On the form we specify the basic stuff – name and description for our mapping. Now for source of the resource mapping, i.e “Catalog Resource Type”, we lookup for “Cloud Machine” and for target, i.e. “Orchestrator Type”, the type of the AWS plugin – AWS:EC2Instance. And bellow on the workflow chooser we need to find the workflow we just created to make the mapping.

Create resource mapping

After this if you look at the available resource mappings you will see our newly created mapping

Created resource mappings list

With this we are done with defining the mapping. Now we can start creating ASD resource actions based on workflows that accept “AWS:EC2Instance” as input. When we select the “Start instances” workflow for our resource action you will see that you can select the mapping that we defined for the input parameter of this resource action.

Create resource action

Now when we publish the resource action and go to the items page, we will see this action in the list of available actions.

ResourcesResources - actions

And with this we are done creating a custom ASD resource action for a Cloud Machine resource.

For more examples you can checkout the resource mappings workflows for the built-in mappings located at /vCAC/ASD/Resource Mappings/vCenter and /vCAC/ASD/Resource Mappings/vCloud Director 

7 comments

  1. Jonathan Medd · April 27, 2015

    Thanks, this is great info! Couldn’t find any other examples out there of a good use case

    Liked by 1 person

  2. Dan Cohen · November 15, 2015

    Very helpful! How do you test your mapping once you added it?

    Like

  3. Dan Cohen · November 15, 2015

    Very helpful! How d you test your mapping once you added it?

    Like

  4. Tony Georgiev · November 16, 2015

    Thanks Dan!
    The mapping workflow is executed everytime you invoke an ASD day2 operation based on this mapping. To verify that the mapping works, or to check what’s wrong with it, you can open the vCO client and check the execution of the workflow that is doing the mapping. You can observe it’s attributes, what it got as an input and what it found. If this is not enough you can add additional System.log() statements around the scripting activities. It is not necessary that you invoke the day 2 operation everytime from vCAC to validate the mapping, you can do that only in the vCO client by providing the expected properties that are passed from vCAC.

    Like

    • Dan Cohen · November 17, 2015

      Thanks man!

      I have another question(a long one) –
      I was trying to create a resource action for a MultiMachine. Now I’ve created a test mapping workflow to check what properties are being sent with a multimachine and that is what came out:

      2015-11-17 15:26:00.412] [I] key:MachineDailyCost-0
      [2015-11-17 15:26:00.412] [I] key:MachineInterfaceType-MultiMachine
      [2015-11-17 15:26:00.412] [I] key:MachineName-lab-vra40
      [2015-11-17 15:26:00.412] [I] key:MachineStorage-0
      [2015-11-17 15:26:00.412] [I] key:Reset-true
      [2015-11-17 15:26:00.413] [I] key:IS_COMPONENT_MACHINE-false
      [2015-11-17 15:26:00.414] [I] key:Reconfigure-true
      [2015-11-17 15:26:00.414] [I] key:MachineType-Multi-Machine
      [2015-11-17 15:26:00.414] [I] key:MachineGroupName-IT
      [2015-11-17 15:26:00.414] [I] key:AddComponentsAppServices-true
      [2015-11-17 15:26:00.415] [I] key:Destroy-true
      [2015-11-17 15:26:00.415] [I] key:PowerOff-true
      [2015-11-17 15:26:00.415] [I] key:Reboot-true
      [2015-11-17 15:26:00.415] [I] key:MachineStatus-On
      [2015-11-17 15:26:00.415] [I] key:MachineBlueprintName-NAT03
      [2015-11-17 15:26:00.415] [I] key:Shutdown-true
      [2015-11-17 15:26:00.416] [I] key:ChangeLease-true
      [2015-11-17 15:26:00.416] [I] key:MachineInterfaceDisplayName-Multi-Machine
      [2015-11-17 15:26:00.416] [I] key:machineId-c33d879c-5f74-413c-ac42-db15a76b7b4c

      I’m looking for a way to get the virtual machines under a multimachine, and I don’t see any property that can link me to them.

      I tried to query back the vCAC so maybe with the machineId i would be able to get the machines names from vCAC. But so far no luck.

      Like

      • Tony Georgiev · November 17, 2015

        I haven’t tried it, but recently a fellow blogger wrote about multi machine day 2 http://virtualviking.net/2015/11/13/day-two-operations-on-multi-machine-blueprints-in-vrealize-automation-6-2/

        He has a script that based on the machineId goes back to vCAC to get the VirtualMachine object. Once you have it you can get it’s child virtual machines with scripting like:

        var entityVm = vm.getEntity();
        var childEntities = entityVm.getLink(host , “ChildVirtualMachines”);

        Like

      • Dan Cohen · November 19, 2015

        I don’t see the reply button beneath the comment, so I’ll leave it here.
        You’re awesome dude, I’m going to recommend your blogs to my colleagues
        Thank you for you help

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s