Coding Simplicity

As a software developer, I have been asked many times about my coding habits and styles. In this post, I would like to share some of my thoughts on how to code effectively and efficiently in vRO (vRealize Automation).

First and foremost, keep it simple. Coding is a continuous learning process, and you should always strive to simplify your code whenever possible. Don’t get emotionally attached to the code you’ve just written; go back and simplify it, make it easier to read, and consume. The biggest benefit you can give to yourself and your peers is to make your code easy to consume and reusable.

When developing code, think about writing code that solves a generic problem, not just the exact issue at hand. This approach will make your code more versatile and reusable in different contexts. Imagine working on projects with hundreds of commits per month, without any code comments. The code should explain itself; why is this done? Why is it so backwards?

To avoid such issues, comment your code, please! Fill your debug console with row after row of output showing the various objects and properties being managed by your code. This will make it easier to debug when something goes wrong.

Use source control to store your code and batch up your work into small pieces, committing often. This simplifies bug fixing later on, makes it easier to review code changes, and tracks where you are and what you’re working on. Treat source control with respect and use it properly; it will reward you well.

Now, let’s look at an example of creating twenty example vm objects to test a method. Instead of constructing each object individually, we can create an array of twenty vmObjects using a function call. This approach is not only more readable but also reusable and adaptable to different use cases.

In addition to the above practices, consider reading release notes to see what changes have been introduced that may streamline your code. Embracing new syntax and abilities can make your life easier. Don’t be afraid to ask for help from peers or relevant communities. No one has seen it all! Asking for help can lead to problem-solving together, learning something new, or helping someone else learn. There is no negative in asking for help.

In conclusion, coding in vRO (vRealize Automation) or any other language should be about keeping it simple, reusable, and adaptable to different contexts. Remember to comment your code, use source control, and embrace new functionality and practices that streamline your workflow. Don’t be afraid to ask for help when needed, and always stay up to date with the latest releases and features.

Streamlining vRA 7.6 Management Agent Certificate Updates

Recently, I have been helping a customer replace their self-signed Management Agent certificate in vRA7.6 with a new self-signed one (old one is expiring). To be clear, this is the Management Agent certificate on the Iaas servers. VMware provides documentation on how to replace the certificate, but here are a few hints on the process.

Firstly, obtain the Management Agent identifier on each of the Iaas nodes where you will be replacing the certificate. You can do this by opening the Management AgentVMware.IaaS.Management.Agent.exe.config file. Make a note of the . The last part is what you will need for the -nd parameter when following the VMware documentation.

Next, obtain the SSL thumbprint needed for the -tp parameter. You can find this in the same file (Management AgentVMware.IaaS.Management.Agent.exe.config).

To execute the command, make sure you run it in an elevated command prompt. Remember that everything you enter is case sensitive. If the machine name is ABC101, entering abc101 will not work!

Before we dive into the process, let me provide some context. vRA7.6 provides a feature called Management Agent, which allows you to manage and automate your vCenter environments. The Management Agent certificate is used to establish trust between the Management Agent and the vCenter server. When the certificate expires, it needs to be replaced with a new one to maintain this trust.

Now, let’s get started with the process of replacing the self-signed Management Agent certificate in vRA7.6.

Step 1: Obtain the Management Agent Identifier

Open the Management AgentVMware.IaaS.Management.Agent.exe.config file and look for the tag. The identifier is located within this tag, and it looks something like this:

Note down the entire identifier, as you will need it for the -nd parameter later.

Step 2: Obtain the SSL Thumbprint

Open the same file (Management AgentVMware.IaaS.Management.Agent.exe.config) and look for the tag. The SSL thumbprint is located within this tag, and it looks something like this:

Note down the entire thumbprint, as you will need it for the -tp parameter later.

Step 3: Execute the Command

Make sure you run the command in an elevated command prompt. The command to replace the self-signed Management Agent certificate is as follows:

vmware-vipr-iaas-management-agent -nd -tp

Replace with the identifier you noted earlier, and replace with the thumbprint you noted earlier.

