Packer, WinRM, AMIs - making it work

This has been a pretty frustrating task for me, so it felt like a good thing to write about.  Pretty much every source had one thing or another wrong, and I'd ended up just mashing it all into one big huge WinRM script glob.

I would preface this with 'it's a packer build, not concerned with security and encryption', which is not terribly security-conscious of me, but here we are.  One of the articles I found whilst googling had a basic SSL setup, but I opted to start with the Packer documentation after many many failures.

If you start with said documentation here (https://www.packer.io/intro/getting-started/build-image.html#a-windows-example) you will (possibly) discover that you are still blocked by 'waiting for winrm'.  So add this to your user-data WinRM setup portion:
set-item WSMan:\localhost\Client\AllowUnencrypted -Value True -Force
set-item WSMan:\localhost\Client\Auth\Basic -Value True -Force
set-item WSMan:\localhost\Client\TrustedHosts -Value * -Force
Enable-PSRemoting -force
(haven't extensively tested the above, but I strongly suspect it's the 3rd line that does it)

Yay, WinRM manages to connect!

But then you get to the end, and this happens:
Build 'amazon-ebs' errored: Error processing command: Error uploading ps script containing env vars: Couldn't determine whether destination was a folder or file: unknown error Post http://IP.AD.DR.ES:5985/wsman: read tcp MYAD.DR.ES:63667->IP.AD.DR.ES:5985: read: connection reset by peer
==> Some builds didn't complete successfully and had errors:
--> amazon-ebs: Error processing command: Error uploading ps script containing env vars: Couldn't determine whether destination was a folder or file: unknown error Post http://IP.AD.DR.ES:5985/wsman: read tcp MY.AD.DR.ES:63667->IP.AD.DR.ES:5985: read: connection reset by peer
Reading up on it, this is an error due to WinRM getting interrupted at the end of the build (because the build has, indeed, finished correctly).  This is extra irritating because installing all the garbage required by a build agent takes a good 40m.

Then, by a stroke of luck(?) our main build script (a powershell script provisioner) silently died, and let the rest of the process finish - and it finished successfully!  So it's definitely something in our build scripts breaking the process.  The following principles were applied:
  • If there is to be a system restart, let Packer handle it
  • Be heavy on the output so you can follow along
  • Don't rely on "it worked during debug"
So now that we have all this working, it'll become the method by which all our Windows servers can be provisioned, and enables putting everything behind ASGs.  Woop!

For some context, here is the process we are using (with additional output sent to Slack):
  1. User-data script sets up WinRM for Packer
    1. Have a gist: https://gist.github.com/christrotter/ff73e3793858fab7cf0d613fedf5e8a7
  2. Powershell script provisioner 
    1. Clones our AWS config repo which has a pile of powershell scripts
    2. Gets EC2 Tags - 'additionalBuildSteps' where we can define 'buildAgent'
    3. It executes the collection of scripts related to 'allServers' and 'additionalBuildSteps'
  3. Powershell 'windows-restart' provisioner
  4. Powershell script provisioner
    1. EC2 Launch sysprep scripts
For reference, this blog article was the best/most relevant/recent:  https://david-obrien.net/2016/12/packer-and-aws-windows-server-2016/

Comments

Popular posts from this blog

Fixing duplicate SPNs (service principal name)

DFSR - eventid 4312 - replication just won't work

Newbie datacenter lesson #3: Racks and 0U PDUs