VMware Cloud Community
nateconehealth
Contributor
Contributor

Trying to Add VM Tags Via vRO Workflow

UPDATE: Just realized that for the property (vRA.Deployment.Tags) I only have the tag name entered in the Value column for the dropdown. Do I need to add a way to reference the tag category? Not sure how to add that to the property.

UPDATE 2: Doesn't look like the workflow requires a tag category. I'm trying to force the workflow to give me more information in the logs, see at what step it's failing.

UPDATE 3: Found the issue, but not sure how to fix it. So the issue is that in the Variables section of the last run of the setVcTags workflow, I can see the following:

vmName: (here it gives the correct VM name)

errorCode: "Could not find VM (Dynamic Script Module name : findVcVmByName#7)"

Because the result of vmName isn't getting properly passed to the vm attribute (type: VC:VirtualMachine), or at least it can't find it based off that name, the workflow ends.

I may end up opening a ticket with VMware to see why it's not getting passed properly.

Hey everybody,

Novice vRO user here (yaaaay) - so I've been tasked with having vRA assign 1 of 2 tags to every single VM when it's being created (for these examples, "Backup Tag 1" and "Backup Tag 2"). We're doing this to enable auto backups in Avamar.

Here's the site that I've been using: Assigning vCenter tags using vRealize Orchestrator – The vGoodie-bag

So far I have:

  1. In vRO client, run "Import vAPI metamodel" successfully.
  2. Imported this package: vCenterTagging/com.vGoodie-Bag.library.vapi.package at master · KnutssonDevelopment/vCenterTagging ·...
  3. Went to the setVcTags workflow in vRO (vGoodie-Bag > setVcTags) > edit > endpoint > changed to "https://[my vCenter FQDN]/api"
  4. Created property "vRA.Deployment.Tags" as a dropdown (X = Backup Tag 1, Y = Backup Tag 2) and added it to the Blueprint.
  5. (I already have a LifeCycle Property Group with pretty much all the "VMPSMasterWorkflow32" entries, plus two "CloneWorkflow" ones, so just made sure that was in the Blueprint as well.)
  6. Created a new Subscription: setVcTags > Machine provisioning > Lifecycle state name = "VMPSMasterWorkflow32.MachineActivated" > State phase = "POST" > selected the "setVcTags" workflow from the imported package > Finish
    1. NOTE: This is one of the steps where I got confused, since they mention sorting workflows in vRO but don't give any information at all - I'm assuming the fact that I chose a state phase when creating the subscription means I'm good?

Now when I build a VM in vRA, it successfully builds, and after a while vRO says that the setVcTags workflow ran successfully (under Logs it has two messages - "Settings vCenter Tags" and then "Tags: Backup Tag 1") - however, no Tags appear in vCenter for that VM.

I'm assuming I'm just missing something with how I've set this up in vRO - obviously vRA is calling the workflow because I see it running, but nothing's making it back to the VM. Maybe I haven't tied in the right action at the end of the workflow or something? I'm really sorry if I've missed something obvious, this is my second time trying any serious workflow, and the first one I'm piecing together myself.

Let me know if any other info is helpful, and I would love any suggestions of what to check next. Thanks!

16 Replies
daphnissov
Immortal
Immortal

Especially if you're a vRO novice, I'd highly recommend you check out the SovLabs module for vSphere tagging. Using this requires no custom vRO code and is as simple as adding a custom property to your blueprint or anywhere else that creates a tag, and the module does the rest.

pastedImage_0.png

pastedImage_1.png

I actually have a blog post coming out soon about this, so I'll try and post it here to my profile first so you can get the idea of how simple that is.

Reply
0 Kudos
nateconehealth
Contributor
Contributor

Their vRO modules seem awesome, the problem is that their stuff costs money. Smiley Sad Don't think I'd be able to get approval for that at the moment.

Reply
0 Kudos
daphnissov
Immortal
Immortal

