Estimated reading time: 12 minutes

While the VCF Automation portal is a powerful tool for managing deployment activities, there’s always room to enhance access and visibility. Imagine maintaining a running log of deployments, enriched with key details for added context. Better yet, consider forwarding these logs to a centralized Syslog server like VCF Operations for Logs, Splunk, or a similar platform to centralize the record of events and share information across teams.
The use case discussed in this article was inspired by a blog post from Dale Hassinger, a vExpert and VCF enthusiast behind the vCROCS blog. Dale explained how to programmatically send Syslog messages to VCF Operations for Logs (formerly Aria Operations for Logs or vRealize Log Insight). Building on his ideas, this article explores how you can use the RFC 3164 standard to achieve a similar goal.
Our objective is straightforward: automatically send a Syslog message to VCF Operations for Logs whenever a new VM is successfully deployed. These messages will include key details, making them both informative and concise. Let’s explore how to make it happen.
Prerequisites
- Access to VCF Automation and Automation Orchestrator.
- Successful deployment of VMs using VCF Automation Cloud Templates.
- Syslog server listening on port 514 (can be modified in the workflow if needed).
Identify Properties
The first step is to identify which deployment properties we consider useful for our Syslog message. I will provide a few suggestions in this demo but keep in mind that any input gathered at time of deployment in addition to many properties generated automatically are accessible to you. In your own environment, open a deployment in VCF Automation Assembler or Service Broker. With the deployment open, look at the right-side pane and notice there are a few expandable headings: General, Storage, Network, Cloud Config, and Custom Properties.

Expand each section and explore the available values. Make note of the ones you find valuable. I find the “Custom Properties” section to be most fruitful. Below is an example of just a few properties you may find in your environment:

Create the Orchestrator Workflow
Browse to your VCF Automation Orchestrator instance, then click on the “Workflows” menu item, located beneath the “Library” heading. If you would like to build the workflow in a particular folder, select it now, then click on the “New Workflow” button.

The “New Workflow” dialog box appears. Give your workflow a meaningful name. You can always change the name later and the Workflow is not visible to end-users. In our demo, I will use the name “vRLI – Register Deployment Activity“. Next, click on the “Create” button.

The Workflow now opens and is relatively empty. The first thing to do is change the “Version” value from “0.0.0” to something else, as you cannot publish a version 0 to the catalog. In this case, I will stick with “0.0.1“.

If you would like, add a meaningful Description to the workflow. This is optional, but can help you distinguish between versions or similar workflows in the future.
Next, we need to instruct the Workflow to gather the full payload of Input Properties from a given deployment. Click on the “Inputs/Outputs” tab, located across the ribbon, then click on the “New” button.

The “New Input Parameter” box appears. Keep the “Input” radio button ticked. Change the “Name” field to “inputProperties” (without quotes). The most important part is to change the “Type” field from the default value of “string” to “Properties“. Leave the “Array” checkbox un-checked, then click on the “Create” button.

This is a good time to pause for a moment and click on the “Save” button, located at the bottom-left corner of the window. It is recommended to save frequently to avoid loss of work due to session timeouts, mistakes, etc.
Click on the “Schema” tab, located along the ribbon.

Notice that a blank canvas has appeared. The left-side pane includes a collection of elements to drive various aspects of your workflow. Click and drag the “Scriptable Task” workflow element onto the blue arrow located canvas, between the “start” and “end” points.

The “Scriptable Task” element should now be placed on the canvas, as shown below. Note that you may click and drag to rearrange any element on the canvas to give you more room or organize the elements differently.

Although the “Scriptable Task” element should already be selected by default, click on it to select. Notice the right-side pane has expanded and displays several attributes. Let’s rename the Scriptable Task to something more meaningful. In this example, I have named mine “Send Syslog Message“. Notice that the name is reflected on the canvas in real-time. Click on the “Inputs/Outputs” heading to expand the list of available options.
Notice there are no Inputs nor Outputs defined. Click on the plus (+) icon, located to the right of the “Inputs” heading. A lookup field appears, with a magnifying glass icon to the left. Click inside the field, then click on the “inputProperties” value from the autocomplete menu, which we created in previous steps.

Once you click on the “inputProperties” option from the autocomplete menu, notice that we now have an Input of type Properties, bound to the “inputProperties” input.

This is a great start, but I want to add an output to capture any errors which may occur. Now would be a great time to click on that “Save” button!
Click on the “Variables” tab, located across the top ribbon.

