From 6b02361e4c36532e33907b8b8bcf1bb3c2e0cdc3 Mon Sep 17 00:00:00 2001 From: Hari Om Date: Fri, 15 May 2026 13:05:45 +0530 Subject: [PATCH] Add SBOM generation templates and update scripts - Introduced multiple Packer templates for generating SBOMs on various platforms including Amazon Linux, FreeBSD, RHEL, and Windows. - Added Docker templates for Linux with both legacy and no-exec styles. - Implemented a script to run SBOM case matrix tests, ensuring templates are executable and logging results. - Updated .gitignore to include necessary files and directories. - Enhanced existing Windows templates to support legacy execution styles. --- .gitignore | 4 +- .../sbom-test/amazon-freebsd-no-exec.pkr.hcl | 48 ++++++++ .../amazon-linux-legacy-exec.pkr.hcl | 51 +++++++++ .../sbom-test/amazon-linux-no-exec.pkr.hcl | 48 ++++++++ .../amazon-linux-no-sudo-exec.pkr.hcl | 49 +++++++++ .../sbom-test/amazon-rhel-legacy-exec.pkr.hcl | 51 +++++++++ .../hcl/sbom-test/amazon-rhel-no-exec.pkr.hcl | 48 ++++++++ .../amazon-unsupported-platforms.pkr.hcl | 54 +++++++++ .../amazon-windows-explicit-exec.pkr.hcl | 86 +++++++++++++++ .../sbom-test/amazon-windows-no-exec.pkr.hcl | 85 ++++++++++++++ .../docker-linux-legacy-exec.pkr.hcl | 46 ++++++++ .../sbom-test/docker-linux-no-exec.pkr.hcl | 42 +++++++ ...docker-linux-no-sudo-explicit-exec.pkr.hcl | 45 ++++++++ examples/hcl/sbom-test/sbom-test.pkr.hcl | 55 +++++++++ examples/hcl/sbom-test/sbom.pkr.hcl | 49 +++++++++ .../hcl/sbom-test/win-legacy-exec.pkr.hcl | 90 +++++++++++++++ examples/hcl/sbom-test/win.pkr.hcl | 104 ++++++++++++++++++ scripts/run-sbom-case-matrix.sh | 97 ++++++++++++++++ 18 files changed, 1049 insertions(+), 3 deletions(-) create mode 100644 examples/hcl/sbom-test/amazon-freebsd-no-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-linux-legacy-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-linux-no-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-linux-no-sudo-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-rhel-legacy-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-rhel-no-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-unsupported-platforms.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-windows-explicit-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/amazon-windows-no-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/docker-linux-legacy-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/docker-linux-no-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/docker-linux-no-sudo-explicit-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/sbom-test.pkr.hcl create mode 100644 examples/hcl/sbom-test/sbom.pkr.hcl create mode 100644 examples/hcl/sbom-test/win-legacy-exec.pkr.hcl create mode 100644 examples/hcl/sbom-test/win.pkr.hcl create mode 100755 scripts/run-sbom-case-matrix.sh diff --git a/.gitignore b/.gitignore index 0769f380d..cf05e291b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,4 @@ Thumbs.db /packer.exe .project cache -/.vscode/ -*.hcl -*.json \ No newline at end of file +/.vscode/ \ No newline at end of file diff --git a/examples/hcl/sbom-test/amazon-freebsd-no-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-freebsd-no-exec.pkr.hcl new file mode 100644 index 000000000..2395feab4 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-freebsd-no-exec.pkr.hcl @@ -0,0 +1,48 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "freebsd" { + ami_name = "sbom-amzn-freebsd-no-exec" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "FreeBSD 13.4-RELEASE-amd64*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["782086452779"] + } + + ssh_username = "ec2-user" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon FreeBSD SBOM test without execute_command override." +} + +build { + name = "sbom-amazon-freebsd-no-exec" + sources = ["source.amazon-ebs.freebsd"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon freebsd'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-freebsd-no-exec" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/amazon-linux-legacy-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-linux-legacy-exec.pkr.hcl new file mode 100644 index 000000000..fce8a5fb2 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-linux-legacy-exec.pkr.hcl @@ -0,0 +1,51 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "ubuntu" { + ami_name = "sbom-amzn-linux-legacy" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["099720109477"] + } + + ssh_username = "ubuntu" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon Linux SBOM test with legacy execute_command style." +} + +build { + name = "sbom-amazon-linux-legacy-exec" + sources = ["source.amazon-ebs.ubuntu"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon linux legacy'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-linux-legacy" + scanner_args = ["-o", "cyclonedx-json"] + + # Legacy style, compatibility path should auto-inject sbom-generate. + execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/amazon-linux-no-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-linux-no-exec.pkr.hcl new file mode 100644 index 000000000..0d6d44da2 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-linux-no-exec.pkr.hcl @@ -0,0 +1,48 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "ubuntu" { + ami_name = "sbom-amzn-linux-no-exec" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["099720109477"] + } + + ssh_username = "ubuntu" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon Linux SBOM test without execute_command override." +} + +build { + name = "sbom-amazon-linux-no-exec" + sources = ["source.amazon-ebs.ubuntu"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon linux'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-linux-no-exec" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/amazon-linux-no-sudo-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-linux-no-sudo-exec.pkr.hcl new file mode 100644 index 000000000..edc5ef8dc --- /dev/null +++ b/examples/hcl/sbom-test/amazon-linux-no-sudo-exec.pkr.hcl @@ -0,0 +1,49 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "ubuntu" { + ami_name = "sbom-amzn-linux-no-sudo" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["099720109477"] + } + + ssh_username = "ubuntu" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon Linux SBOM test with explicit no-sudo execute_command." +} + +build { + name = "sbom-amazon-linux-no-sudo-exec" + sources = ["source.amazon-ebs.ubuntu"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon linux no sudo'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-linux-no-sudo" + scanner_args = ["-o", "cyclonedx-json"] + execute_command = "chmod +x {{.Path}} && {{.Path}} sbom-generate {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/amazon-rhel-legacy-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-rhel-legacy-exec.pkr.hcl new file mode 100644 index 000000000..82d7609c3 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-rhel-legacy-exec.pkr.hcl @@ -0,0 +1,51 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "rhel" { + ami_name = "sbom-amzn-rhel-legacy" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "RHEL-9.*_HVM-*-x86_64-*-Hourly2-GP3" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["309956199498"] + } + + ssh_username = "ec2-user" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon RHEL SBOM test with legacy execute_command style." +} + +build { + name = "sbom-amazon-rhel-legacy-exec" + sources = ["source.amazon-ebs.rhel"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon rhel legacy'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-rhel-legacy" + scanner_args = ["-o", "cyclonedx-json"] + + # Legacy style, compatibility path should auto-inject sbom-generate. + execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/amazon-rhel-no-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-rhel-no-exec.pkr.hcl new file mode 100644 index 000000000..77b53ee87 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-rhel-no-exec.pkr.hcl @@ -0,0 +1,48 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "rhel" { + ami_name = "sbom-amzn-rhel-no-exec" + instance_type = "t3.large" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "RHEL-9.*_HVM-*-x86_64-*-Hourly2-GP3" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["309956199498"] + } + + ssh_username = "ec2-user" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon RHEL SBOM test without execute_command override." +} + +build { + name = "sbom-amazon-rhel-no-exec" + sources = ["source.amazon-ebs.rhel"] + + provisioner "shell" { + inline = ["echo 'packer works on amazon rhel'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-rhel-no-exec" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/amazon-unsupported-platforms.pkr.hcl b/examples/hcl/sbom-test/amazon-unsupported-platforms.pkr.hcl new file mode 100644 index 000000000..369255786 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-unsupported-platforms.pkr.hcl @@ -0,0 +1,54 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +# This template captures scenarios expected to fail SBOM generation on targets +# where the embedded Syft generator is not supported by build tags. +# Current unsupported targets in code include: netbsd, openbsd, solaris, +# mips, mipsle, mips64, and freebsd/386. + +source "amazon-ebs" "freebsd_i386_candidate" { + ami_name = "sbom-amzn-freebsd-unsupported" + instance_type = "t3.large" + region = "us-west-2" + + # Candidate filter for historical FreeBSD i386 AMIs (may not resolve in every region/account). + source_ami_filter { + filters = { + name = "FreeBSD*-i386*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["782086452779"] + } + + ssh_username = "ec2-user" +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon SBOM test for expected unsupported platform targets." +} + +build { + name = "sbom-amazon-unsupported-platforms" + sources = ["source.amazon-ebs.freebsd_i386_candidate"] + + provisioner "shell" { + inline = ["echo 'attempting unsupported SBOM target'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/usr/bin" + destination = "sbom.json" + sbom_name = "amzn-unsupported-platform" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/amazon-windows-explicit-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-windows-explicit-exec.pkr.hcl new file mode 100644 index 000000000..86644a737 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-windows-explicit-exec.pkr.hcl @@ -0,0 +1,86 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "windows" { + ami_name = "sbom-amzn-windows-explicit" + instance_type = "m4.2xlarge" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "Windows_Server-2022-English-Full-Base-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["801119661308"] + } + + communicator = "winrm" + winrm_username = "packer" + winrm_password = "P@cker1234" + winrm_insecure = true + winrm_use_ssl = true + winrm_timeout = "30m" + + user_data = < +Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore +$ErrorActionPreference = "stop" + +Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse +$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer" +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force + +$username = "packer" +$password = ConvertTo-SecureString -String 'P@cker1234' -AsPlainText -Force +New-LocalUser $username -Password $password -FullName "Packer User" -Description "Temporary user for Packer" +Add-LocalGroupMember -Group "Administrators" -Member $username + +cmd.exe /c winrm quickconfig -q +cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}' +cmd.exe /c winrm set "winrm/config" '@{MaxEnvelopeSizekb="8192"}' +cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}' +cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}' +cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}" +cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes +cmd.exe /c netsh advfirewall firewall add rule name="Port 5986" dir=in action=allow protocol=TCP localport=5986 profile=any +cmd.exe /c net stop winrm +cmd.exe /c sc config winrm start= auto +cmd.exe /c net start winrm + +EOF +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon Windows SBOM test with explicit execute_command." +} + +build { + name = "sbom-amazon-windows-explicit-exec" + sources = ["source.amazon-ebs.windows"] + + provisioner "powershell" { + inline = ["Write-Output 'packer works on amazon windows explicit'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "C:\\Windows\\Temp" + destination = "sbom.json" + sbom_name = "amzn-windows-explicit" + scanner_args = ["-o", "cyclonedx-json"] + execute_command = "{{.Path}} sbom-generate {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/amazon-windows-no-exec.pkr.hcl b/examples/hcl/sbom-test/amazon-windows-no-exec.pkr.hcl new file mode 100644 index 000000000..2c5b9ccf2 --- /dev/null +++ b/examples/hcl/sbom-test/amazon-windows-no-exec.pkr.hcl @@ -0,0 +1,85 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "windows" { + ami_name = "sbom-amzn-windows-no-exec" + instance_type = "m4.2xlarge" + region = "us-west-2" + + source_ami_filter { + filters = { + name = "Windows_Server-2022-English-Full-Base-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["801119661308"] + } + + communicator = "winrm" + winrm_username = "packer" + winrm_password = "P@cker1234" + winrm_insecure = true + winrm_use_ssl = true + winrm_timeout = "30m" + + user_data = < +Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore +$ErrorActionPreference = "stop" + +Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse +$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer" +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force + +$username = "packer" +$password = ConvertTo-SecureString -String 'P@cker1234' -AsPlainText -Force +New-LocalUser $username -Password $password -FullName "Packer User" -Description "Temporary user for Packer" +Add-LocalGroupMember -Group "Administrators" -Member $username + +cmd.exe /c winrm quickconfig -q +cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}' +cmd.exe /c winrm set "winrm/config" '@{MaxEnvelopeSizekb="8192"}' +cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}' +cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}' +cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}" +cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes +cmd.exe /c netsh advfirewall firewall add rule name="Port 5986" dir=in action=allow protocol=TCP localport=5986 profile=any +cmd.exe /c net stop winrm +cmd.exe /c sc config winrm start= auto +cmd.exe /c net start winrm + +EOF +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Amazon Windows SBOM test without execute_command override." +} + +build { + name = "sbom-amazon-windows-no-exec" + sources = ["source.amazon-ebs.windows"] + + provisioner "powershell" { + inline = ["Write-Output 'packer works on amazon windows'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "C:\\Windows\\Temp" + destination = "sbom.json" + sbom_name = "amzn-windows-no-exec" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/docker-linux-legacy-exec.pkr.hcl b/examples/hcl/sbom-test/docker-linux-legacy-exec.pkr.hcl new file mode 100644 index 000000000..4589dae29 --- /dev/null +++ b/examples/hcl/sbom-test/docker-linux-legacy-exec.pkr.hcl @@ -0,0 +1,46 @@ +packer { + required_plugins { + docker = { + source = "github.com/hashicorp/docker" + version = ">= 1.0.0" + } + } +} + +variable "hcp_bucket_name" { + type = string + default = "sbom-bucket-test" + description = "HCP Packer bucket name." +} + +variable "image_name" { + type = string + default = "ubuntu:22.04" + description = "Base docker image to build from." +} + +source "docker" "ubuntu" { + image = var.image_name + commit = true +} + +build { + name = "sbom-docker-linux-legacy-exec" + sources = ["source.docker.ubuntu"] + + hcp_packer_registry { + bucket_name = var.hcp_bucket_name + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/" + destination = "./sbom" + sbom_name = "docker-linux-legacy" + scanner_args = ["-o", "cyclonedx-json"] + + # Legacy style command that omits 'sbom-generate'. + # This should now work through compatibility injection in code. + execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/docker-linux-no-exec.pkr.hcl b/examples/hcl/sbom-test/docker-linux-no-exec.pkr.hcl new file mode 100644 index 000000000..d4233c539 --- /dev/null +++ b/examples/hcl/sbom-test/docker-linux-no-exec.pkr.hcl @@ -0,0 +1,42 @@ +packer { + required_plugins { + docker = { + source = "github.com/hashicorp/docker" + version = ">= 1.0.0" + } + } +} + +variable "hcp_bucket_name" { + type = string + default = "sbom-bucket-test" + description = "HCP Packer bucket name." +} + +variable "image_name" { + type = string + default = "ubuntu:22.04" + description = "Base docker image to build from." +} + +source "docker" "ubuntu" { + image = var.image_name + commit = true +} + +build { + name = "sbom-docker-linux-no-exec" + sources = ["source.docker.ubuntu"] + + hcp_packer_registry { + bucket_name = var.hcp_bucket_name + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/" + destination = "./sbom" + sbom_name = "docker-linux-no-exec" + scanner_args = ["-o", "cyclonedx-json"] + } +} diff --git a/examples/hcl/sbom-test/docker-linux-no-sudo-explicit-exec.pkr.hcl b/examples/hcl/sbom-test/docker-linux-no-sudo-explicit-exec.pkr.hcl new file mode 100644 index 000000000..0228b872d --- /dev/null +++ b/examples/hcl/sbom-test/docker-linux-no-sudo-explicit-exec.pkr.hcl @@ -0,0 +1,45 @@ +packer { + required_plugins { + docker = { + source = "github.com/hashicorp/docker" + version = ">= 1.0.0" + } + } +} + +variable "hcp_bucket_name" { + type = string + default = "sbom-bucket-test" + description = "HCP Packer bucket name." +} + +variable "image_name" { + type = string + default = "ubuntu:22.04" + description = "Base docker image to build from." +} + +source "docker" "ubuntu" { + image = var.image_name + commit = true +} + +build { + name = "sbom-docker-linux-no-sudo-explicit-exec" + sources = ["source.docker.ubuntu"] + + hcp_packer_registry { + bucket_name = var.hcp_bucket_name + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/" + destination = "./sbom" + sbom_name = "docker-linux-no-sudo-explicit" + scanner_args = ["-o", "cyclonedx-json"] + + # Explicit no-sudo command that includes sbom-generate. + execute_command = "chmod +x {{.Path}} && {{.Path}} sbom-generate {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/sbom-test.pkr.hcl b/examples/hcl/sbom-test/sbom-test.pkr.hcl new file mode 100644 index 000000000..746ad4838 --- /dev/null +++ b/examples/hcl/sbom-test/sbom-test.pkr.hcl @@ -0,0 +1,55 @@ +packer { + required_plugins { + docker = { + source = "github.com/hashicorp/docker" + version = ">= 1.0.0" + } + } +} + +variable "hcp_bucket_name" { + type = string + default = "sbom-bucket-test" + description = "HCP Packer bucket name (must exist or be creatable in your org/project)." +} + +variable "image_name" { + type = string + default = "ubuntu:22.04" + description = "Base docker image to build from." +} + +source "docker" "ubuntu" { + image = var.image_name + commit = true +} + +build { + name = "sbom-test" + sources = ["source.docker.ubuntu"] + + # This publishes the artifact metadata to HCP Packer Registry. + hcp_packer_registry { + bucket_name = var.hcp_bucket_name + } + + # Automatically generate SBOM using the embedded Syft SDK in the Packer + # binary and upload to HCP Packer. + # + # Packer automatically selects the right binary for the remote host: + # - Same OS/arch as host → uses the running Packer binary (zero cost) + # - Different OS/arch, release build → downloads from releases.hashicorp.com + # - Different OS/arch, dev build → cross-compiles from source via `go build` + # + # You can also pin a specific binary with `scanner_binary_path` (e.g. for + # air-gapped environments or pre-built cross-compiled binaries). + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "/" + destination = "./sbom" # local folder must already exist + sbom_name = "auto-sbom" + scanner_args = ["-o", "spdx-json", "-q"] + # {{.Path}} is the uploaded Packer binary; sbom-generate is the subcommand. + execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} \ No newline at end of file diff --git a/examples/hcl/sbom-test/sbom.pkr.hcl b/examples/hcl/sbom-test/sbom.pkr.hcl new file mode 100644 index 000000000..2503537bd --- /dev/null +++ b/examples/hcl/sbom-test/sbom.pkr.hcl @@ -0,0 +1,49 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} +source "amazon-ebs" "ubuntu" { + ami_name = "test16" + instance_type = "t2.large" + region = "us-west-2" + source_ami_filter { + filters = { + name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["099720109477"] + } + ssh_username = "ubuntu" + # skip_create_ami = true +} +hcp_packer_registry { + bucket_name = "native-sbom" + description = < + +Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore +$ErrorActionPreference = "stop" + +Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse +$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer" +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force + +$username = "packer" +$password = ConvertTo-SecureString -String 'P@cker1234' -AsPlainText -Force +New-LocalUser $username -Password $password -FullName "Packer User" -Description "Temporary user for Packer" +Add-LocalGroupMember -Group "Administrators" -Member $username + +cmd.exe /c winrm quickconfig -q +cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}' +cmd.exe /c winrm set "winrm/config" '@{MaxEnvelopeSizekb="8192"}' +cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}' +cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}' +cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}" +cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes +cmd.exe /c netsh advfirewall firewall add rule name="Port 5986" dir=in action=allow protocol=TCP localport=5986 profile=any +cmd.exe /c net stop winrm +cmd.exe /c sc config winrm start= auto +cmd.exe /c net start winrm + + +EOF +} + +hcp_packer_registry { + bucket_name = "native-sbom" + description = "Windows SBOM test using a legacy execute_command style." +} + +build { + name = "native-sbom-packer-windows-legacy-exec" + sources = ["source.amazon-ebs.windows"] + + provisioner "powershell" { + inline = ["Write-Output 'packer works on Windows'"] + } + + provisioner "hcp-sbom" { + auto_generate = true + scan_path = "C:\\Windows\\Temp" + destination = "sbom.json" + sbom_name = "windows-legacy-exec" + scanner_args = ["-o", "cyclonedx-json"] + + # Legacy style command that omits 'sbom-generate'. + execute_command = "{{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}" + } +} diff --git a/examples/hcl/sbom-test/win.pkr.hcl b/examples/hcl/sbom-test/win.pkr.hcl new file mode 100644 index 000000000..fc6bf7a66 --- /dev/null +++ b/examples/hcl/sbom-test/win.pkr.hcl @@ -0,0 +1,104 @@ +packer { + required_plugins { + amazon = { + version = ">= 1.2.8" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "windows" { + ami_name = "test1-windows" + instance_type = "m4.2xlarge" + region = "us-west-2" + source_ami_filter { + filters = { + name = "Windows_Server-2022-English-Full-Base-*" + root-device-type = "ebs" + virtualization-type = "hvm" + } + most_recent = true + owners = ["801119661308"] # Microsoft’s official AWS account + } + + communicator = "winrm" + winrm_username = "packer" + winrm_password = "P@cker1234" + winrm_insecure = true + winrm_use_ssl = true + winrm_timeout = "30m" + + user_data = < + +write-output "Running User Data Script" +write-host "(host) Running User Data Script" + +Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore + +$ErrorActionPreference = "stop" + +Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse + +$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer" +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force + +$username = "packer" +$password = ConvertTo-SecureString -String 'P@cker1234' -AsPlainText -Force +New-LocalUser $username -Password $password -FullName "Packer User" -Description "Temporary user for Packer" +Add-LocalGroupMember -Group "Administrators" -Member $username + +write-output "Setting up WinRM" +write-host "(host) setting up WinRM" + +cmd.exe /c winrm quickconfig -q +cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}' +cmd.exe /c winrm set "winrm/config" '@{MaxEnvelopeSizekb="16384"}' +cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}' +cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}' +cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}' +cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}" +cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes +cmd.exe /c netsh advfirewall firewall add rule name="Port 5986" dir=in action=allow protocol=TCP localport=5986 profile=any +cmd.exe /c net stop winrm +cmd.exe /c sc config winrm start= auto +cmd.exe /c net start winrm + + +EOF +} + +hcp_packer_registry { + bucket_name = "native-sbom" + + description = <&2 + exit 1 +fi + +if [[ ! -d "$TEMPLATE_DIR" ]]; then + echo "error: template directory not found: $TEMPLATE_DIR" >&2 + exit 1 +fi + +mkdir -p "$LOG_DIR" +RUN_TS="$(date +%Y%m%d-%H%M%S)" +MASTER_LOG="$LOG_DIR/all-cases-localhost3231-${RUN_TS}.log" +SUMMARY_TSV="$LOG_DIR/summary-${RUN_TS}.tsv" + +version_raw="$($PACKER_BIN version 2>/dev/null | awk 'NR==1{print $2}')" +version="${version_raw#v}" +if [[ -z "$version" ]]; then + echo "error: could not detect packer version from $PACKER_BIN version" >&2 + exit 1 +fi + +sums_url="$RELEASE_SERVER/packer/$version/packer_${version}_SHA256SUMS" + +start_local_release_server() { + if [[ "$RELEASE_SERVER" != "http://localhost:3231" && "$RELEASE_SERVER" != "http://127.0.0.1:3231" ]]; then + return + fi + + if curl -sS --max-time 3 "$sums_url" >/dev/null 2>&1; then + return + fi + + echo "[info] starting local release server on localhost:3231" | tee -a "$MASTER_LOG" + ( + cd "$ROOT_DIR" || exit 1 + python3 scripts/local-release-server.py --port 3231 + ) >"$LOG_DIR/local-release-server-${RUN_TS}.log" 2>&1 & + server_pid=$! + + for _ in {1..20}; do + if curl -sS --max-time 3 "$sums_url" >/dev/null 2>&1; then + echo "[info] local release server ready (pid=$server_pid)" | tee -a "$MASTER_LOG" + return + fi + sleep 1 + done + + echo "error: local release server did not become ready; see $LOG_DIR/local-release-server-${RUN_TS}.log" | tee -a "$MASTER_LOG" >&2 + exit 1 +} + +start_local_release_server + +echo -e "template\texit_code\tcase_log" > "$SUMMARY_TSV" +echo "Run started at $(date)" | tee -a "$MASTER_LOG" +echo "PACKER_BIN=$PACKER_BIN" | tee -a "$MASTER_LOG" +echo "TEMPLATE_DIR=$TEMPLATE_DIR" | tee -a "$MASTER_LOG" +echo "RELEASE_SERVER=$RELEASE_SERVER" | tee -a "$MASTER_LOG" +echo "SUMMARY_TSV=$SUMMARY_TSV" | tee -a "$MASTER_LOG" +echo | tee -a "$MASTER_LOG" + +mapfile -t templates < <(find "$TEMPLATE_DIR" -maxdepth 1 -type f -name '*.pkr.hcl' | sort) +if [[ ${#templates[@]} -eq 0 ]]; then + echo "error: no templates found in $TEMPLATE_DIR" | tee -a "$MASTER_LOG" >&2 + exit 1 +fi + +for f in "${templates[@]}"; do + name="$(basename "$f" .pkr.hcl)" + case_log="$LOG_DIR/${name}-${RUN_TS}.log" + + echo "===== RUNNING: $f =====" | tee -a "$MASTER_LOG" "$case_log" + + set +e + PACKER_RELEASE_SERVER="$RELEASE_SERVER" "$PACKER_BIN" build "$f" 2>&1 | tee -a "$MASTER_LOG" "$case_log" + code=${PIPESTATUS[0]} + set -e + + echo "===== EXIT: $code : $f =====" | tee -a "$MASTER_LOG" "$case_log" + echo -e "$f\t$code\t$case_log" >> "$SUMMARY_TSV" + echo | tee -a "$MASTER_LOG" "$case_log" +done + +echo "Run finished at $(date)" | tee -a "$MASTER_LOG" +echo "MASTER_LOG=$MASTER_LOG" | tee -a "$MASTER_LOG" +echo "SUMMARY_TSV=$SUMMARY_TSV" | tee -a "$MASTER_LOG"