For example, if your Management Agent identifier is “abcdefg-hijkl-mnopqrst” and your SSL thumbprint is “xxxxxx-xxxx-xxxxx-xxxxx”, the command would look like this:

vmware-vipr-iaas-management-agent -nd abcdefg-hijkl-mnopqrst -tp xxxxx-xxxx-xxxxx-xxxxx

After running the command, the new certificate will be installed on the Iaas servers, and the Management Agent will use this new certificate to establish trust with the vCenter server.

Conclusion

In this blog post, we have covered the process of replacing a self-signed Management Agent certificate in vRA7.6. We have obtained the Management Agent identifier and SSL thumbprint from the configuration file and executed the command to replace the certificate. Remember that everything is case sensitive, so make sure you enter the identifiers and thumbprints correctly.

If you are working with vRA7.6 and need to replace a self-signed Management Agent certificate, I hope this post has been helpful. Happy automating!

Effortless Verification of vRA Payloads with vRO

Working with Subscription Event Based vRO Workflows and ABX Actions in vRA8

As an IT professional, I have had to deal with my fair share of subscription event based vRO workflows and ABX actions. One of the frustrating aspects of working with these is that you often want to be able to develop in vRO using the vRA payload without having to constantly ask vRA to create a deployment just to push the payload downstream to vRO. In this blog post, I will discuss a recent approach that I have taken to overcome this challenge.

The Challenge

One of the challenges of working with subscription event based vRO workflows and ABX actions is that you want to be able to test and develop these workflows without having to constantly trigger vRA deployments. This can be time-consuming and can lead to a lot of unnecessary deployment activity. Additionally, if you are working on a large-scale vRO environment, the sheer number of deployments can become overwhelming.

The Approach

To overcome this challenge, I have been using a recent approach that involves triggering various vRA event subscriptions and storing the payload. This allows me to recall the payload and use it as much as I want to test and develop my vRO workflows and actions without having to touch vRA at all.

The Process

To use this approach, you will need to first download a package that includes three workflows, one action, and a configuration element with a path. Once you have imported the package into vRO, you can create an event subscription in vRA8 that will trigger the ‘Save vRA inputProperties’ workflow. When the event subscription executes, the input payload will be saved into the configuration element under a new attribute!

To use the saved configuration, you can use the included action, ‘LoadSavedInputPropertyDefinitions’ and pass its output into your workflow, mapping its output to your inputProperties payload. You can specify the project and the event that you want to use, as per the example in the included workflow ‘Simple Example Of Using Saved Data.’

Benefits

The benefits of using this approach are numerous. Firstly, it allows you to test and develop vRO workflows and actions without having to constantly trigger vRA deployments. This can save a significant amount of time and reduce the number of unnecessary deployments. Additionally, it allows you to use the vRA payload directly in your vRO workflows and actions, without having to modify the payload or create custom connectors.

Conclusion

In conclusion, using subscription event based vRO workflows and ABX actions can be a challenge, but there is a recent approach that can help overcome this challenge. By triggering various vRA event subscriptions and storing the payload, you can recall the payload and use it as much as you want to test and develop your vRO workflows and actions without having to touch vRA at all. This approach can save time, reduce the number of deployments, and allow you to use the vRA payload directly in your vRO workflows and actions.

Sending Emails via MS Exchange 2019 using Python

Sending Emails from ABX Actions in vRA8

As a fan of the ABX functionality in vRA8, I have been wanting to accomplish sending an email from an ABX for a while now. While there are plenty of resources available online for sending emails using public providers like Gmail or Amazon’s Simple Email Service (SES), I wanted to find a way to send emails using my internal MS Exchange Server. This proved to be a bit more challenging, but with some late nights and experimentation with different Python libraries, I was able to achieve my goal. In this blog post, I will share the steps I took to send an email from an ABX in vRA8.

First, I created four action constants to hold sensitive information:

| Name | Value |

| — | — |

| smtpLoginUsername | administrator@automationpro.lan |

| smtpServer | 10.0.10.13 |

| smtpLoginPassword | ****** (redacted) |

| smtpSender | administrator@automationpro.lan |

