VMware Cloud Community
bdamian
Expert
Expert
Jump to solution

vRA 7.3 custom spec - Computer Name and Hostname

Hi all,

I need to specify the a "Computer Name" in customization spec different from the "Machine Name". I've modified the custom spec in vCenter as shown in the capture below:

pastedImage_0.png

But then, I cannot find the way to specify that parameter with custom properties. I always get the same error message: "A specified parameter was not correct: spec.identity.hostname"

pastedImage_1.png

I've tried with:

  • ext.policy.activedirectory.system.machineName
  • SysPrep.UserData.ComputerName
  • spec.identity.hostname
  • VirtualMachine.Admin.Name

Any ideas?

Thanks.

A specified parameter was not correct: spec.identity.hostname

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
1 Solution

Accepted Solutions
jasnyder
Hot Shot
Hot Shot
Jump to solution

I don't think what you want to do can be done with a single custom property value.

You can do it with the event broker and a machine lifecycle workflow.

Here is what the example looks like, first the request form of a requested VM:

pastedImage_0.png

I add the 'Hostname' property to the blueprint (although you could put it on the vSphere VM itself if you have composite blueprints).  I also added a new custom property called 'DisplayNameSuffix'.  The point is that the machine will get named according to the Hostname property, but we'll use the suffix to rename it in vSphere later.  Lastly, I added the Extensibility.Lifecycle.Properties.VMPSMasterWorkflow32.MachineProvisioned = * property to make sure properties to get passed to vRO later.

After the machine is completely provisioned, a vRO workflow runs which grabs the vCAC UUID from the machine properties, matches it to a vCAC Entity object, grabs the managed object ID, then matches it to a vSphere VM and calles the rename_Task() method on it.

Workflow run output looks like this:

[2017-11-24 22:30:54.389] [I] # VMs = 373

[2017-11-24 22:30:54.402] [I] Matched UUID = 501edba1-69ea-c3f5-b35d-6ae20a324faf ; moid = vm-12239

[2017-11-24 22:30:54.416] [I] vCAC UUID: 501edba1-69ea-c3f5-b35d-6ae20a324faf

[2017-11-24 22:30:54.418] [I] VM MOID: vm-12239

[2017-11-24 22:30:54.736] [I] Found VM in vSphere Inventory: test7

[2017-11-24 22:30:54.738] [I] Renaming VM in vSphere from: test7 to test7.test.local

[2017-11-24 22:30:54.854] [I] Rename_Task 0 %

[2017-11-24 22:30:56.858] [I] Rename_Task end

[2017-11-24 22:30:56.860] [I]    Done.  Task Result = null

In vSphere:

pastedImage_1.png

In the vRA Items tab:

pastedImage_4.png

The workflow is fairly simple.  Schema looks like this:

pastedImage_5.png

There is one attribute, vCACHost, which is of type vCAC:vCACHost.  You set it to the vCAC IAAS host you're using for this operation.

It takes a single input called props of type Properties.  This is the payload from vRA.  It gets wired to the inputs of the Rename VM task.

There is a single output called virtualMachineAddOrUpdateProperties of type Properties.  This holds any updates to machine properties you want to make from the workflow.  I commented out a section updating the 'VirtualMachine.Admin.Name' property because it's unclear if this is needed and the solution seems to work without it.  But you could uncomment it out if you want to test it.  Otherwise, there are no property updates made.

The Rename VM scriptable task content is:

virtualMachineAddOrUpdateProperties = new Properties();

if(props != null)