Similar to when we built our input in previous steps, click on the “New” button. The “New Variable” box appears. Set the “Name” field to “errorCode“, then click on the “Create” button.

Return to the workflow canvas by clicking on the “Schema” tab, located along the top ribbon. Locate the “Throw Exception” workflow element, located in the left-side pane. Click and drag the element on top of the “Send Syslog Message” element, located on the canvas. I moved my elements around a bit for visibility, but your canvas should appear similar to the below:

The “Throw Exception” element on your canvas may be selected already by default, but click on the icon if the “Workflow Element” pane does not appear on the right-side of your window. If necessary, click on the “Exception Handling” heading to expand. Notice that the “Output exception binding” field is empty. Click on the “Select Variable” field, then click on the “errorCode” variable we created in previous steps.

Click on the “Send Syslog Message” workflow element, located on your canvas, then click on the “Inputs/Outputs” heading to expand the menu. Click on the “plus sign” icon (+) located to the right of the “Outputs” heading. Just as above, click on the “errorCode” variable.
Next, click on the “Scripting” tab, located on the right-side pane. The default “Runtime Environment” is JavaScript by default, as you can see below the “Scripting” tab. Click on the dropdown menu and select “PowerShell 7.4“. Although the PowerShell version will change over time, version 7.4 is the latest at the time of this article.
VCF Orchestrator provides 10 lines of PowerShell code to help get you started. Select and delete all code within the box, then copy and paste the code below:
function Handler($context, $inputs) {
### Set Variables
$inputsString = $inputs | ConvertTo-Json -Compress
#Write-Host "Inputs were $inputsString" #Uncomment line for troubleshooting
### Build Syslog Function
function Send-SyslogMessage {
Param (
[string]$IP = "192.168.1.1", # Default Syslog server IP
[int]$Port = 514, # Default Syslog server UDP port
[string]$Facility = "syslog", # Default Syslog facility
[string]$Severity = "info", # Default Syslog severity
[string]$Content = "No Content provided", # Default Message content
[string]$SourceHostname = "automation.domain.local", # Default Hostname
[string]$Tag = "Automation" # Default Tag for the message
)
# Map RFC 3164 facilities to numeric values
$facilityMap = @{
kern = 0; user = 1; mail = 2; daemon = 3;
auth = 4; syslog = 5; lpr = 6; news = 7;
uucp = 8; cron = 9; authpriv = 10; ftp = 11;
ntp = 12; audit = 13; alert = 14; clock = 15;
local0 = 16; local1 = 17; local2 = 18; local3 = 19;
local4 = 20; local5 = 21; local6 = 22; local7 = 23;
}
# Map RFC 3164 severities to numeric values
$severityMap = @{
emerg = 0; alert = 1; crit = 2; err = 3;
warn = 4; notice = 5; info = 6; debug = 7;
}
# Resolve facility and severity values
$facilityValue = $facilityMap[$Facility.ToLower()]
$severityValue = $severityMap[$Severity.ToLower()]
if (-not $facilityValue) { $facilityValue = $facilityMap["syslog"] } # Default to syslog
if (-not $severityValue) { $severityValue = $severityMap["info"] } # Default to informational
# Calculate the syslog priority value
$pri = "<" + (($facilityValue * 8) + $severityValue) + ">"
# Timestamp in RFC 3164 format
$timestamp = (Get-Date).ToString("MMM dd HH:mm:ss")
# Create the syslog message
$header = "$timestamp $SourceHostname "
$msg = $pri + $header + $Tag + ": " + $Content
# Convert message to ASCII bytes
$byteArray = [System.Text.Encoding]::ASCII.GetBytes($msg)
# Send the message via UDP
$udpClient = New-Object System.Net.Sockets.UdpClient
$udpClient.Connect($IP, $Port)
$udpClient.Send($byteArray, $byteArray.Length) | Out-Null
$udpClient.Close()
$output = "Syslog message sent to " + $IP + ":" + $Port
Write-Host $output
}
### Set Input Variables
$actionName = $inputs.inputProperties.requestInputs._catalogItemName # Name of the Catalog Item in Service Broker
$objName = $inputs.inputProperties.deployment_details.resourceName # Name of the VM
$projName = $inputs.inputProperties.projectName # Name of the associated Project
$createdBy = $inputs.inputProperties.deploymentOwner # User ID who created the deployment
$deploymentName = $inputs.inputProperties.deploymentName # Name of the Deployment
$deploymentId = $inputs.inputProperties.deploymentId # The Deployment ID generated by VCF Automation
$osEdition = $inputs.inputProperties.requestInputs.os_version # The Operating Sytem selected for deployment. Adjust the field name as needed to match your environment.
$syslogMessage = "New Deployment Executed: $actionName. Deployment Name: $deploymentName. Deployment ID: $deploymentId. Operating System: $osEdition. Created by: $createdBy. Scoped Object: $objName. Scoped Project: $projName." # The message strong sent to the Syslog server
### Write Syslog Message
try {
Send-SyslogMessage -Content $syslogMessage
Write-Host $syslogMessage
}
catch {
Write-Host "Error sending syslog message. $_"
throw $_
}
return $output
}
PowerShellI highlighted a few lines which you will need to modify to reflect your environment:
Line 9 – Change the provided IP Address with the IP Address of your Syslog server.
Line 10 – If needed, change the provided Syslog port. Although ports 514 and 1514 are standard for Syslog traffic, your configuration may vary.
Line 14 – Change the provided source FQDN to reflect the FQDN of your VCF Automation instance. This will help the Syslog server determine the source of the message.
Lines 65-72 – Remove variables which you do not intend to reference in your Syslog message and add a couple of your own, if you would like. Note that any variables you add/modify/remove from lines 65-71 must also be reflected on line 72, per the above example.
Once the code is modified, click on the “Save” button, located at a bottom-left corner of the window.
Discover the new Workflow in Assembler
Now that the new Workflow has been created, we need to discover it in VCF Automation Assembler to finish our configuration. Although Assembler will routinely synchronize with VCF Orchestrator, we will initiate a sync manually to help move things along.
Browse to VCF Automation Assembler, then click on the “Infrastructure” tab, located along the top ribbon.

