Continuing into my own automation learning objectives this year, I am diving a bit deeper down the Terraform rabbit hole and want to share a few more things learned over the past few weeks with this automation tool. Terraform is a great tool to provision infrastructure, including virtual machines in VMware vSphere. When it comes to provisioning virtual machines, aside from using Terraform, most likely you are familiar with using a VM guest customization specification with your deployment. This accomplishes what it says, including customizing relevant portions of guest operating system configuration, including network customization, domain joins, as well as sysprepping a Windows guest virtual machine. Let’s take a look at Sysprep and VMware Guest Customization with Terraform and see a few things you need to know to successfully provision VMware virtual machines with Terraform.
What is Sysprep and Does Terraform Sysprep?
When considering mass deployment of Windows operating systems either physical or virtual, Sysprep is an important mechanism. Generally, you start off with a “Gold” image of some sort that is installed and configured with the applications you want and other customized setup. Then, you use that “Gold” image to deploy from, either in the physical world, or with a virtual machine template or clone to create other new virtual machines.
Sysprep comes into play with unique Windows identifiers called SIDs that are important, especially in a security context. These are and should be unique with each Windows machine on the domain. Especially in earlier versions of Windows, there could be major problems if you had Windows machines with duplicate SIDs on the network. Mark Russinovich published a very interesting read back in 2009 however, talking about some myths that come into play with old ideas regarding SIDs. He help to clarify why Sysprep is important – “Windows never exposes a machine SID outside its computer, proving that it’s okay to have systems with the same machine SID. Note that Sysprep resets other machine-specific state that, if duplicated, can cause problems for certain applications like Windows Server Update Services (WSUS), so MIcrosoft’s support policy will still require cloned systems to be made unique with Sysprep.”
So the bottom line here is that Sysprep is still a very valuable and necessary part of rolling out systems in mass. As we know you can manually sysprep a machine or have the guest customization specification take care of this as well when it is applied.
In the realm of Terraform, does it Sysprep? Yes. When I first used Terraform to deploy a test virtual machine, I was a bit confused in that it wasn’t glaringly obvious if it was performing Sysprep or not. I assumed that it was not and that I had to do this. However, Terraform has directives that help control this functionality.
In my build.tf file I have the following section, which performs customization on the deployed virtual machine.
computer_name = "win10test1"
join_domain = "cloud.local"
domain_admin_user = "[email protected]"
domain_admin_password = "password"
ipv4_address = "10.1.149.29"
ipv4_netmask = 24
ipv4_gateway = "10.1.149.1"
dns_server_list = ["10.1.149.10", "18.104.22.168"]
If you have a template that you have already Sysprepped you will run into an error with the deploy process as I found out in my first few tests.
After creating a new template without sysprepping, the deployment went through fine. As you can see, the sysprep process is ran by Terraform during the deployment process.
If you want to control the sysprep process yourself, you can add the following directive in your build.tf file:
skip_customization = true
Generally, if you see the network connected after the machine is deployed with with Guest Customization or with Terraform, the customization is working properly. Usually, all times that I saw Terraform fail, I would see the virtual NIC disconnected. This is generally expected however as one of the last steps that is performed is the network card is connected. This is to ensure that all the customization, including Sysprep is finished before placing the machine on the network.
The below listing is taken from the documentation found here: https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html
These options allow performing the same customization as you can do with the guest customization specification in VMware.
computer_name – (Required) The computer name of this virtual machine.
admin_password – (Optional) The administrator password for this virtual machine.
NOTE: admin_password is a sensitive field in Terraform and will not be output on-screen, but is stored in state and sent to the VM in plain text – keep this in mind when provisioning your infrastructure.
workgroup – (Optional) The workgroup name for this virtual machine. One of this or join_domain must be included.
join_domain – (Optional) The domain to join for this virtual machine. One of this or workgroup must be included.
domain_admin_user – (Optional) The user of the domain administrator used to join this virtual machine to the domain. Required if you are setting join_domain.
domain_admin_password – (Optional) The password of the domain administrator used to join this virtual machine to the domain. Required if you are setting join_domain.
NOTE: domain_admin_password is a sensitive field in Terraform and will not be output on-screen, but is stored in state and sent to the VM in plain text – keep this in mind when provisioning your infrastructure.
full_name – (Optional) The full name of the user of this virtual machine. This populates the “user” field in the general Windows system information. Default: Administrator.
organization_name – (Optional) The organization name this virtual machine is being installed for. This populates the “organization” field in the general Windows system information. Default: Managed by Terraform.
product_key – (Optional) The product key for this virtual machine. The default is no key.
run_once_command_list – (Optional) A list of commands to run at first user logon, after guest customization.
auto_logon – (Optional) Specifies whether or not the VM automatically logs on as Administrator. Default: false.
auto_logon_count – (Optional) Specifies how many times the VM should auto-logon the Administrator account when auto_logon is true. This should be set accordingly to ensure that all of your commands that run in run_once_command_list can log in to run. Default: 1.
time_zone – (Optional) The new time zone for the virtual machine. This is a numeric, sysprep-dictated, timezone code. For a list of codes, click here. The default is 85 (GMT/UTC).
Windows 10 Windows Store Apps Causing Sysprep to Fail
One other note to pass along, there are countless forum and threads out there with the Windows Store Apps or Modern UI Apps as they are sometimes referred to, causing Sysprep to fail. This happens when the store apps install under each user account. A quick PowerShell snippet will take care of the offending applications and must be ran under each user account:
Get-AppxPackage | Remove-AppxPackage
When it comes to Sysprep and VMware Guest Customization with Terraform, knowing what operations are performed where and with what directives can save a lot of confusion. If you don’t tell Terraform not to, it will Sysprep as it deploys Windows virtual machines. Sysprep is an important function that needs to be performed to ensure that the unique identifiers are changed for a Windows machine. This can affect a lot of different things including WSUS deployment, etc. Terraform is a powerful tool that can certainly be used effectively to manage infrastructure as code and allows DevOPs engineers to be more agile and efficient in carrying out needed daily operations.