diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2cc2474f..3928aa66 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -238,6 +238,12 @@ jobs: - lint - test runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + architecture: + - arm64 + - x86_64 steps: - id: harden-runner name: Harden the runner @@ -315,7 +321,8 @@ jobs: # This runs through the AMI creation process but does not # actually create an AMI run: | - packer build -timestamp-ui \ + packer build -only amazon-ebs.${{ matrix.architecture }} \ + -timestamp-ui \ -var skip_create_ami=true \ src/packer.pkr.hcl - name: Remove /usr/bin/python3 symlink to the installed Python diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 1f8dcfaa..dcc3d6a0 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -33,6 +33,12 @@ jobs: needs: - diagnostics runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + architecture: + - arm64 + - x86_64 steps: - id: harden-runner name: Harden the runner @@ -108,7 +114,8 @@ jobs: run: packer init src - name: Create machine image run: | - packer build -timestamp-ui \ + packer build -only amazon-ebs.${{ matrix.architecture }} \ + -timestamp-ui \ -var is_prerelease=${{ github.event.release.prerelease }} \ -var release_tag=${{ github.event.release.tag_name }} \ -var release_url=${{ github.event.release.html_url }} \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b50f9b62..f0555082 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,12 @@ jobs: needs: - diagnostics runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + architecture: + - arm64 + - x86_64 steps: - id: harden-runner name: Harden the runner @@ -123,7 +129,8 @@ jobs: run: packer init src - name: Create machine image run: | - packer build -timestamp-ui \ + packer build -only amazon-ebs.${{ matrix.architecture }} \ + -timestamp-ui \ -var is_prerelease=${{ github.event.release.prerelease }} \ -var release_tag=${{ github.event.release.tag_name }} \ -var release_url=${{ github.event.release.html_url }} \ diff --git a/src/packer.pkr.hcl b/src/packer.pkr.hcl index 849c29d8..437adf07 100644 --- a/src/packer.pkr.hcl +++ b/src/packer.pkr.hcl @@ -63,8 +63,21 @@ variable "skip_create_ami" { type = bool } -data "amazon-ami" "debian_bookworm" { +data "amazon-ami" "debian_bookworm_arm64" { filters = { + architecture = "arm64" + name = "debian-12-arm64-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["136693071363"] + region = var.build_region +} + +data "amazon-ami" "debian_bookworm_x86_64" { + filters = { + architecture = "x86_64" name = "debian-12-amd64-*" root-device-type = "ebs" virtualization-type = "hvm" @@ -76,7 +89,51 @@ data "amazon-ami" "debian_bookworm" { locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") } -source "amazon-ebs" "example" { +source "amazon-ebs" "arm64" { + ami_name = "example-hvm-${local.timestamp}-arm64-ebs" + ami_regions = var.ami_regions + associate_public_ip_address = true + encrypt_boot = true + instance_type = "t4g.small" + kms_key_id = var.build_region_kms + launch_block_device_mappings { + delete_on_termination = true + device_name = "/dev/xvda" + encrypted = true + volume_size = 8 + volume_type = "gp3" + } + region = var.build_region + region_kms_key_ids = var.region_kms_keys + skip_create_ami = var.skip_create_ami + source_ami = data.amazon-ami.debian_bookworm_arm64.id + ssh_username = "admin" + subnet_filter { + filters = { + "tag:Name" = "AMI Build" + } + } + tags = { + Application = "Example" + Architecture = "arm64" + Base_AMI_Name = data.amazon-ami.debian_bookworm_arm64.name + GitHub_Release_URL = var.release_url + OS_Version = "Debian Bookworm" + Pre_Release = var.is_prerelease + Release = var.release_tag + Team = "VM Fusion - Development" + } + # Many Linux distributions are now disallowing the use of RSA keys, + # so it makes sense to use an ED25519 key instead. + temporary_key_pair_type = "ed25519" + vpc_filter { + filters = { + "tag:Name" = "AMI Build" + } + } +} + +source "amazon-ebs" "x86_64" { ami_name = "example-hvm-${local.timestamp}-x86_64-ebs" ami_regions = var.ami_regions associate_public_ip_address = true @@ -93,7 +150,7 @@ source "amazon-ebs" "example" { region = var.build_region region_kms_key_ids = var.region_kms_keys skip_create_ami = var.skip_create_ami - source_ami = data.amazon-ami.debian_bookworm.id + source_ami = data.amazon-ami.debian_bookworm_x86_64.id ssh_username = "admin" subnet_filter { filters = { @@ -102,7 +159,8 @@ source "amazon-ebs" "example" { } tags = { Application = "Example" - Base_AMI_Name = data.amazon-ami.debian_bookworm.name + Architecture = "x86_64" + Base_AMI_Name = data.amazon-ami.debian_bookworm_x86_64.name GitHub_Release_URL = var.release_url OS_Version = "Debian Bookworm" Pre_Release = var.is_prerelease @@ -120,7 +178,10 @@ source "amazon-ebs" "example" { } build { - sources = ["source.amazon-ebs.example"] + sources = [ + "source.amazon-ebs.arm64", + "source.amazon-ebs.x86_64", + ] provisioner "ansible" { playbook_file = "src/upgrade.yml" diff --git a/src/version.txt b/src/version.txt index 5c4105cd..8c0d5d5b 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -__version__ = "1.0.1" +__version__ = "2.0.0" diff --git a/terraform-post-packer/main.tf b/terraform-post-packer/main.tf index 7b3b4fff..d30cfdf2 100644 --- a/terraform-post-packer/main.tf +++ b/terraform-post-packer/main.tf @@ -24,34 +24,92 @@ locals { account_name_regex = format("^env[[:digit:]]+ \\(%s\\)$", local.images_account_type) } -# The IDs of all cisagov/skeleton-packer AMIs -data "aws_ami_ids" "historical_amis" { +# The IDs of all ARM64 cisagov/skeleton-packer AMIs +data "aws_ami_ids" "historical_amis_arm64" { + owners = [data.aws_caller_identity.images.account_id] + + filter { + name = "architecture" + values = ["arm64"] + } + filter { - name = "name" - values = [ - "example-hvm-*-x86_64-ebs", - ] + name = "name" + values = ["example-hvm-*-arm64-ebs"] + } + + filter { + name = "root-device-type" + values = ["ebs"] } filter { name = "virtualization-type" values = ["hvm"] } +} + +# Assign launch permissions to the ARM64 AMIs +module "ami_launch_permission_arm64" { + # Really we only want the var.recent_ami_count most recent AMIs, but + # we have to cover the case where there are fewer than that many + # AMIs in existence. Hence the min()/length() tomfoolery. + for_each = toset(slice(data.aws_ami_ids.historical_amis_arm64.ids, 0, min(var.recent_ami_count, length(data.aws_ami_ids.historical_amis_arm64.ids)))) + + source = "github.com/cisagov/ami-launch-permission-tf-module" + + providers = { + aws = aws + aws.master = aws.master + } + + account_name_regex = local.account_name_regex + ami_id = each.value + extraorg_account_ids = var.extraorg_account_ids +} + +# The IDs of all x86-64 cisagov/skeleton-packer AMIs +data "aws_ami_ids" "historical_amis_x86_64" { + owners = [data.aws_caller_identity.images.account_id] + + filter { + name = "architecture" + values = ["x86_64"] + } + + filter { + name = "name" + values = ["example-hvm-*-x86_64-ebs"] + } filter { name = "root-device-type" values = ["ebs"] } - owners = [data.aws_caller_identity.images.account_id] + filter { + name = "virtualization-type" + values = ["hvm"] + } +} + +# This moved block allows us to rename the resources at +# aws_ami_ids.historical_amis to aws_ami_ids.historical_amis_x86_64 +# instead of destroying and recreating them with a new name. +# +# TODO: Consider removing this moved block when it is no longer +# needed. See cisagov/skeleton-packer#369 for more details. +moved { + from = aws_ami_ids.historical_amis + to = aws_ami_ids.historical_amis_x86_64 } -# Assign launch permissions to the AMI -module "ami_launch_permission" { +# Assign launch permissions to the x86-64 AMIs +module "ami_launch_permission_x86_64" { # Really we only want the var.recent_ami_count most recent AMIs, but # we have to cover the case where there are fewer than that many # AMIs in existence. Hence the min()/length() tomfoolery. - for_each = toset(slice(data.aws_ami_ids.historical_amis.ids, 0, min(var.recent_ami_count, length(data.aws_ami_ids.historical_amis.ids)))) + for_each = toset(slice(data.aws_ami_ids.historical_amis_x86_64.ids, 0, min(var.recent_ami_count, length(data.aws_ami_ids.historical_amis_x86_64.ids)))) source = "github.com/cisagov/ami-launch-permission-tf-module" @@ -64,3 +122,14 @@ module "ami_launch_permission" { ami_id = each.value extraorg_account_ids = var.extraorg_account_ids } + +# This moved block allows us to rename the resources at +# module.ami_launch_permission to module.ami_launch_permission_x86_64 +# instead of destroying and recreating them with a new name. +# +# TODO: Consider removing this moved block when it is no longer +# needed. See cisagov/skeleton-packer#369 for more details. +moved { + from = module.ami_launch_permission + to = module.ami_launch_permission_x86_64 +} diff --git a/terraform-post-packer/outputs.tf b/terraform-post-packer/outputs.tf index ef5a669d..2937e6ea 100644 --- a/terraform-post-packer/outputs.tf +++ b/terraform-post-packer/outputs.tf @@ -1,4 +1,9 @@ -output "launch_permissions" { - value = module.ami_launch_permission - description = "The cisagov/ami-launch-permission-tf-module for each AMI to which launch permission is being granted." +output "launch_permissions_arm64" { + value = module.ami_launch_permission_arm64 + description = "The cisagov/ami-launch-permission-tf-module for each ARM64 AMI to which launch permission is being granted." +} + +output "launch_permissions_x86_64" { + value = module.ami_launch_permission_x86_64 + description = "The cisagov/ami-launch-permission-tf-module for each x86_64 AMI to which launch permission is being granted." } diff --git a/terraform-post-packer/variables.tf b/terraform-post-packer/variables.tf index 22b2a336..1b28b610 100644 --- a/terraform-post-packer/variables.tf +++ b/terraform-post-packer/variables.tf @@ -12,6 +12,6 @@ variable "extraorg_account_ids" { variable "recent_ami_count" { default = 12 - description = "The number of most-recent AMIs for which to grant launch permission (e.g. \"3\"). If this variable is set to three, for example, then accounts will be granted permission to launch the three most recent AMIs (or all most recent AMIs, if there are only one or two of them in existence)." + description = "The number of most-recent AMIs (per architecture) for which to grant launch permission (e.g. \"3\"). If this variable is set to three, for example, then accounts will be granted permission to launch the three most recent AMIs (or all most recent AMIs, if there are only one or two of them in existence)." type = number }