FYI, I put the blog up here if you want to see how that solution would address vSphere tagging.

Reply
0 Kudos
hawks76
Enthusiast
Enthusiast

We add tags by invoking a powershell script and running powercli commands.  Works like a champ everytime.  Very simple and straighforward.
Reply
0 Kudos
nateconehealth
Contributor
Contributor

Huh, that's awesome. For someone just getting into this, would you mind sharing how you have it setup and what the script is? Thanks!

Reply
0 Kudos
hawks76
Enthusiast
Enthusiast

Sure.  Give me a little bit to put all the info together and i'll post it.
Reply
0 Kudos
nateconehealth
Contributor
Contributor

Awesome, thanks! You have no idea how excited I am - been trying to tweak a workflow I imported for days now and getting nothing but errors.

Reply
0 Kudos
hawks76
Enthusiast
Enthusiast

Ok, So, here is how we do tags

Components:

Resource Element with the following script:

$DC = "%%location%%"
$appCode = "%%appcode%%"

If ($DC -eq "DCNAME1") { $vc = "VCNAME1" }
If ($DC -eq "DCNAME2") { $vc = "VCNAME2" }

##### Imports Core Module  #####
If (!(Get-Module VMWare.VimAutomation.Core)) { Import-Module VMWare.VimAutomation.Core }

##### Connects to vCenter  #####
Connect-VIServer $vc -Credential $creds | Out-Null

##### Validates tag exist, and if not, creates it, and attaches it to specific category  #####
If (!(Get-Tag $appCode -ErrorAction SilentlyContinue))
{
    New-Tag -Name $appCode -Category (Get-TagCategory APP_CODE) -ErrorAction SilentlyContinue
}

##### Executes tag assignment  #####
if (!(New-TagAssignment -Entity (Get-VM %%vmName%%) -Tag (Get-Tag $appCode) -ErrorAction SilentlyContinue)) { return $false } else { return $true }

##### Closes connection to vCenter  #####
Disconnect-VIServer * -Force -Confirm:$false

Custom Action called "invokeScript"

Invoke Scrip Custom Action.png

Here is Custom Action Script Contents to copy:

var output;

var session;

try {

    session = host.openSession();

    output = invokeScript(host,script,session.getSessionId()) ;

} finally {

    if (session){

        host.closeSession(session.getSessionId());

    }

}

return output;

function invokeScript(host,script,sessionId){

if(sessionId == null){

    throw "PowerShellInvocationError: Invalid session."

}

var oSession = host.getSession(sessionId)

if (oSession == null )

{

    throw "PowerShellInvocationError: Invalid session."

}

System.debug("Invoke command in session " + sessionId);

var result = oSession.invokeScript(script);

if (result.invocationState  == 'Failed'){

    throw "PowerShellInvocationError: Errors found while executing script \n"  + result.getErrors();

}

//System.log ( result.getHostOutput() );

return ( result.getHostOutput() );

}

Here is the workflow setup

Attributes.png

Inputs.png

Schema.png

Scriptable task.png

Here, we are tagging each vm with an application code.  Ofcourse, you could change the property that gets sent in to anything you want. As well, the Categorys we use are already setup. Not all the App codes are setup, so as shown in the ResourceElement, it checks for it first, and creates it if it doesn't exist.

We trigger it to run base on an Event Subscription for conditions MachineActivated and POST.

I'm sure there will be questions, as i'm terrible at explaining things.

Thanks!

Reply
0 Kudos
nateconehealth
Contributor
Contributor

That's very helpful, thanks! This is new to me so getting the PowerShell host added and working with scripts is going to take a while, but this is a great start.

I do have one question so far - I created the workflow and entered the script as you put, just changing the following:

"site.com.rf.app.code" to "vRA.Deployment.Tags" (had already created this as a custom property)

"site.com.rf.actions" to (module name that I created)