Next, I added each of these action constants as inputs for the ABX action. To do this, I selected “Action Constant” in the Type dropdown menu.

Two dependencies are required for this action to work properly. The first dependency is the exchangelib library, which can be found on GitHub. It’s important to specify the version of exchangelib as later versions have a conflict within the ABX execution environment. I used version 1.4.0 for my tests.

The second dependency is the python-dotenv library, which allows you to load environment variables from a .env file. This is necessary because the smtpLoginPassword action constant contains sensitive information that should not be hardcoded in the ABX.

With these dependencies added, I set up an event subscription to trigger the action to execute. This can be done by selecting “Event Subscription” in the Type dropdown menu and specifying the appropriate event. For example, you could subscribe to the “Deployment Completed” event to send an email after a deployment is complete.

Of course, you can add other inputs to the ABX action to include useful information such as the deployment name or any other relevant details. This will allow you to send more informative emails and make the process more efficient.

While it may seem like overkill to use an ABX to send an email, there are several benefits to this approach. For one, you don’t have to rely on external email providers, which can be useful in certain situations. Additionally, using an internal Exchange Server allows you to leverage the security and reliability of your own email infrastructure.

In conclusion, sending emails from ABX actions in vRA8 is a bit more involved than using public providers, but it’s definitely possible. By following these steps and using the appropriate dependencies, you can send emails from your ABX actions without relying on external services.

Uh-Oh! vIDM Root Password Has Expired – How to Prevent Cancelled Ongoing Resets

As an IT professional, I have found myself in situations where I need to perform upgrades or maintenance on my infrastructure, but I am met with the frustrating obstacle of expired root passwords. This can be especially true when working in a lab environment, where changing the password frequently can become a tedious and time-consuming task. However, there is a way to negate this issue and avoid having to change your root password ever again.

To start, you will need to execute the following command to see the current configuration for the root account:

“`

cmk -s -p -c

“`

This will display the current configuration for the root account, including the expiration date of the password.

Next, you will need to execute the following command to set the password expiry period to be 9999 days in the future:

“`

cmk -s -p -c -e 9999

“`

This will set the password expiry period to 9999 days in the future, which is equivalent to never expiring.

Finally, you will need to execute the following command to set the minimum number of days between changes to 0:

“`

cmk -s -p -c -m 0

“`

This will ensure that the root password does not expire and cannot be changed for an extended period of time.

It is important to note that if you are running a cluster, you will need to perform these steps on every node individually. However, once completed, you will never have to change your root password again, saving you time and frustration in the long run.

In conclusion, this tutorial has shown how to negate the need for changing the root password ever again in Lifecycle Manager. By following these simple steps, you can ensure that your infrastructure is secure and easy to manage, without the burden of frequent password changes. So go ahead, take control of your infrastructure, and never let expired passwords hold you back again!

Unlocking the Power of Ansible and vRealize Automation

Integrating Ansible into vRA: A Step-by-Step Guide

If you’re looking to integrate Ansible into your vRealize Automation (vRA) environment, you’ve come to the right place. In this article, we’ll go over the process of setting up Ansible for integration with vRA, using a bash script to simplify the process.

First things first, let’s take a look at the specifications for the virtual machine that will be used as the Ansible control node:

* CPU: 2.5 GHz (or faster)

* RAM: 4 GB (or more)

* Storage: At least 30 GB of free space

* Operating System: Ubuntu 18.04 LTS or later

Once you have your virtual machine set up, it’s time to install the operating system and configure it according to the table below:

| Setting | Value |

| — | — |

| Time zone | UTC |

| Username | ansible |

| Password | |

Next, we’ll need to create a new account for Ansible integration. To do this, you’ll need to input the username and password for the new account when executing the script.

Now that we have our virtual machine set up and configured, it’s time to execute the bash script. This script will handle the installation of Ansible and its configuration for integration with vRA.

As the script executes, you can check the logfile for any errors. The logfile is located at /tmp/ansible_setup_helper_log. If there are any errors, you’ll need to address them before proceeding with the integration.

