In the VMware CMBU lab, I built something cool that I wanted to share. Creating a demo for vRealize Network Insights featured called Flow-based Application Discovery, I needed to get applications running in the lab to dynamically resize from time to time. In a demo three tiered application; add one or two web or app servers, or remove them. Flow-based application discovery would then detect the change and suggest updating the application in Network Insight.
One of the requirements is that there has to be traffic going between all servers before application discovery picks it up. That’s what led me to write this action.
Disclaimer: The script itself is quite specific. If you want to use it, expect to need to modify it to your needs.
The application isn’t a big thing and it’s easy to build. A web server at the front, that connects over HTTP to an application server, that in turn connects to a MySQL server.
The web servers have an NGINX service running that configures the web server to forward requests to the app servers. That means the web servers need to know the list of app servers when the deployment changes. vRealize Automation’s API can dig up a list of IPs that the app servers have but only when it’s done deploying. Maybe I should rephrase that: you can only trust the list once it’s done deploying.
This post doesn’t go through the entire cloud template configuration, but know that the 3 tiers are also represented in the blueprint. Another important detail is that the OS password for the deployed VMs is a Cloud Template Input – so it gets asked when you deploy this blueprint. It’s what the script uses to log into the web servers.
If you don’t want to store these passwords like this, you could also consider to use SSH key authentication. You can put the SSH public key into the VM template and store the SSH private key as a secret that’s passed to the action script when it runs. I just had low security requirements for this one; it’s a demo environment.
vRealize Automation has event-based automation called subscriptions. You can subscribe actions to an event and run code when something happens. That something could be a deployment request, network provisioning, kubernetes cluster allocation, and the one I’ll be using here, when a deployment completes. There are about 60 of these events, so you can get creative.
The Deployment Complete event gets fired when a new deployment or update of an existing deployment completes. Perfect for post-deployment steps where you need the full details of the deployment as it is after vRA is done.
You’ll need to create the action first, which I’ll cover in the next chapter, but for the sake of explaining the logic: knowing about subscriptions first, made sense to me. Here’s the configuration I used:
Simple enough, right? Give it a name, select the Deployment complete event from the Event Topic list and select the action.
Now for the good part, what does the action do? The code is in the GitHub Gist below, but let’s have a look at how to add it to vRA first:
Adding an action defaults to Python and the only modification needed is the Dependency field with requests (API calls) and paramiko (SSH). And of course putting the script into the left side.
Talking about the script, let’s (finally!) take a look at it. First off, the logic is as follows:
- Action runs when the event triggers. It’ll provide basic info to the script, like deployment ID (line 83)
- Take the deployment ID and request the full deployment details from the vRA API
- From the deployment details, find the IP addresses of the web and app servers (line 100)
- Loop through the web server IPs, SSH into them and update the NGINX config to point to the list of app servers (line 111)
When adopting this for your own purposes, the most interesting lines will be 100 to 104 (that determines what servers we’re looking for), and then the function reconfigureWebserver. That is where the commands are defined that run on the servers and the SSH connection takes place. Without further ado, here’s the script:
Let me know if you use this action in your setup!