{"id":51319786,"url":"https://github.com/ivoronin/packer-plugin-ebsdirect","last_synced_at":"2026-07-02T13:00:44.746Z","repository":{"id":368579255,"uuid":"1284743064","full_name":"ivoronin/packer-plugin-ebsdirect","owner":"ivoronin","description":"Packer post-processor that imports a raw disk image to an AMI via EBS direct APIs - no S3 staging, no vmimport role","archived":false,"fork":false,"pushed_at":"2026-07-01T07:12:15.000Z","size":71,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-01T09:12:18.472Z","etag":null,"topics":["ami","aws","devops","ebs","ebs-direct-apis","ebs-snapshot","ec2","hashicorp","packer","packer-plugin","packer-post-processor"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivoronin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-30T06:45:46.000Z","updated_at":"2026-07-01T07:12:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ivoronin/packer-plugin-ebsdirect","commit_stats":null,"previous_names":["ivoronin/packer-plugin-ebsdirect"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ivoronin/packer-plugin-ebsdirect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivoronin%2Fpacker-plugin-ebsdirect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivoronin%2Fpacker-plugin-ebsdirect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivoronin%2Fpacker-plugin-ebsdirect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivoronin%2Fpacker-plugin-ebsdirect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivoronin","download_url":"https://codeload.github.com/ivoronin/packer-plugin-ebsdirect/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivoronin%2Fpacker-plugin-ebsdirect/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35005413,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ami","aws","devops","ebs","ebs-direct-apis","ebs-snapshot","ec2","hashicorp","packer","packer-plugin","packer-post-processor"],"created_at":"2026-07-01T12:01:26.856Z","updated_at":"2026-07-01T12:01:27.806Z","avatar_url":"https://github.com/ivoronin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# packer-plugin-ebsdirect\n\nRegister a raw disk image as an AMI through the EBS direct APIs - no S3 bucket and no `vmimport` role.\n\n[![test](https://github.com/ivoronin/packer-plugin-ebsdirect/actions/workflows/test.yml/badge.svg)](https://github.com/ivoronin/packer-plugin-ebsdirect/actions/workflows/test.yml)\n[![release](https://img.shields.io/github/v/release/ivoronin/packer-plugin-ebsdirect)](https://github.com/ivoronin/packer-plugin-ebsdirect/releases)\n\n## Table of Contents\n\n[Overview](#overview) · [Features](#features) · [Installation](#installation) · [Usage](#usage) · [Configuration](#configuration) · [Requirements](#requirements) · [License](#license)\n\n```hcl\n# amazon-import uploads through S3 and needs the vmimport service role:\n#   post-processor \"amazon-import\" {\n#     s3_bucket_name = \"my-vmimport-bucket\"   # create it, manage it, pay for it\n#     role_name      = \"vmimport\"             # set up its trust policy first\n#     ...\n#   }\n\n# ebsdirect writes the snapshot straight from the raw image:\npost-processor \"ebsdirect\" {\n  ami_name = \"my-image\"\n}\n```\n\n## Overview\n\n`ebsdirect` is a Packer post-processor that takes a raw disk image from a previous build step and turns it into an AMI without going through S3. It uploads the image straight into an EBS snapshot with the EBS direct APIs (`StartSnapshot` / `PutSnapshotBlock` / `CompleteSnapshot`), writing 512 KiB blocks in parallel and skipping all-zero ones, then registers that snapshot as an AMI with `RegisterImage`. Credentials come from the default AWS SDK chain.\n\nThis drops the two things `amazon-import` requires that have nothing to do with the image itself: the S3 bucket you upload through, and the `vmimport` IAM role with its trust policy.\n\nAvailable on the [Packer integrations registry](https://developer.hashicorp.com/packer/integrations/ivoronin/ebsdirect).\n\n## Features\n\n- Uploads via the EBS direct APIs - no S3 bucket and no `vmimport` role to set up.\n- Skips all-zero 512 KiB blocks, so a 10 GiB image holding 2 GiB of data uploads about 2 GiB.\n- Parallel block upload (64 workers) with retry on throttling.\n- Per-block SHA-256 plus a LINEAR aggregate checksum that AWS validates at `CompleteSnapshot`.\n- Registers a modern HVM AMI: ENA enabled, gp3 root volume (16 TiB ceiling), `x86_64` or `arm64`, boot mode `legacy-bios` / `uefi` / `uefi-preferred`.\n- Optional snapshot encryption (`ami_encrypt` / `ami_kms_key`) with the account default or a customer-managed KMS key.\n- Optional `imds_support = v2.0` so the AMI defaults to requiring IMDSv2 on instances launched from it.\n- Share the AMI's launch permission with accounts, organizations, OUs, or publicly (`ami_users` / `ami_org_arns` / `ami_ou_arns` / `ami_groups`).\n\n## Installation\n\nDeclare the plugin in your template and run `packer init`:\n\n```hcl\npacker {\n  required_plugins {\n    ebsdirect = {\n      version = \"\u003e= 0.1.0\"\n      source  = \"github.com/ivoronin/ebsdirect\"\n    }\n  }\n}\n```\n\n```bash\npacker init .\n```\n\nPrebuilt binaries are on the [releases page](https://github.com/ivoronin/packer-plugin-ebsdirect/releases).\n\n## Usage\n\nChain the post-processor after any builder that produces a raw image. With the core `file` builder pointing at an image you built elsewhere:\n\n```hcl\nsource \"file\" \"image\" {\n  source = \"disk.raw\"   # raw format, a whole number of GiB\n  target = \"disk.raw\"\n}\n\nbuild {\n  sources = [\"source.file.image\"]\n\n  post-processor \"ebsdirect\" {\n    ami_name      = \"my-image\"\n    architecture  = \"x86_64\"        # or arm64\n    boot_mode     = \"legacy-bios\"   # or uefi / uefi-preferred\n    tags          = { project = \"demo\" }\n    snapshot_tags = { project = \"demo\" }\n  }\n}\n```\n\nThe same shape works after a `qemu` build that outputs a raw disk. The post-processor produces an AMI artifact with id `\u003cregion\u003e:\u003cami-id\u003e`; destroying that artifact deregisters the AMI and deletes its snapshot.\n\n## Configuration\n\n| Field | Required | Default | Description |\n|-------|----------|---------|-------------|\n| `ami_name` | yes | - | Name of the registered AMI. |\n| `ami_description` | no | `\"\"` | AMI description. |\n| `architecture` | no | `x86_64` | `x86_64` or `arm64` (arm64 requires `uefi`). |\n| `boot_mode` | no | `legacy-bios` | `legacy-bios`, `uefi`, or `uefi-preferred`. |\n| `root_device_name` | no | `/dev/xvda` | Root device name on the AMI. |\n| `region` | no | from the SDK chain | Target region; otherwise `AWS_REGION` or the active profile. |\n| `tags` | no | - | Tags applied to the AMI. |\n| `snapshot_tags` | no | - | Tags applied to the snapshot. |\n| `ami_encrypt` | no | `false` | Request encryption of the snapshot (and the resulting AMI). An account/region with EBS encryption-by-default still produces an encrypted snapshot regardless. |\n| `ami_kms_key` | no | account default EBS key | KMS key ARN for the encrypted snapshot. Requires `ami_encrypt = true`; ignored otherwise. |\n| `imds_support` | no | `\"\"` | Set to `v2.0` so the AMI defaults to requiring IMDSv2 on launched instances. Image default, not a hard lock (overridable at `RunInstances`). |\n| `ami_users` | no | - | Account IDs granted launch permission on the AMI. |\n| `ami_groups` | no | - | Launch-permission groups; only `all` (makes the AMI public) is supported. |\n| `ami_org_arns` | no | - | Organization ARNs granted launch permission. |\n| `ami_ou_arns` | no | - | Organizational-unit ARNs granted launch permission. |\n\nCredentials are read from the default AWS SDK chain (environment, `AWS_PROFILE` / shared config, SSO, instance role). There are no credential fields in the template.\n\n## Requirements\n\n- Packer 1.7 or later (for `packer init`).\n- A raw disk image whose size is a whole number of GiB. Use `qemu-img convert -O raw` to convert and `qemu-img resize` to round up if needed.\n- IAM permissions:\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\"ebs:StartSnapshot\", \"ebs:PutSnapshotBlock\", \"ebs:CompleteSnapshot\"],\n      \"Resource\": \"arn:aws:ec2:*::snapshot/*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\"ec2:RegisterImage\", \"ec2:DescribeSnapshots\", \"ec2:DeregisterImage\", \"ec2:DeleteSnapshot\", \"ec2:CreateTags\", \"ec2:ModifyImageAttribute\"],\n      \"Resource\": \"*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\"kms:DescribeKey\", \"kms:GenerateDataKeyWithoutPlaintext\", \"kms:CreateGrant\", \"kms:ReEncrypt*\", \"kms:Decrypt\"],\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\nThe KMS actions are only needed when `ami_encrypt` is used with a customer-managed key; the account default EBS key is already usable by account principals.\n\nSharing does not share the underlying snapshot: AWS gives recipients snapshot access for launch. Sharing an encrypted AMI works only when it is backed by a customer-managed KMS key (not the default `aws/ebs` key), and the recipient accounts must be granted access to that key.\n\n## License\n\n[MPL-2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivoronin%2Fpacker-plugin-ebsdirect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivoronin%2Fpacker-plugin-ebsdirect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivoronin%2Fpacker-plugin-ebsdirect/lists"}