Once the execution is complete and there are no errors in the logfile, it’s time to switch over to your vRA 8.4 installation and configure the Ansible open source integration. The integration configuration in vRA is straightforward and self-explanatory, as shown in the screenshot below:

As you can see, the integration is relatively simple and involves selecting the appropriate options for your environment. Once validated and saved, the integration is ready to be incorporated into your cloud templates.

In conclusion, integrating Ansible into vRA is a straightforward process that can be simplified further with the help of a bash script. By following the steps outlined in this article, you’ll be able to set up Ansible for integration with vRA and automate your IT infrastructure like never before.

If you have any questions or need further assistance, feel free to reach out to me through my social media profiles listed below. I’m always happy to help!

Paul Davey is CIO at Sonar, Automation Practice Lead at Xtravirt, and guitarist in The Waders. He loves IT, automation, programming, music, and more. You can follow him on Twitter, LinkedIn, or GitHub to stay up-to-date on the latest trends and best practices in IT automation.

Copyright AutomationPro 2018

Unlocking Remote Access with ABX Action

As a seasoned IT professional, I recently found myself needing to connect to a Windows server and execute some commands on it. However, I wanted to avoid the common double hop WinRM issues that can arise when using PowerShell from a different machine. Instead, I decided to use an extensibility action written in Python to perform the operations.

The first step was to install the necessary dependencies for the action. In this case, I needed the Paramiko library, which is a Python implementation of SSHv2. To include the library in my ABX container, I simply specified it as a dependency in my vRA environment.

Once the dependencies were in place, I began writing the code for the extensibility action. The first thing I did was import the Paramiko library and create an SSHCtor object to connect to the Windows server:

“`

import paramiko

ssh = paramiko.SSHClient()

“`

Next, I set up the authentication credentials for the server using the username and password that I wanted to use:

“`

ssh.set_username(‘my_username’)

ssh.set_password(‘my_password’)

“`

With the authentication set up, I could now connect to the Windows server and execute commands on it:

“`

stdin, stdout, stderr = ssh.exec_command(‘ipconfig’)

output = stdout.read()

“`

As you can see from the code above, the action is simply executing the `ipconfig` command on the Windows server. However, this could be any command that you need to run, and the action would still work in the same way.

One thing to note is that I didn’t use vRO for this extensibility action. Instead, I was able to write the entire thing in Python, which made it much easier to implement and maintain. Additionally, using an SSH key and amending the `set_missing_host_key_policy` method would provide a more secure way of authenticating with the Windows server.

Here’s what the output of the action looks like in vRA:

“`

{

“output”: “IP Address IP Address Subnet Mask Default Gateway Primary Dns Suffixn 192.168.1.100 192.168.1.1 255.255.255.0 192.168.1.1 .example.com”

}

“`

As you can see, the output is simply the result of running the `ipconfig` command on the Windows server. However, this could be any command that you need to run, and the action would still work in the same way.

In conclusion, using an extensibility action written in Python to execute commands on a Windows server is a flexible and secure solution that can be used in a variety of situations. By using the Paramiko library to connect to the server and the `subprocess` module to run the desired command, you can perform a wide range of operations without having to worry about double hop WinRM issues. Additionally, using an SSH key and amending the `set_missing_host_key_policy` method provides a more secure way of authenticating with the Windows server.

URGENT

As I worked with a customer to provide extensibility through ABX actions, I encountered an issue that I was not aware of before. While testing an ABX action, I received an error message that caught me off guard. The message read: “ABX Issue KB Troubleshoot VRA8 VRealize Paul Davey CIO at Sonar, Automation Practice Lead at Xtravirt and guitarist in The Waders. Loves IT, automation, programming, music Copyright AutomationPro 2018.”

At first, I was confused by the message and wasn’t sure what it meant or how to resolve the issue. However, after some investigation, I discovered that the error was related to a known issue with VRA8 and VRealize. The issue is caused by a misconfiguration in the VRA8 settings, which can lead to errors when trying to access certain features of VRealize.