{

    var machine = props.get("machine");

    if(machine != null)

    {

        var vraProps = machine.get("properties");

           

       

        if(vraProps != null)

        {

            var uuid = vraProps["VirtualMachine.Admin.UUID"];

            var hostname = vraProps.get("Hostname");

            var suffix = vraProps.get("DisplayNameSuffix");

           

            //Only do something if user entered values for both hostname and suffix

            if(hostname != "" && suffix != "") {

                var requestId = vraProps.get("__Cafe.Root.Request.Id");

               

                var searchProperties = new Properties();

               

                var vmEntities = vCACEntityManager.readModelEntitiesByCustomFilter(vCACHost.id, "ManagementModelEntities.svc", "VirtualMachines", searchProperties, null);

               

                var vms = new Array;

                var vmProps = null;

                var vmMOID = "";

               

                System.log("# VMs = " + vmEntities.length);

                           

                for each (var v = 0; v < vmEntities.length; v++) {

                    var vEntity = vmEntities[v];

                   

                    if(vEntity != null) {

                        //vCAC UUID

                        var vmid = vEntity.getProperty("VMUniqueID");

                        //vSphere Managed Object ID

                        var moid = vEntity.getProperty("ExternalReferenceId");

                       

                        if (vmid == uuid) {

                            System.log("Matched UUID = " + vmid + " ; moid = " + moid);

                            vmMOID = moid;

                        }

                    }

                }

                           

                System.log("vCAC UUID: " + uuid);

                System.log("VM MOID: " + vmMOID);

               

                var vms = VcPlugin.getAllVirtualMachines();

                var vm = null;

               

                for(var v in vms) {

                    if(vms[v].id == vmMOID) {

                        System.log("Found VM in vSphere Inventory: " + vms[v].name);

                        vm = vms[v];

                        var fullName = hostname + "." + suffix;

                        System.log ("Renaming VM in vSphere from: " + vm.name + " to " + fullName);

                        var task = vm.rename_Task(fullName);

                       

                        var taskResult = System.getModule("com.vmware.library.vc.basic").vim3WaitTaskEnd(task, true, 2);

                        System.log("   Done.  Task Result = " + taskResult);

                       

                        //Uncomment if you want to update the VirtualMachine.Admin.Name property

                        //  It's unclear if you really need to do this after renaming the

                        //  machine in vSphere.

                        //virtualMachineAddOrUpdateProperties.put("VirtualMachine.Admin.Hostname", fullName);

                       

                        break;

                    }

                }

           

               

                System.log("Updated Machine Properties Passed Out:");

                for(var pk in virtualMachineAddOrUpdateProperties.keys)

                {

                    System.log("   " + pk + ". " + virtualMachineAddOrUpdateProperties.keys[pk] + " = " + virtualMachineAddOrUpdateProperties.get(virtualMachineAddOrUpdateProperties.keys[pk]));

                }

            }

        }

    }

}

And to setup the subscription:

pastedImage_8.png

And map to the workflow.  Be sure to publish after saving.

I have attached the workflow if you would like to review.

You will obviously want to apply these changes to a test environment.  You may also want to modify the subscription to only run for a specific blueprint to keep it from impacting others.

One last note - the script adds the dot in between the hostname and suffix, so no need to enter that.  You could change this if you want.

View solution in original post

Reply
0 Kudos
20 Replies
jasnyder
Hot Shot
Hot Shot
Jump to solution

Try the Hostname property (no prefixes).

From the Custom Properties Reference guide -

Hostname (page 66):

Specifies the host machine name, overriding the generated machine name contained in the VirtualMachine.Admin.Name property. If Hostname is not used, the VirtualMachine.Admin.Name value is used as the machine name. The maximum number of allowed characters for the Hostname value is 15

VirtualMachine.Admin.Name (page 83):

Specifies the generated machine name for vSphere, for example CodyVM01. When creating custom workflows or plug-ins for customizing a virtual machine name, set this property to match the name of the virtual machine. This is an internal input property for the agent to name the virtual machine. Note This property is for vSphere only. The value specified in the blueprint has no effect on this property. This property is not intended to be used to prompt the user. Use the HostName property to prompt the user. If the property is set at runtime, the container name that is created in the hypervisor might not match the item record name.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

Hi Jasnyder,

I've already tested those two also. Same error.

I don't know what else to do. There is no information on Internet about this topic. All posts assume that you use the "use machine name" option in the custom spec.

Thanks anyway.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
jasnyder
Hot Shot
Hot Shot
Jump to solution

OK, so your problem is you don't want to set it to that option on the customization spec side of things.  Is there a reason why you can't do that?  Perhaps one customization spec for users to use in the vSphere client and one to call from the blueprint in vRA?  Or is that too many specs to create and maintain?

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

I need to deploy VMs with names that contains dots (.) but for the hostname, I want only the part before the first dot. Ex: my new Virtual Machine called "mynewserver.domain.com" (we want to see this name on vCenter inventory) but the hostname must be "mynewserver".

So I can use the Hostname property to set the VM name, but I can't set the Hostname on the customization spec. If I use the option "use machine name", the hostname is invented (for windows) or is the hole vm name without dots (for linux). Neither is good.

I need to tell the Custom Spec the hostname but I cannot find a custom property to do it.

D.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
jasnyder
Hot Shot
Hot Shot
Jump to solution

