Heads up - Due to popular demand, I've rewritten this article to include a more elegant solution for vRA 7.x - it's available here.
This particular article is based on a solution to a particular set of use cases.
I recently implemented a similar solution at a customer where the requirement was to integrate with well over 50 different domains, from a single instance of vRA.
This will, obviously, still also work with a single domain.
So, first off, some context...
We have a use case exposing a requirement to create Microsoft DNS A record whenever a virtual machine is provisioned. Now, normally, when using Active-Directory integrated DNS, when a machine joins a domain, the DNS entry is created. Great. But what if we wanted to control that for different operating systems?
Such is the use case. Now, you're probably aware that there is no Microsoft DNS plug-in for vRO. This means we're in a position to use something else. It's easy enough to put my C# knowledge to the forefront, but that leaves the code closed. So I figured I would do this using Powershell.
Let's first clear something up. I was questioned time and again as to why I didn't just use the vRO plug-in for Powershell. Well, there are a number of reasons:
In a production environment with sensitivity to the already cumbersome, load-balanced, highly available implementation, we had Identity (SSO1), vRA1, vRA2, vRO1, vRO2, SQL 1, SQL 2, IaaS1, IaaS2, DEM1 and DEM2. That's a fair amount of VMs. Then we had load balancers. The DEMs live in a separate VLAN. The reasons for this design are many, not in the scope of this article.
The issue(s) with the vRO Powershell Plug-In.
The Powershell plugin requires one to add a Powershell Host to the Inventory. Furthermore, to complement my design, we would need to load-balance the Powershell hosts. You could argue that we could use the DEMs, since they're already windows servers anyway, but the need to stick to HA principles denies us that opportunity because we would need to load-balance them. This would impact the design. So, we would need 2 separate PS hosts. And yet another load balancer. If we don't load-balance the PS hosts, we lose HA. To mitigate this, we would add two hosts to the vRO Inventory, but (big but) we would need to create a smart interim workflow that checks for connectivity and, upon failure, moves on to the next PS host.
Why? Because the plug-in will only connect to the PS host you specify, and if it's down, fail.
So we'd need to write a custom workflow to mitigate that. It's getting complex and even more clunky. And I don't like it. Not one bit. It's not my style.
Right. "Ons gaan NOU Braai " (It's a South African thing - google it).
Solution: Powershell executed in the DEMs.
Why, you ask? Well, it addresses the above issue of HA. Inherently. The DEMs, by their design, have built-in HA which we are leveraging. They are Windows Servers (for now) which means they will run Powershell without a hitch. Locally. Without a plug-in. No additional load balancers. No additional nodes. Same design. Easy-as-pie. Well, mostly.
First off, we create a powershell script to create a DNS entry, and another to delete a DNS entry.
Now, let's be clear. You would still need to do this bit if you were using vRO. This but does not change.
The next bit: Create XAML workflows (pronounced "ZAMIL" (phonetically like camel. Camels smell bad though, so we'll use XAMLs instead)), to execute the Powershell.
The powershell will execute on the DEMs. We will install the MS RSAT (Remote Server Administration Toolkit) feature on the DEM Servers, specifically selecting DNS. This installed powershell CmdLets allowing us to remotely execute commands against the target DNS Server, in a dynamic remoted script session, leveraging WinRM.
I've seen a few solutions in the past and one of the constant struggles is around secure management of credential information.
This particular solution decrypts passwords from vRA. Yup. You read right.
I'll write it again. It decrypts the account passwords you store as encrypted custom properties, stored in vRA :-)
or your convenience, I've attached the two XAML files (because the camels refused to upload) for you to use in a POC or Demo environment.
Disclaimer: I accept no responsibility for anything not working. It worked perfectly in my use case, but it's at your own risk to implement or use these workflows or Powershell Files.
The ZIP comprises the following files:
The XAML files included in the package are Windows (.NET) workflows, compiled as XML. These simply go and collect a bunch of custom properties from the VM during the provisioning phase and execute the accompanying powershell script, passing a bunch of variables into the Powershell Script obtained from custom properties.
These XAML files are uploaded to the Repository using a command-line tool included with your installation of vRA.
The Powershell files, similarly, are also uploaded to the Repository using the same command-line tool. The procedure for this will follow imminently.
There are also two XML Files. There are files that need to be copied into a location, to hook our workflows into the correct phases in the VM lifecycle.
Wait, what does THAT mean?
Every VM has a lifecycle associated with it, as you probably already know.
The source of this lifecycle lives on the Manager Services. It is this very source that allows vRO integration during the lifecycle, where the DEM calls out to vRO during a number of phases during the lifecycle of a VM, using Stubs. That detail is not important now.
However, suffice it to say that, by loading these XML files into the right place, we effectively create hooks into the "Provisioned" and "Disposing" states, instructing vRA to execute our custom XAML workflows in addition to whatever else it normally does at these phases.
The Powershell took a good deal of trial and error. The first part of the script worked flawlessly on a Windows 2012 R2 DC. Then, when testing against another domain, on a Windows 2008 R2 DC, it failed dismally. It turns out that the Powershell Cmdlet to add a DNS entry only works on 2012 or greater. Yup. Now, it gets a little complex as to why:
Note the "Add-DnsServerResourceRecordA" command in the first block. If I executed that as follows: Add-DnsServerResourceRecordA -Name "vm001" -ZoneName "rainpole.com" -IPv4Address "192.168.1.48" -ComputerName $DC2008R2
Where $DC2008R2 was the name of a 2008 R2 DC, it would work.
Why? Because I would need to use a CimSession. Why not? Because it would be on the same domain, and we are assuming that the user content would be a domain admin (meaning that the DEM service account would be a domain admin). This is obviously never the case, or probably shouldn't be, at least.
I had to support multiple domains, ergo the need to be able to run this command using different credentials. Because of how Win RM works, we need to establish a CIMSession first, using these credentials, against the remote host. Then we use Powershell to execute the commands remotely.
I hope it makes sense (I don't think everyone wants to read pages and pages of technical details as to why I did what I did, so just accept it, ok? If you run into issues or need more detail, feel free to comment or ping me :-)
To summarise, we are effectively expecting an input letting us know whether the destination DNS server is below or above Server 2012, in which case we're running either DnsCmd.exe or the powershell cmdlet Add-DnsServerResourceRecordA.
Remember, these commands are executed remotely, using the CimSession.
This means you need WinRM enabled on the DNS servers, and you will need the Remote Server Administration Toolkit installed on them too. Furthermore, you will need to open a powershell prompt (on the DNS Server and on the DEM) and run "WinRM QuickConfig" which will set up the rudimentary WinRM services.
Next: Part 2, where I'll explain the following:
- Complete list of Prerequisites
- Ports (for firewall rules, if any)
- Installation Procedure