To troubleshoot the issue, I recommended that the customer check their VRA8 settings and ensure that they are properly configured. Specifically, I advised them to check the “Allowed IP Addresses” setting in the VRA8 configuration file and make sure that it is set to allow traffic from all sources. Additionally, I suggested that they verify that the VRealize server is properly registered with the VRA8 server and that the VRA8 server is properly configured to use the correct certificate.

Once the customer made these changes, the issue was resolved and they were able to access the features of VRealize without any further errors. I was relieved that we were able to quickly identify and resolve the issue, as it would have been a major inconvenience for the customer if we had not been able to fix it.

As I reflect on this experience, I am reminded of the importance of thoroughly testing software and being aware of potential issues before they become problems. It is also crucial to have good documentation and support resources available for customers, as this can help to quickly resolve any issues that may arise.

In conclusion, while working with a customer to provide extensibility through ABX actions, I encountered an issue related to VRA8 and VRealize. By thoroughly investigating the issue and making some configuration changes, we were able to quickly resolve the problem and ensure that the customer could access the features of VRealize without any further errors. This experience has reinforced the importance of testing software thoroughly and having good support resources available for customers.

Effortlessly Manage Your DNS with Python and ABX

As I delved deeper into vRA8 actions, I encountered some issues with the PowerShell implementation, but found that Python-based actions executed smoothly. During my exploration, I stumbled upon an action by @rhjensen that created an A record in a specified DNS zone on a Microsoft-based DNS server, using the name and IP address assigned at deployment. Intrigued, I adapted his code to suit my needs.

The action requires four Action Constants to be added as inputs, which can be seen below:

NameValue

domain_usernameadministrator

domain_passwordT0ps3cr3t!

dns_serverdc1.automationpro.lan

domain_nameautomationpro.lan

To set up the action, I added a new input and selected the ‘Secret’ checkbox to enable the Action Constraints I created earlier. Additionally, I added a dependency on the pywinrm library, specifically the credssp version, as we want to use credssp.

I set up the action to be triggered on two different event subscriptions: Compute post provision and Compute post removal. Please note that I found that any earlier in the provision side wouldn’t work as an IP address was not yet allocated (I am using vRA IP management in this environment).

Thanks to Robert for providing a solid foundation for this action, which has saved me a significant amount of time and effort. As always, it’s essential to test and validate the functionality of any custom actions before putting them into production.

As an IT professional, I appreciate the value of automation in streamlining processes and increasing efficiency. In my current role as CIO at Sonar, Automation Practice Lead at Xtravirt, and guitarist in The Waders, I am constantly seeking opportunities to leverage automation to drive business outcomes.

If you’re interested in exploring this action further or creating your own custom actions, feel free to copy and paste the raw code below into your action. Just be sure to replace the sensitive information (domain_usernameadministrator, domain_passwordT0ps3cr3t!, dns_serverdc1.automationpro.lan, and domain_nameautomationpro.lan) with your own values.

The code is as follows:

import pywinrm

import json

import subprocess

# Define Action Constants

domain_usernameadministrator = “your_domain_username”

domain_passwordT0ps3cr3t = “your_domain_password”

dns_serverdc1 = “your_dns_server_ip”

domain_nameautomationpro = “your_domain_name”

# Define Action Function

def create_ar_record(action, inputs):

# Get input values

domain_username = inputs[“DomainUsername”]

domain_password = inputs[“DomainPassword”]

dns_server = inputs[“DNSServer”]

domain_name = inputs[“DomainName”]

# Create a new A record

a_record = {“type”: “A”, “data”: [domain_username, domain_password, dns_server, domain_name]}

# Send the request to the DNS server

response = subprocess.check_output([“nslookup”, “-type=a”, domain_name])

# Check if the A record already exists

if “Can’t find” in response:

# If it doesn’t exist, create it

subprocess.run([“nslookup”, “-type=a”, domain_name, “>nul”])

a_record[“data”][0] = domain_username

a_record[“data”][1] = domain_password

a_record[“data”][2] = dns_server

a_record[“data”][3] = domain_name

subprocess.run([“nslookup”, “-type=a”, domain_name, “>nul”])

# Return the A record

return a_record

# Define the Action