So to clarify on this - you want the hostname to be different from the VM display name in vCenter, correct?

And the hostname would be a subset of the display name?  i.e. hostname.domain.com, so the VM hostname would be 'hostname' and the vcenter display name would be the full 'hostname.domain.com'

Or should it be the other way around?

And is it OK if the vRA machine display name is the full hostname.domain.com i.e. would match the vCenter display name and not the machine hostname?

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

Exactly like that. Please help.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
jasnyder
Hot Shot
Hot Shot
Jump to solution

I don't think what you want to do can be done with a single custom property value.

You can do it with the event broker and a machine lifecycle workflow.

Here is what the example looks like, first the request form of a requested VM:

pastedImage_0.png

I add the 'Hostname' property to the blueprint (although you could put it on the vSphere VM itself if you have composite blueprints).  I also added a new custom property called 'DisplayNameSuffix'.  The point is that the machine will get named according to the Hostname property, but we'll use the suffix to rename it in vSphere later.  Lastly, I added the Extensibility.Lifecycle.Properties.VMPSMasterWorkflow32.MachineProvisioned = * property to make sure properties to get passed to vRO later.

After the machine is completely provisioned, a vRO workflow runs which grabs the vCAC UUID from the machine properties, matches it to a vCAC Entity object, grabs the managed object ID, then matches it to a vSphere VM and calles the rename_Task() method on it.

Workflow run output looks like this:

[2017-11-24 22:30:54.389] [I] # VMs = 373

[2017-11-24 22:30:54.402] [I] Matched UUID = 501edba1-69ea-c3f5-b35d-6ae20a324faf ; moid = vm-12239

[2017-11-24 22:30:54.416] [I] vCAC UUID: 501edba1-69ea-c3f5-b35d-6ae20a324faf

[2017-11-24 22:30:54.418] [I] VM MOID: vm-12239

[2017-11-24 22:30:54.736] [I] Found VM in vSphere Inventory: test7

[2017-11-24 22:30:54.738] [I] Renaming VM in vSphere from: test7 to test7.test.local

[2017-11-24 22:30:54.854] [I] Rename_Task 0 %

[2017-11-24 22:30:56.858] [I] Rename_Task end

[2017-11-24 22:30:56.860] [I]    Done.  Task Result = null

In vSphere:

pastedImage_1.png

In the vRA Items tab:

pastedImage_4.png

The workflow is fairly simple.  Schema looks like this:

pastedImage_5.png

There is one attribute, vCACHost, which is of type vCAC:vCACHost.  You set it to the vCAC IAAS host you're using for this operation.

It takes a single input called props of type Properties.  This is the payload from vRA.  It gets wired to the inputs of the Rename VM task.

There is a single output called virtualMachineAddOrUpdateProperties of type Properties.  This holds any updates to machine properties you want to make from the workflow.  I commented out a section updating the 'VirtualMachine.Admin.Name' property because it's unclear if this is needed and the solution seems to work without it.  But you could uncomment it out if you want to test it.  Otherwise, there are no property updates made.

The Rename VM scriptable task content is:

virtualMachineAddOrUpdateProperties = new Properties();

if(props != null)

