॥ श्री ॥

Cloud Images Beyond AWS

Enterprise 2026-08-28

What exists today for non-AWS targets, what you can build yourself, and how far official support extends.

Current Reality

There are two distribution paths:

  1. Official automated pipeline: AWS AMI. shani-install-media/packer/ contains a working Packer template (amazon-ebssurrogate builder) that turns a .zst base image into a bootable AMI — profiles, variables, and the GitHub Actions OIDC workflow are documented in OEM & Fleet Deployment. This is the only cloud target with an end-to-end maintained path.
  1. Raw artifacts for every profile and release. The image build publishes each profile's artifacts publicly to Cloudflare R2 and SourceForge mirrors:
ArtifactContents
shanios-<profile>-<version>.zstCompressed Btrfs send-stream of the full OS image
shanios-<profile>-<version>.zst.sha256Checksum
shanios-<profile>-<version>.zst.ascDetached GPG signature

The .zst send-stream is the same artifact the AWS Packer build consumes — anything it can do with it, you can replicate on another platform.

Verify Artifacts Before Use

sha256sum -c shanios-server-2026.08.zst.sha256

# One-time: import and trust the signing key
gpg --keyserver keys.openpgp.org --recv-keys 7B927BFFD4A9EAAA8B666B77DE217F3DA8014792
gpg --fingerprint 7B927BFFD4A9EAAA8B666B77DE217F3DA8014792   # confirm before trusting

gpg --verify shanios-server-2026.08.zst.asc shanios-server-2026.08.zst

A failed checksum or signature means do not use the artifact — fetch again from another mirror (R2 primary, SourceForge fallback) and re-verify.


Generic KVM / qcow2 (Advanced, Unofficial)

This is not a supported or documented product surface. The steps below describe the concept using standard tools; they assume familiarity with Btrfs, UEFI booting, and cloud-init. Read upstream's build.sh test bootstrap first — that local test loop performs exactly this class of operation (loop-mount, receive stream, chroot configure) and is the best available prior art.

Conceptual flow:

# 1. Create a blank disk sized for the profile (server needs ~28 GB minimum)
truncate -s 30G shanios-server.raw

# 2. Format Btrfs and receive the verified send-stream into it,
#    following the subvolume layout the images expect (@blue/@green/@data)
mkfs.btrfs shanios-server.raw
mount -o loop shanios-server.raw /mnt
zstd -dc shanios-server-2026.08.zst | btrfs receive /mnt

# 3. Bootloader setup follows the image conventions: UKIs generated by
#    gen-efi and systemd-boot entries on an ESP, exactly as physical
#    installs produce them. Replicating this outside the Packer pipeline
#    means reproducing what the pipeline's configuration stage does.
#    Consult the upstream build scripts and the Arch Wiki pages on
#    systemd-boot and unified kernel images — this is the step that
#    requires real experience to get right.

# 4. Swap the cloud-init datasource: the shipped config targets AWS
#    (IMDSv2 strict, EC2 metadata). Replace it inside the received rootfs.
rm /mnt/etc/cloud/cloud.cfg.d/10-shanios-aws.cfg
cat > /mnt/etc/cloud/cloud.cfg.d/10-myorg-generic.cfg <<'EOF'
datasource_list: [ NoCloud ]
EOF

umount /mnt

Then convert and attach as a VM disk:

qemu-img convert -f raw -O qcow2 shanios-server.raw shanios-server.qcow2
virt-install --name shanios-01 --memory 4096 --vcpus 2 \
  --disk path=shanios-server.qcow2 \
  --boot uefi --os-variant archlinux --import --no-console

UEFI firmware (OVMF) is required — Secure Boot with MOK-enrolled UKIs is part of the boot chain. If your hypervisor cannot enforce Secure Boot, the machine still boots via the MOK-signed UKI path but report boot state accordingly in your own compliance evidence (see Compliance & Benchmarks).


Azure / GCP

No official templates exist. The practical approach: copy packer/shanios-ami.pkr.hcl, swap the amazon-ebssurrogate builder block for azure-arm or googlecompute, and keep the three provisioner scripts (00-bootstrap-shanios.sh, 01-configure-aws.sh → rename/adjust its cloud-init bits, 02-verify.sh) operating on the attached volume unchanged where possible.

Variable differences from the AWS template:

VariableAWS templateAzure/GCP adaptation
r2_base_url / s3_base_urlBase .zst source for the buildUnchanged — still pulled from R2/SourceForge
gpg_public_keyOptional org signing key baked at build timeUnchanged
shanios_profilegnome/plasma/cosmic (server default)Unchanged
CredentialsAWS OIDC role, no long-lived keysAzure: OIDC/service principal; GCP: service account impersonation
Addedazure_subscription_id + resource group / gcp_project_id + zone

Budget time for the platform-specific parts of 01-configure-aws.sh (fstab device naming differs; serial console targets differ).


Proxmox / OpenStack

Both consume the output of either path above directly:

PlatformImportcloud-init datasource
Proxmox VEqm importdisk with the qcow2/raw; attach as SCSI diskNoCloud (Proxmox cloud-init drive)
OpenStackUpload to Glance, boot from imageOpenStack datasource (metadata service)
Plain libvirt/KVMAttach qcow2NoCloud seed ISO

The server profile is built for exactly this usage: headless, systemd-networkd + cloud-init networking, serial console on ttyS0, sshd/firewalld/fail2ban/auditd enabled by default. After swapping the AWS datasource config (step 4 above) for the platform's datasource, first boot picks up hostname, SSH keys, and network from the metadata provider as usual.


Support Posture

  • Officially supported: AWS only. The AMI pipeline is tested end-to-end, including the CI build workflow.
  • Everything else: community/DIY. The raw artifacts are public and verifiable precisely so this remains possible, but nobody has validated Azure, GCP, Proxmox, or bare-KVM builds against release QA.
  • Issues and improvements for other platforms are welcome upstream at the shani-install-media repository. For organisation-scale needs, contact the project.

See Also