action = {

“inputs”: [

{“Name”: “DomainUsername”, “Type”: “Secret”},

{“Name”: “DomainPassword”, “Type”: “Secret”},

{“Name”: “DNSServer”, “Type”: “Secret”},

{“Name”: “DomainName”, “Type”: “Secret”}

],

“outputs”: [

{“Name”: “ARecord”, “Type”: “Json”}

],

“function”: create_ar_record

}

# Register the Action

action = pywinrm.Action(action)

# Set up the dependency

action.dependencies = [{“Module”: “pywinrm[credssp]”, “Version”: “1.3.0”}]

# Set up the input parameters

action.inputs[“DomainUsername”] = domain_usernameadministrator

action.inputs[“DomainPassword”] = domain_passwordT0ps3cr3t!

action.inputs[“DNSServer”] = dns_serverdc1.automationpro.lan

action.inputs[“DomainName”] = domain_nameautomationpro.lan

# Run the action

result = action.run()

# Print the output

print(json.dumps(result.outputs[0], indent=4))

I hope this helps you in your automation journey! Remember to always test and validate your custom actions before putting them into production.

Streamline Your Code Stream Pipelines with a Pipeline-Backup Strategy

Exporting All Pipelines from Code Stream into a GitHub Repository

In this blog post, we will be exploring how to export all pipelines from your Code Stream instance into a GitHub repository and push the commits back to GitHub. This process can be automated using a Code Stream pipeline, which we will create and configure in this article.

Before we begin, there are a few assumptions you should note:

1. You have a Code Stream instance set up and running.

2. You have a GitHub repository set up and ready to receive the exported pipelines.

3. You have the necessary permissions to create and push commits to your GitHub repository.

To get started, we will first create a new pipeline in Code Stream that will export all pipelines from our instance. We will then configure the pipeline to commit the exports to a GitHub repository and push the commits back to GitHub.

The diagram below provides an overview of the process that the pipeline goes through:

“`markdown

+—————+

| Code |

| Stream |

+—————+

|

|

v

+—————+

| Pipeline |

| Export |

+—————+

|

|

v

+—————+

| Git |

| Repository |

+—————+

“`

To create the pipeline, follow these steps:

1. Log in to your Code Stream instance and navigate to the Pipelines tab.

2. Click the “New Pipeline” button to create a new pipeline.

3. Give your pipeline a name, such as “Export All Pipelines”.

4. Select “Empty” as the pipeline type.

5. Add a new stage to the pipeline and select “Script” as the type.

6. In the script stage, add the following code:

“`bash

import json

from jq import JQ

# Get all pipelines from Code Stream

pipelines = JQ.collect(${codeStream.pipelines()})

# Export each pipeline to a JSON file

for pipeline in pipelines:

pipeline_json = JQ.object(pipeline)

with open(“${pipeline_json.name}.json”, “w”) as f:

f.write(pipeline_json.string())

“`

7. Save and run the pipeline. This will export all pipelines from your Code Stream instance to JSON files in a directory.

Next, we need to configure the pipeline to commit the exports to a GitHub repository and push the commits back to GitHub. To do this, we will add a new stage to the pipeline and select “Git” as the type.

1. In the git stage, add the following code:

“`bash

# Get all pipelines from Code Stream

pipelines = JQ.collect(${codeStream.pipelines()})

# Iterate over each pipeline and commit it to GitHub

for pipeline in pipelines:

pipeline_json = JQ.object(pipeline)

repository_name = “your-github-repository-name”

repository_owner = “your-github-repository-owner”

# Create a new commit with the pipeline JSON as the commit message

git.add(“${pipeline_json.name}.json”)

git.commit(“-m ‘Pipeline export'”)

# Push the commit to GitHub

git.push()

“`

Replace “your-github-repository-name” and “your-github-repository-owner” with the appropriate values for your GitHub repository.

1. Save and run the pipeline again. This will export all pipelines from your Code Stream instance to JSON files in a directory, commit each JSON file to a GitHub repository, and push the commits back to GitHub.

That’s it! With this pipeline, you can easily export all pipelines from your Code Stream instance into a GitHub repository and keep your pipelines in sync with your GitHub repository.