{

    var machine = props.get("machine");

    if(machine != null)

    {

        var vraProps = machine.get("properties");

           

       

        if(vraProps != null)

        {

            var uuid = vraProps["VirtualMachine.Admin.UUID"];

            var hostname = vraProps.get("Hostname");

            var suffix = vraProps.get("DisplayNameSuffix");

           

            //Only do something if user entered values for both hostname and suffix

            if(hostname != "" && suffix != "") {

                var requestId = vraProps.get("__Cafe.Root.Request.Id");

               

                var searchProperties = new Properties();

               

                var vmEntities = vCACEntityManager.readModelEntitiesByCustomFilter(vCACHost.id, "ManagementModelEntities.svc", "VirtualMachines", searchProperties, null);

               

                var vms = new Array;

                var vmProps = null;

                var vmMOID = "";

               

                System.log("# VMs = " + vmEntities.length);

                           

                for each (var v = 0; v < vmEntities.length; v++) {

                    var vEntity = vmEntities[v];

                   

                    if(vEntity != null) {

                        //vCAC UUID

                        var vmid = vEntity.getProperty("VMUniqueID");

                        //vSphere Managed Object ID

                        var moid = vEntity.getProperty("ExternalReferenceId");

                       

                        if (vmid == uuid) {

                            System.log("Matched UUID = " + vmid + " ; moid = " + moid);

                            vmMOID = moid;

                        }

                    }

                }

                           

                System.log("vCAC UUID: " + uuid);

                System.log("VM MOID: " + vmMOID);

               

                var vms = VcPlugin.getAllVirtualMachines();

                var vm = null;

               

                for(var v in vms) {

                    if(vms[v].id == vmMOID) {

                        System.log("Found VM in vSphere Inventory: " + vms[v].name);

                        vm = vms[v];

                        var fullName = hostname + "." + suffix;

                        System.log ("Renaming VM in vSphere from: " + vm.name + " to " + fullName);

                        var task = vm.rename_Task(fullName);

                       

                        var taskResult = System.getModule("com.vmware.library.vc.basic").vim3WaitTaskEnd(task, true, 2);

                        System.log("   Done.  Task Result = " + taskResult);

                       

                        //Uncomment if you want to update the VirtualMachine.Admin.Name property

                        //  It's unclear if you really need to do this after renaming the

                        //  machine in vSphere.

                        //virtualMachineAddOrUpdateProperties.put("VirtualMachine.Admin.Hostname", fullName);

                       

                        break;

                    }

                }

           

               

                System.log("Updated Machine Properties Passed Out:");

                for(var pk in virtualMachineAddOrUpdateProperties.keys)

                {

                    System.log("   " + pk + ". " + virtualMachineAddOrUpdateProperties.keys[pk] + " = " + virtualMachineAddOrUpdateProperties.get(virtualMachineAddOrUpdateProperties.keys[pk]));

                }

            }

        }

    }

}

And to setup the subscription:

pastedImage_8.png

And map to the workflow.  Be sure to publish after saving.

I have attached the workflow if you would like to review.

You will obviously want to apply these changes to a test environment.  You may also want to modify the subscription to only run for a specific blueprint to keep it from impacting others.

One last note - the script adds the dot in between the hostname and suffix, so no need to enter that.  You could change this if you want.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

So you suggest that I should provision the vm with the hostname, and then, in post provision, rename the vm and the vcac entity. Right?

It's a good workaround. Thanks. I will try that.

But should be a custom property for this in the next version.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
jasnyder
Hot Shot
Hot Shot
Jump to solution

I agree that there should be better handling of unforeseen provisioning details in all kinds of resources.  If the devs would look into matching a prefix to object creation in the code, it would be helpful.  In your case, it's creating a customizationspec and submitting it as part of a machine reconfiguration in vSphere.  If you could dynamically drive the details of that request by looking for custom properties that match a pattern, then they could leave it open ended to fix problems like this.  In your case, if you could add something like "VMware.VirtualMachine.Provisioning.CustomizationSpec.identity.hostname" then their code would read the first 4 sections of that and determine the last 2 are there to set the spec.identity.hostname parameter according to the value of the custom property.  Seems easy enough...

The same issues apply to Amazon EC2 provisioning.  Almost nothing on the instance request object is customizable and they could easily make this work by doing he same custom property pattern matching as above and setting request object members according to those things.  I say easily, but I know it would take some work, and it would be hard to document the whole thing given how open ended it would be.  But it sure would make things a lot more flexible.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

I will try your suggested approach, I'll might change some parts or the code (don't like the "getAllVms" part) but, if it works, I'll mark your answer as the correct one.

Thanks,

D.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
jasnyder
Hot Shot
Hot Shot
Jump to solution

Fair enough.  One other thing you might want to change in the code:

//Only do something if user entered values for both hostname and suffix

            if(hostname != "" && suffix != "") {

Should be

//Only do something if user entered values for both hostname and suffix

            if(hostname != null && suffix != null hostname != "" && suffix != "") {

Just in case you end up calling the workflow from a request that doesn't have one or both of those properties present, it will show up as null which would pass the != "" test, and may inadvertently end up renaming a machine unnecessarily.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

Thanks a lot jasnyder, it works smoothly,

Here is my final solution with a little code just to add some value to this thread:

In vRA subscriptions, I've used the "VMPSMasterWorkflow32.MachineActivated" state and phase POST

In the workflow, I've started using "getVirtualMachineEntity" from the plugin library to get the vRA entity, then I've wrote the following code (with comments)

var props = vmEntity.getProperties();

var vmName = props.get("VirtualMachineName");

var moid = props.get('ExternalReferenceId');

// Again I'm using an action from the vRA plugin library

var vms = System.getModule("com.vmware.vcac.asd").findVcObjectsByMoRefId('VC:VirtualMachine',moid);

// Because could have many vCenter endpoints, I could get more that one VM. Check the name to be sure

var vm = null;

for each(var v in vms) {

    if (v.name == vmName) {

        vm = v;

    }

}

if (vm==null) throw 'Cannot find the VM ' + vmName + ' with moid ' + moid;

// Rename the VM and wait until is finished

var task = vm.rename_Task(newVmName);

System.getModule("com.vmware.library.vc.basic").vim3WaitTaskEnd(task,null,null);

// Change the name on vRA properties

props.remove('VirtualMachineName');

props.put('VirtualMachineName', newVmName);

// This could be used to update any property in a vRA entity

var hostId = vmEntity.hostId;

var modelName = vmEntity.modelName;

var entitySetName = vmEntity.entitySetName;

var entityIdString = vmEntity.keyString;

System.getModule("com.vmware.library.vcac").updateVCACEntity(hostId,modelName,entitySetName,entityIdString,props,null,null);

I hope this could be useful for other people.

D.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
pizzle85
Expert
Expert
Jump to solution

This solution has worked for years. My only issue with it is that my vSphere team doesnt like the fact that the underlying artifacts (vmx, vmdk, folder, etc) are named with the hostname instead of the FQDN until a sVMotion is performed. What i ended up doing was exactly like jasnyder suggested just a bit more complex.

1. Create the VM with the FQDN

2. In the cloneMachine POST state, rename the VM to the hostname.

3. In the machineProvisoined state, rename the VM back to the FQDN.

It would be nice to have a custom property to feed to the customization spec to avoid all the run around.

Reply
0 Kudos
KoThwin
Contributor
Contributor
Jump to solution

Hello , In my case, we use the deployed VM's host name same with VM name. Now, our environment changed the option to get the host name input from custom properties and change the host name with user input one (not with VM name). I think my scenario is same like you. Could you please kindly mention about

  • custom properties that we have to attach with VM
  • Event subscription condition and
  • Workflow a little detail

I hope your answer.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

Hi KoThwin,

The solution is exactly the one is marked as a correct answer. The Custom Property to ask for the name is "hostname" (is a shortcut).

The correct answer has all the steps you need to do.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
KoThwin
Contributor
Contributor
Jump to solution

Hello Damian,

Thanks for your explanation.

According to marked one(correct answer), I tried to configure the vRA setting like below screenshots.

  • For my case ( our developer team , want two inputs for VMs(Host name (computer name) and VM name. So, I configured the custom properties like this.

  • After that I mapped these custom properties to our blueprint. And then, create the event subscription with attached workflow from correct answer.

But, I still get the errors associated with this error.

I hope you will see and give some advices for my case. Thanks

Reply
0 Kudos
pizzle85
Expert
Expert
Jump to solution

The way I do it is to name the VM what we want it to be named in the end, which in our case is the FQDN. The machine is built with the FQDN as the name, this ensures all related files have the same name as the VM. Then through a vRO workflow I rename the machine to what I want it named in the OS. My customization Spec is set to set the OS name the same as the VM name. Then once the customization spec has completed running i rename the VM back to what i want the VM named via another vRO workflow.

Reply
0 Kudos
bdamian
Expert
Expert
Jump to solution

Hi KoThwin,

I cannnot see your screenshots. But you need to use "hostname" and a second custom property that you like for the Machine Name. When the deployment is finished, you need to change the name of the VM for the one specified in the second custom property.

If you set a name for hostname or Machine Name that already exists in vCenter, the Blueprint will raise an error.

D.

---
Damián Bacalov
vExpert 2017-2023 (7 years)
https://www.linkedin.com/in/damianbacalov/
https://tecnologiaimasd.blogspot.com/
twitter @bdamian
Reply
0 Kudos
KoThwin
Contributor
Contributor
Jump to solution

Hello Damian,

I have reattached the screenshot files on my original post.

My VM deployment scenario brief

--------------------------------------------

  • Our organization will use new naming format for VM (26  characters). So, we would like to get this VM name via customer input.
  • In the before, we used VM name as OS name. But, now, we can't use VM name as OS name . Cause character length is so long.
  • So, we tried to get another input hostname (OS name) from user and after deployement , VM name will be 26 characters and OS name (Host name) will be in the range of 15 characters for future FQDN process.

I have attached my customization specification also.

Thanks for continuous replying me.

Reply
0 Kudos