PackerBaseAMI is a PowerShell module which automates the process of creating a Windows Base AMI for use with AWS EC2.
PackerBaseAMI is a PowerShell module which automates the process of creating a Windows Base AMI for use with AWS EC2.
There are a few problems associated with utilizing the Amazon provided Base Windows AMI images:
-
The Amazon provided Base Windows AMI images are frequently deprecated and deregistered.
- This causes problems if you are using those AMIs in CloudFormation stacks, as you may not be able to update the stack after the AMI is deregistered. This problem is resolved by creating an new AMI based on the Amazon provided image.
- The AMI produced by this module will remain in your account until you choose to remove it.
-
The Amazon provided Base Windows AMI images cannot be directly copied via the AWS API (cli / Powershell)
- The Amazon recommended process is a manual one utilizing the web console via a browser, which is highly inefficient and not well suited to automation
-
The Amazon provided Base Windows AMI images are not encrypted. They can't be encrypted as they are based on snapshots owned by Amazon, which means that Amazon would have to share their private encryption keys in order for customer to use their encrypted images, which would render the encryption useless.
- The AMI produced by this module will encrypt the snapshot for the new AMI by default, using the master key associated with your AWS account.
Upon importing the module, a single PowerShell cmdlet named New-PackerBaseAMI is exported which makes use of AWSPowerShell
I suggest using the latest version of PowerShell if possible so that you can use PowerShellGet cmdlets. Download the latest PowerShell here: https://aka.ms/wmf5latest
You have two options:
- Install Packer from the main site: https://packer.io
- Or use Chocolatey to install Packer:
-
Install Chocolatey: https://chocolatey.org/install
-
Install Packer package via Chocolatey:
choco install packer
-
Install PackerBaseAMI & Requirements
(Assumes you have PowerShellGet and access to PowerShellGallery.com)
-
AWSPowerShell PowerShell Module
# If you want the old monolithic module: # Install-Module AWSPowerShell # Otherwise, if you want the new modularized modules with only the necessary cmdlets (recommended): Install-Module AWS.Tools.Common,AWS.Tools.EC2,AWS.Tools.SecurityToken,AWS.Tools.SimpleSystemsManagement
-
PackerBaseAMI PowerShell Module
Install-Module PackerBaseAMI
Import-Module PackerBaseAMIWindows Server 2025 removed the wmic.exe utility, which EC2Launch v2 depends on during instance initialization. This causes EC2Launch v2 to fail at its preReady stage, which prevents UserData from executing and stops the instance from shutting down after sysprep. Recent Server 2022 base AMIs running the same EC2Launch v2 build hit the same class of preReady failure, so 2022 uses the same workaround.
To work around this, the module uses a different build strategy for Windows Server 2022 and 2025:
- SSM Run Command is used instead of UserData to execute commands on the instance
- After Packer launches the instance, the module waits for the SSM Agent to come online, then removes the
installEgpuManagertask from the EC2Launch v2 configuration — this is the specific task that depends onwmic.exe - EC2Launch v2 then runs sysprep and shuts down the instance
- The Packer template uses
communicator = "none"withdisable_stop_instance = "true", so Packer waits for the instance to shut down on its own after sysprep completes - The instance is tagged with a unique
PackerBuildIdso the module can find it after launch
SSM Agent runs as an independent Windows service that starts on boot regardless of EC2Launch v2 status. The config change persists in the AMI, so instances launched from it will not hit the same issue. The installEgpuManager task is only relevant for Elastic Graphics (eGPU) instances and is safe to remove for standard workloads.
Note: the SSM Run Command will stay in "In Progress" until it times out — this is expected. The last step of the SSM payload triggers
ec2launch.exe sysprep --shutdown=true, which shuts down the OS (and the SSM Agent with it) before the agent can report completion to the Run Command API. SSM leaves the command inInProgressuntil its delivery timeout fires (default 1 hour) and then transitions it toDeliveryTimedOut. The actual success signal is the build instance reaching thestoppedstate and Packer creating the AMI from its root volume — not the Run Command status. This is a well-known consequence of running Send-SSMCommand payloads that reboot or shut down the target.
To make the SSM-based build self-contained, the module also:
- Attaches a temporary IAM instance profile to the build instance (created and deleted by Packer for the duration of the build) granting
ssm:*,ssmmessages:*, andec2messages:*. This removes the dependency on Default Host Management Configuration (DHMC) being enabled in the account. - Prefers a public subnet when selecting where to launch the build instance, falling back to any subnet whose AZ supports the chosen instance type. This is so the SSM Agent has a network path to reach the SSM endpoints.
- Sets
associate_public_ip_address = "true"so the build instance gets a public IP even if the subnet's default doesn't auto-assign one.
The build instance must be able to reach the SSM API endpoints (ssm, ssmmessages, ec2messages on port 443). The default behavior above (public subnet + public IP) satisfies this. If your VPC has only private subnets, you must provide one of:
- A NAT gateway with a route from the chosen subnet to it, or
- VPC endpoints for
com.amazonaws.<region>.ssm,com.amazonaws.<region>.ssmmessages, andcom.amazonaws.<region>.ec2messagesreachable from the chosen subnet.
Older Windows Server versions (2019, 2016, 2012) build via UserData and do not require SSM reachability.
The IAM role used for the build must have the following permissions in addition to the existing EC2 and STS permissions:
SSM:
ssm:SendCommandssm:DescribeInstanceInformation
IAM (for the temporary instance profile Packer creates and deletes around the build):
iam:CreateRole,iam:DeleteRoleiam:CreateInstanceProfile,iam:DeleteInstanceProfile,iam:GetInstanceProfileiam:PutRolePolicy,iam:DeleteRolePolicyiam:AddRoleToInstanceProfile,iam:RemoveRoleFromInstanceProfileiam:PassRole
Older Windows Server versions (2019, 2016, 2012) are unaffected and do not require these additional permissions.
No special setup is required for GitHub Actions. The module handles the SSM Run Command internally using the same AWS credentials configured for the workflow:
jobs:
build-ami:
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/YourRole
aws-region: us-east-1
- name: Install Packer
uses: hashicorp/setup-packer@main
- name: Build AMI
shell: pwsh
run: |
Install-Module AWS.Tools.Common,AWS.Tools.EC2,AWS.Tools.SecurityToken,AWS.Tools.SimpleSystemsManagement -Force
Install-Module PackerBaseAMI -Force
Import-Module PackerBaseAMI
New-PackerBaseAMI -AccountNumber '111111111111' -BaseOS 'Windows_Server-2025-English-Full-Base' -IamRole 'YourRole' -Region 'us-east-1'New-PackerBaseAMI -AccountNumber '111111111111' -Alias ExampleAlias -BaseOS 'Windows_Server-2025-English-Full-Base' -IamRole 'ExampleRoleName' -Region 'us-east-1' -InstanceType 't3.medium' -OutputDirectoryPath 'c:\example\directory'Robert D. Biddle - https://github.com/RobBiddle
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Create Issues / Submit a pull request
- Upic Solutions for sponsoring my time to develop this project. This code is being used as part of our mission to help United Ways be the best community solution leaders, in an increasingly competitive environment, by providing state of the art business and technology solutions
- Hashicorp for creating Packer and other fantastic open source projects
- The AWSPowerShell Devs for supporting all of us PowerShell users
GNU General Public License v3.0 https://github.com/RobBiddle/PackerBaseAMI/LICENSE.txt
- Please ⭐Star this repo if you found some of this code useful!
- If you're an unbelievably nice person and want to show your appreciation, I like beer ;-)
- Send me 🍺 money via LTC: MHJj5jaWFU2VeqEZXnLC4xaZdQ1Nu9NC48
- Send me 🍺 money via BTC: 38ieXk9rn2LJEsfimFWiyycUZZv5ABJPqM
- Send me 🍺 money via USD: https://paypal.me/RobertBiddle