Based on https://gist.github.com/ilude/a083934402ee761c402b7ab3ae9bcda7 and https://docs.aws.amazon.com/vm-import/latest/userguide/vmie_prereqs.html
ISO_DIR=~/Downloads/packer
IMAGE_DIR=/var/lib/libvirt/images
WINDOWS_ISO=$ISO_DIR/19043.928.210409-1212.21h1_release_svc_refresh_CLIENTENTERPRISEEVAL_OEMRET_x64FRE_en-us.iso
VIRTIO_ISO=$ISO_DIR/virtio-win.iso
IMAGE_PREFIX=$IMAGE_DIR/win10
sudo qemu-img create -f qcow2 $IMAGE_DIR/win10.qcow2 20G
sudo virt-install --name Win10 --description 'Windows 10' --ram 4096 --vcpus 2 --disk path=${IMAGE_PREFIX}.qcow2,size=20,bus=virtio --disk path=$VIRTIO_ISO,device=cdrom,perms=ro --os-type windows --os-variant win2k8 --network network=default,model=virtio --graphics vnc,listen=127.0.0.1,port=5901 --cdrom $WINDOWS_ISO
- During installation install drivers from CDROM
D:\amd\w10
to get the storage to appear - Create user:
setup
, passwordsetup
, answersetup
to 3 security questions
Post install
Install all drivers from cdrom E:\virtio-win-gt-x64.exe
Start a powershell prompt as Administrator, then clone and run some setup scripts
Invoke-WebRequest -Uri https://github.com/StefanScherer/packer-windows/archive/refs/tags/2021.08.23.zip -OutFile packer-windows-2021.08.23.zip
Expand-Archive -Path packer-windows-2021.08.23.zip -DestinationPath packer-windows
cd ./packer-windows/packer-windows-2021.08.23/scripts/
Allow execution of scripts
Set-ExecutionPolicy RemoteSigned
Edit win-updates.ps1
, replace a:\enable-winrm.ps1
with .\enable-winrm.ps1
Edit microsoft-updates.bat
, replace A:\temp.vbs
with .\temp.vbs
Run the following scripts
.\fixnetwork.ps1
.\microsoft-updates.bat
.\disable-screensaver.ps1
.\win-updates.ps1
.\enable-rdp.bat
.\set-powerplan.ps1
.\compile-dotnet-assemblies.bat
.\set-winrm-automatic.bat
.\scripts/uac-enable.bat
.\dis-updates.bat
Install AWS CLI
Invoke-WebRequest -Uri https://awscli.amazonaws.com/AWSCLIV2.msi -OutFile AWSCLIV2.msi
msiexec.exe /i AWSCLIV2.msi /qn
doesn't work so run the installer manually instead
Install AWS Elastic Network Adapter (ENA)
Invoke-WebRequest -Uri https://s3.amazonaws.com/ec2-windows-drivers-downloads/ENA/Latest/AwsEnaNetworkDriver.zip -OutFile AwsEnaNetworkDriver.zip
Expand-Archive -Path AwsEnaNetworkDriver.zip -DestinationPath AwsEnaNetworkDriver
cd AwsEnaNetworkDriver
.\install.ps1
Install AWS SSM agent
Invoke-WebRequest -Uri https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/windows_amd64/AmazonSSMAgentSetup.exe -OutFile AmazonSSMAgentSetup.exe
SSMAgent_latest.exe /S
Eject D:\
and E:\
drives in Windows Explorer.
Configure universal time
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f
Run Sysprep
c:\windows\system32\sysprep\sysprep.exe /generalize /oobe /quit
Set an Administrator password
net user administrator /active:yes
net user administrator <password>
Convert to raw disk format (qemu-img
can create VMDKs but it AWS EC2 rejects it)
sudo qemu-img convert ${IMAGE_PREFIX}.qcow2 ${IMAGE_PREFIX}.raw
Upload the raw disk file to an S3 bucket. Make the object public (a pre-signed URL is meant to work but it didn't for me). Note the bucket must not have a top-level block on public access:
aws cp win10.raw s3://example-bucket/prefix/win10.raw
aws s3api put-object-acl --bucket example-bucket --key prefix/win10.raw --acl public-read
Create a JSON file containing the S3 bucket, prefix, and disk description:
containers.json
[
{
"Description": "Windows 10 test",
"Format": "raw",
"UserBucket": {
"S3Bucket": "example-bucket",
"S3Key": "prefix/win10.raw"
}
}
]
Import the disk to an AMI:
aws ec2 import-image --description "Windows 10 test" --disk-containers file://containers.json
This should output an ImportTaskId
. Use this to monitor the progress of the import:
aws ec2 describe-import-image-tasks --import-task-ids <ImportTaskId>
When it shows completed there should be an ImageId
which is the AMI ID.