Closed lcc2207 closed 9 years ago
There's an AWS example template in this repo: dylanmei/packer-windows-templates. EC2 User Data is used to run some basic setup on a new instance. Does that answer your question?
Unless I am looking at the wrong sample, not really those setups are for setting up WinRM to get into the instance. What I am seeing is more there is no process to run ec2config or sysprep before making the instances an AMI. This results in all the Windows instances deployed from this AMI having the same SID etc.
In the past I've tested running sysprep commands for doing vmware/vbox images - which works, but IIRC my issue was that the sysprep process shuts down the box, but the Packer builder is expecting that this is its responsibility, so it would hang there and ultimately time out or I'd abort it.
In this case of Virtualbox/Parallels/VMWare you have the shutdown_command
configuration item - I've used that in the past to execute sysprep with the shutdown option. This works nicely.
In the case of AWS this option is not available, however you can still control how the AMI export process behaves via the EC2Config service. It's fairly easy to do as it's just XML configuration, and it is in here that you can do this sort of thing.
Here is a Gist that:
Ideally, you avoid sysprepping and domain-joining where possible - it's slow, and a bit messy with the whole cloud & auto-scaling thing, although I understand Amazon are making this easier. We have worked around this problem in other ways - IAM roles, security groups/Network ACLS, security tokens for API calls and so on. Hope this helps.
For now, I'm going to close this issue as I believe this documentation is sufficient to move forward.
Thanks for the suggestion about using shutdown_command
to do the sysprep - seems obvious in retrospect!
Would it be possible to get the shutdown_command added to the AWS module?
There is a PR that includes this feature. You could give that a shot whilst we work on integrating it (it's fairly big). So i suppose the answer is yes but if you're in a hurry I'd suggest running you're own script for now as per above. Hope that helps?
I would just caution having the "shutdown_command" making sure it can be overridden if you DON'T want it to sysprep. There are valid reasons in AWS where you might not, granted most people WILL want it, but it is faster (and less reboots) if you don't (and just use a statically created user account(s)).
@mefellows I followed your steps but the image is still not syspreped...
Hi @rdmips, we're going to need more information if you would like some assistance.
Examples aside, please familiarise yourself with both http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html#UsingConfigXML_WinAMI and http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ami-create-standard.html which explain the concepts and practices.
Packer (and this now mostly obsolete project) support this feature by providing a way to upload a file in tho correct location.
Sure.
Packer provisioner type :
{
"type" : "powershell",
"elevated_user" : "{{user winrm_username
}}",
"elevated_password" : "{{user winrm_password
}}",
"scripts" : [ "./scripts/Ec2Config.ps1",
"./scripts/BundleConfig.ps1"]
}
BundleConfig.ps1 : $EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\BundleConfig.xml" $xml = [xml](get-content $EC2SettingsFile) $xmlElement = $xml.get_DocumentElement()
foreach ($element in $xmlElement.Property){ if ($element.Name -eq "AutoSysprep"){ $element.Value="Yes" } } $xml.Save($EC2SettingsFile)
EC2Config.ps1 $EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\Config.xml" $xml = [xml](get-content $EC2SettingsFile) $xmlElement = $xml.get_DocumentElement() $xmlElementToModify = $xmlElement.Plugins
foreach ($element in $xmlElementToModify.Plugin){ if ($element.name -eq "Ec2SetPassword"){ $element.State="Enabled" } elseif ($element.name -eq "Ec2SetComputerName"){ $element.State="Enabled" } elseif ($element.name -eq "Ec2HandleUserData"){ $element.State="Enabled" } } $xml.Save($EC2SettingsFile)
Thanks @rdmips. First of all, how are you determining that the Sysprep has not been performed? (i.e. before after expectations).
WRT diagnosing, are you able to perform a Packer run with the -debug
flag and take a snapshot of the modified BundleConfig.xml
after the powershel
l provisioner has been run? Or even create another provisioner which cat
s it to stdout and therefore in the logs? It would be good to first see if it modifies the correct files for the EC2ConfigService.
@mefellows Yes I was able to run packer with debug and the BundleConfig.xml is being updated correctly. I also tried to build an image using the following git repository : https://gist.github.com/mefellows/a7a5ef98a3ec21a2c972
If you try to create a image from the git repository above and provision two or more servers, the Windows Machine SID will be the same. The command below provides the USER SIDs or https://technet.microsoft.com/en-us/sysinternals/bb897417.aspx PsGetSid MACHINE SID.
gwmi win32userprofile | select -unique @{name="Name";expression={$._server}},@{name="SID";expression={$.sid}},@{name="LastUseTime";expression={$.converttodatetime($.lastusetime)}},localpath | ft -auto
Packer Debug : ==> amazon-windows-ebs: Provisioning with shell script: ./scripts/Ec2Config.ps1 amazon-windows-ebs: ==> amazon-windows-ebs: Provisioning with shell script: ./scripts/BundleConfig.ps1 ==> amazon-windows-ebs: Pausing after run of step 'StepProvision'. Press enter to continue. ==> amazon-windows-ebs: Stopping the source instance... ==> amazon-windows-ebs: Waiting for the instance to stop...
Server provisioned using AMI built with Packer. AWS System Log : 2016/03/24 22:38:05Z: Windows sysprep configuration complete. 2016/03/24 22:38:06Z: Driver: AWS PV Storage Host Adapter v7.3.2.0 2016/03/24 22:38:06Z: Driver: Intel(R) 82599 Virtual Function v1.0.15.3 2016/03/24 22:38:06Z: AMI Origin Version: 2016.03.09 2016/03/24 22:38:06Z: AMI Origin Name: Windows_Server-2012-R2_RTM-English-64Bit-Base 2016/03/24 22:38:06Z: OS: Microsoft Windows NT 6.3.9600 2016/03/24 22:38:06Z: OsVersion: 6.3 2016/03/24 22:38:06Z: OsProductName: Windows Server 2012 R2 Standard 2016/03/24 22:38:06Z: OsBuildLabEx: 9600.18202.amd64fre.winblue_ltsb.160119-0600 2016/03/24 22:38:06Z: Language: en-US 2016/03/24 22:38:06Z: TimeZone: Coordinated Universal Time 2016/03/24 22:38:06Z: Offset: UTC 00:00:00 2016/03/24 22:38:06Z: EC2 Agent: Ec2Config service v3.14.786 2016/03/24 22:38:06Z: Message: Waiting for meta-data accessibility... 2016/03/24 22:38:06Z: Message: Meta-data is now available. 2016/03/24 22:38:07Z: AMI-ID: ami-13f4fb79 2016/03/24 22:38:07Z: Instance-ID: i-b9c64122 2016/03/24 22:38:07Z: Ec2SetPassword: Disabled 2016/03/24 22:38:07Z: RDPCERTIFICATE-SUBJECTNAME: IP-0AA8A20A 2016/03/24 22:38:07Z: RDPCERTIFICATE-THUMBPRINT: 6590461127F8580BAD50EFD42FE33B9E4635B21C 2016/03/24 22:38:14Z: Message: Windows is Ready to use
Thank you so much for your help.
@mefellows
==> amazon-windows-ebs: Provisioning with shell script: ./scripts/Ec2Config.ps1 ==> amazon-windows-ebs: Provisioning with shell script: ./scripts/BundleConfig.ps1
I had to logon to the instance and run EC2Config --sysprep before the step below : _==> amazon-windows-ebs: Pausing after run of step 'StepProvision'. Press enter to continue._ ==> amazon-windows-ebs: Stopping the source instance... ==> amazon-windows-ebs: Waiting for the instance to stop... ==> amazon-windows-ebs: Pausing after run of step 'stepStopInstance'. Press enter to continue. ==> amazon-windows-ebs: Pausing after run of step 'stepModifyInstance'. Press enter to continue.
Interesting. So when you manually ran EC2Config --sysprep
the SIDs were updated as expected? I suppose that wouldn't be difficult to automate, but my understanding was that wasn't required.
Upon review of it http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ami-create-standard.html#sysprep-using, it seems %ProgramFiles%\Amazon\Ec2ConfigService\ec2config.exe -sysprep
might be required to run on shutdown. I'll likely be able to look into this properly early next week, but if you wanted to give that a try and report back that would be super!
Correct. For some reasons the AutoSysprep doesn't work.
On the bundleconfig.xml you change the switch /shutdown to /quit
cd "C:\Program Files\Amazon\Ec2ConfigService\" .\Ec2Config.exe -sysprep
Packer will stop the instance and take an image.
Thanks for the ideas/solutions @ghost. I had to solve the 'apply sysprep to an AMI through packer' problem today too.
I used @ghost's example code and have some additions:
$xml = [xml](get-content $EC2SettingsFile)
. With your $xml = xml
I receive exceptions from powershellOn the bundleconfig.xml you change the switch /shutdown to /quit /oobe /quit /generalize
$EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\BundleConfig.xml"
$xml = [xml](get-content $EC2SettingsFile)
$xml_switches = $xml.SelectSingleNode("//Switches[1]")
foreach ($switch in $xml_switches) {
$switch.'#text' = "/quit /oobe /generalize"
}
$xml.Save($EC2SettingsFile)
So if you want to switch the sysprep parameters and want sysprep to generate a random password, you can use this:
$EC2SettingsFile="C:\Program Files\Amazon\Ec2ConfigService\Settings\BundleConfig.xml"
$xml = [xml](get-content $EC2SettingsFile)
$xml_switches = $xml.SelectSingleNode("//Switches[1]")
foreach ($switch in $xml_switches) {
$switch.'#text' = "/quit /oobe /generalize"
}
$xml.Save($EC2SettingsFile)
$xml = [xml](get-content $EC2SettingsFile)
$xmlElement = $xml.get_DocumentElement()
$xmlElementToModify = $xmlElement.Property
foreach ($element in $xmlElementToModify.Property){
if ($element.Name -eq "SetPasswordAfterSysprep"){
$element.Value="Enabled"
}
}
$p = Start-Process "C:\Program Files\Amazon\Ec2ConfigService\Ec2Config.exe" -ArgumentList "-sysprep" -Wait
@fzk-rec Most concise set of instructions I have seen. Well done.
I appears that the AMIs have not been syspreped, or am I missing how to sysprep them as part of the build?