However, when I go to save it, it's saying there's a syntax error on this line:

if (!(actionResult.match( "True" ) != null)) {throw ("TagError"); ) ;

Any ideas on that? Thanks!

Reply
0 Kudos
hawks76
Enthusiast
Enthusiast

Check the quotes.  Sometimes when quotes get copied, they don't copy correctly. just remove and replace them and see if that helps.

Just saw the error. You need to change this ("TagError"); ) ; to this ("TagError"); } ;

Closing bracket is ) instead of }.

Reply
0 Kudos
Mnemonic
Enthusiast
Enthusiast

Hi, if you ask your questions on the article on my blog I notice them, and try to respond. Assigning vCenter tags using vRealize Orchestrator – The vGoodie-bag

Did you remember to create the tags in vCenter?

Reply
0 Kudos
Mnemonic
Enthusiast
Enthusiast

The benefit of using javascript in orchestrator is that it is MUCH faster and easier when returning data.

Reply
0 Kudos
parakkatil
Contributor
Contributor

I am passing my vm tag as input attribute just to test the workflow. When i run the workflow, i can see  the logs where the input attribute replaces the variable in the powercli. But i keep encountering the error "The term '?' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."

It seems to be a powercli related error but have verified each line and no "?" term exists here, I even replaced the script to exact same as pasted in the blog( with values pertaining to my environment) and still hit on the same error. If i am to hard code the varible values and run the powercli script, it runs perfectly fine.

Is there anything that i am missing. I am no javascript excpert. Appreciate any help on this.

i am pasting the logs here.

 

***************************************************************

[2018-11-30 16:42:57.325] [E] (io.mlctech.hi/invokeScript) Error in (Dynamic Script Module name : invokeScript#30) PowerShellInvocationError: Errors found while executing script 

System.Management.Automation.CommandNotFoundException: The term '?' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)

   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)

   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

   at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)

   at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)

   at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)

   at System.Management.Automation.ScriptBlock.<>c__DisplayClass57_0.<InvokeWithPipe>b__0()

   at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)

   at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Boolean propagateAllExceptionsToTop, List`1 variablesToDefine, Dictionary`2 functionsToDefine, Object[] args)

   at System.Management.Automation.ScriptBlock.InvokeUsingCmdlet(Cmdlet contextCmdlet, Boolean useLocalScope, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Object[] args)

   at Microsoft.PowerShell.Commands.InvokeExpressionCommand.ProcessRecord()

   at System.Management.Automation.CommandProcessor.ProcessRecord()

Reply
0 Kudos
hawks76
Enthusiast
Enthusiast

Copy the Powershell code out and run it on the powershell host in ISE.  that should give you more detail where the error is actually occuring.
Reply
0 Kudos
parakkatil
Contributor
Contributor

My update. i got it work after passing the script as a string instead of the resource element. Something that I need to troubleshoot later as to why using resource element did not work.

Another issue that i came across was the "payload" properties you specify in the workflow script is case sensitive and need to be exactly the way it is in vRA property dictionary. I just used logging to find where the error is at each stage.

Hopefully this helps those who encounter similar issue.

Thank you hawks76​ for posting and reaching out to help.

Reply
0 Kudos
DurgadeviN
Contributor
Contributor

After a little bit of pain I am able to assign tags to vRA-provisioned virtual machines on vCenter through vRO.

1) Configure VAPI endpoint in vRO.

2) Create property definitions (vRA.Deployment.Tags) in vRA.

3) Create a subscription Event Machine Provisioning as below.

pastedImage_4.png

4) Edit Blueprint and Add custom property Extensibility.Lifecycle.Properties.VMPSMasterWorkflow32.MachineProvisioned

pastedImage_0.png

Have a look into workflow.

pastedImage_0.png

Inputs : payload (type=properties),

pastedImage_1.png

pastedImage_3.png

pastedImage_4.png

pastedImage_5.png

Thank You.:)