Skip to content

Building

Build pelotech-nat AMIs from source using Packer and FPM.

Prerequisites

  • Packer >= 1.8
  • FPM (for RPM packaging)
  • AWS credentials with EC2 AMI creation permissions
  • GNU Make

Build Steps

1. Package the RPM

make package-rpm

This creates build/pelotech-nat-<version>-any.rpm containing the service script and systemd unit.

2. Build AMIs

Build a single architecture:

# ARM64
make al2023-ami-arm64

# x86_64
make al2023-ami-x86

Build both architectures:

make al2023-ami

3. Publish to All Regions

Build and copy AMIs to all 34 commercial regions:

make publish

This uses packer/pelotech-nat-public-all-regions.pkrvars.hcl to configure multi-region publishing.

What the Build Does

  1. Starts from the latest AL2023 minimal AMI (kernel 6.1, FIPS 140-3 validated)
  2. Runs dnf upgrade --refresh and reboots
  3. Installs: amazon-cloudwatch-agent, amazon-ssm-agent, nftables, conntrack-tools
  4. Installs the pelotech-nat RPM
  5. Installs kpatch-dnf, kpatch-runtime and enables kernel live patching
  6. Enables FIPS 140-3 mode (fips-mode-setup --enable) and reboots
  7. Applies CIS Level 2 hardening (auditd, PAM faillock, SSH hardening, sysctl, filesystem restrictions)
  8. Runs security scans (Trivy + OpenSCAP CIS L2 server profile)
  9. Downloads security reports (oscap-results.xml, oscap-report.html, trivy-report.json)
  10. Runs cleanup (clears caches, logs, SSH host keys, machine-id)
  11. Produces a 6 GB EBS-backed HVM AMI with ENA and IMDSv2 required

Note: The build uses RSA temporary key pairs (instead of ed25519) for FIPS compatibility.

Packer Variables

Variable Description Default
version AMI version string 0.0.1
architecture arm64 or x86_64 arm64
ami_regions List of regions to copy the AMI to []
ami_users List of AWS account IDs to share the AMI with []
ami_groups AMI launch permission groups (e.g., all for public) []
snapshot_groups Snapshot sharing groups []
prefix AMI name prefix pelotech-nat
flavor OS flavor label al2023
region Build region us-east-1
instance_type Build instance type (map by architecture) {arm64: t4g.micro, x86_64: t3a.micro}
base_image_name Source AMI name filter (kernel 6.1 for all builds; will move to 6.12 when FIPS certified) (auto-detected)
base_image_owner Source AMI owner amazon

Custom Builds

Override variables on the command line:

packer build \
  -only=pelotech-nat.amazon-ebs.pelotech-nat \
  -var 'version=1.0.0' \
  -var 'architecture=arm64' \
  -var 'ami_regions=["us-east-1","us-west-2"]' \
  packer/pelotech-nat.pkr.hcl

Publishing with GitHub Environments (OIDC)

The release workflow uses GitHub Environments to authenticate with AWS via OIDC. Each environment represents a Seller of Record (SOR) AWS account (commercial or GovCloud). Packer builds and publishes AMIs directly within the SOR account — no cross-account copying is required. On release, the workflow iterates over all configured environments and runs a Packer build for each one.

Setup

  1. Create an IAM OIDC identity provider in your AWS account for token.actions.githubusercontent.com (see AWS docs).

  2. Create an IAM role with a trust policy scoped to your fork's repository and environment:

{
  "Effect": "Allow",
  "Principal": {
    "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
  },
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringEquals": {
      "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
      "token.actions.githubusercontent.com:sub": "repo:<OWNER>/<REPO>:environment:<ENV_NAME>"
    }
  }
}

The role needs EC2 AMI creation and copying permissions.

  1. Create a GitHub Environment in your repository (Settings > Environments) and add the following variables:
Variable Description Example
AWS_ROLE_ARN IAM role ARN to assume via OIDC arn:aws:iam::123456789012:role/packer-build
AWS_REGION Region to run the Packer build in us-east-1
MAKE_TARGET Make target to run publish
ADDITIONAL_PARAMS Extra Packer var-file flags (optional) -var-file="packer/pelotech-nat-govcloud-all-regions.pkrvars.hcl"
  1. Repeat for each AWS account (e.g., create a govcloud environment with the GovCloud role ARN, region, and var-file).

When a release is created, the workflow discovers all environments automatically and runs a parallel Packer build for each one.

GovCloud Builds

GovCloud builds automatically use the kernel 6.1 base AMI (FIPS 140-3 validated) when region is set to a GovCloud region. No manual base_image_name override is needed.

Use the GovCloud var file to publish to us-gov-east-1 and us-gov-west-1:

make al2023-ami additional_params='-var-file="packer/pelotech-nat-govcloud-all-regions.pkrvars.hcl"'