Scroll down the left-side navigation as needed, then click on the “Integrations” menu item, located beneath the “Connections” heading.
Click on the “embedded-VRO” Integration from the displayed table. Note that your Orchestrator instance may be named something different – select as appropriate.
Click on the “Start Data Collection” button, located beneath the health indicator widgets. Allow a few moments for this process to complete.

Click on the “Extensibility” tab, located along the top ribbon, then click on the “Subscriptions” menu item located on the left-side navigation bar.

The “New Subscription” page appears. Inside the “Name” field, type a meaningful name for this event subscription. In this case, I will use “TEST-Register_Deployment_in_vRLI“. You can always change the name later without consequence.
Click on the “Add” button, located to the right of the “Event Topic” text label.

The “Event Topics” box appears. This controls at what point the subscription should fire. In this case, I want the workflow to trigger when a given deployment is complete. Locate the “Deployment Completed” Event Topic, tick the radio button to select, then click on the “Select” button.

Since I only want this workflow to trigger if a VM is created, we will set a Condition. If we do not set this condition, the workflow will trigger on deployment updates and removals (“destroy”) as well, which is not what we want. Click on the slider button to the right of the “Condition” text label to enable the field. Notice that a small code text box appears below.
Type or paste the JavaScript code below inside the field:
event.data.eventType == 'CREATE_DEPLOYMENT'
JavaScript
Next, click on the “Add” button located to the right of the “Action/Workflow” text label. By default, the “Runnable Type” is scoped to display results for “ABX Action“. Click on the “ABX Action” button, then click on the “Workflow” menu item.

Browse the list of Workflows and tick the radio button for the workflow we just created. Use the search box to locate it quickly, as there are many pre-built workflows (over 500!) populated by default. Once selected, click on the “Select” button.

Although you could limit the subscription to only trigger on certain projects or enable blocking, we will leave the default values for now. Click on the “Save” button.
You are now ready to give it a try! Deploy a new VM using VCF Automation, and wait for the Deployment Status to indicate that it is complete. Once complete, check your Syslog server to determine if a message has been recorded.
You can check the instances of Workflow runs from within VCF Orchestrator, which can provide useful information for troubleshooting as needed. In this case, we can see that our run was successful:
2024-11-21 10:30:16.394 -05:00infoSyslog message sent to 192.168.1.1:514
2024-11-21 10:30:16.395 -05:00infoNew Deployment Executed: Windows Server. Deployment Name: Windows Server / 2411.01-REQ0123456. Deployment ID: 350b9324-c71c-485b-b732-6b5424cc2adc. Operating System: Windows_Server_2019. Created by: MyUser. Scoped Object: myTestVM. Scoped Project: My Project.