{"id":20697420,"url":"https://github.com/epomatti/aws-ec2-imagebuilder","last_synced_at":"2026-05-01T16:31:10.216Z","repository":{"id":220696999,"uuid":"704225192","full_name":"epomatti/aws-ec2-imagebuilder","owner":"epomatti","description":"AWS EC2 Image Builder components for a Tailscale image","archived":false,"fork":false,"pushed_at":"2024-04-25T00:19:37.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-12T16:09:12.417Z","etag":null,"topics":["aws","ec2","ec2-image-builder","image-builder","tailscale","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/epomatti.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-12T20:01:22.000Z","updated_at":"2024-04-25T00:19:40.000Z","dependencies_parsed_at":"2024-04-25T02:00:41.223Z","dependency_job_id":"5686726e-a4ab-4e2f-886d-cb58ef5ee55f","html_url":"https://github.com/epomatti/aws-ec2-imagebuilder","commit_stats":null,"previous_names":["epomatti/aws-ec2-imagebuilder"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/epomatti/aws-ec2-imagebuilder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Faws-ec2-imagebuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Faws-ec2-imagebuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Faws-ec2-imagebuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Faws-ec2-imagebuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/epomatti","download_url":"https://codeload.github.com/epomatti/aws-ec2-imagebuilder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/epomatti%2Faws-ec2-imagebuilder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32504940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"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":["aws","ec2","ec2-image-builder","image-builder","tailscale","terraform"],"created_at":"2024-11-17T00:17:57.846Z","updated_at":"2026-05-01T16:31:09.880Z","avatar_url":"https://github.com/epomatti.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EC2 Image Builder\n\nThis project created all of the resources for an Image Builder Pipeline with a **Tailscale** subnet router installation.\n\nOn top of subnet router [IP forwarding][3] settings, the image is also configured with Tailscale [performance best practices][4].\n\nTo see this image in use, check my other repository [epomatti/aws-rds-tailscale-vpn][2].\n\n## Setup\n\nCopy the `.auto.tfvars` file:\n\n```sh\ncp config/template.tfvars .auto.tfvars\n```\n\nYou can find the latest image in SSM. Example for [Canonical images][5] used in this project:\n\n```sh\naws ssm get-parameters --region us-east-2 --names \\\n   /aws/service/canonical/ubuntu/server/22.04/stable/current/arm64/hvm/ebs-gp2/ami-id\n```\n\nTo create the project resources:\n\n```sh\nterraform init\nterraform apply -auto-approve\n```\n\nLogin to the AWS Console and start the build process manually.\n\nA test instance will be automatically created by the workflow. If needed, a launch template is available to manually test the created image on EC2.\n\nChecking the status of the CloudWatch agent:\n\n```sh\n/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -m ec2 -a status\n```\n\n## Implementation\n\nRecipe components:\n\n- Linux update\n- CloudWatch Agent\n- Custom component for Tailscale with complete setup ([tailscale.yaml](./modules/imagebuilder/components/tailscale.yaml))\n- Reboot\n\nSSM agent is kept in the image to be used during launch. Vulnerability scan will be performed by the pipeline.\n\nAdditional information:\n\n- Image Builder publishes managed or curated images which have higher update rates, but appear to be unavailable via other means. I've created this [thread][1] to learn more about it.\n- EC2 build instances require internet access. This can be configured via NAT in the VPC, or enabling public IP addresses auto-assign.\n- Make sure to make the installation completely noninteractive, for example with `DEBIAN_FRONTEND=noninteractive` for Debian-based distributions.\n\n## Cross-account distribution\n\nSteps documented following the cross-account distribution [documentation][6] with help from this [blob post][7].\n\n**Requirement:** You'll need to create a KMS CMK key and use it in your image recipe.\n\n### Source\n\nIn the Image Builder, create a distribution setting with the KMS CMK Key referenced and the target accounts.\n\n\u003cimg src=\".img/imagebuilder5.png\" /\u003e\n\nAdd this policy to the KMS CMK Key:\n\n```json\n{\n   \"Sid\": \"Enable cross-account Image Builder distribution\",\n   \"Effect\": \"Allow\",\n   \"Principal\": {\n         \"AWS\": [\n            \"arn:aws:iam::ACCOUNT_A:root\",\n            \"arn:aws:iam::ACCOUNT_B:root\",\n            \"arn:aws:iam::ACCOUNT_C:root\"\n         ]\n   },\n   \"Action\": [\n         \"kms:Encrypt\",\n         \"kms:Decrypt\",\n         \"kms:ReEncrypt*\",\n         \"kms:GenerateDataKey*\",\n         \"kms:DescribeKey\",\n         \"kms:CreateGrant\",\n         \"kms:ListGrants\",\n         \"kms:RevokeGrant\"\n   ],\n   \"Resource\": \"*\"\n}\n```\n\n### Destination\n\n1. Create the `EC2ImageBuilderDistributionCrossAccountRole` on each destination account. This role will be used by the **source** account. The trust policy should look like below, replacing the `SOURCE_ACCOUNT` with the source account id.\n   ```json\n   {\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Principal\": {\n                \"AWS\": \"arn:aws:iam::SOURCE_ACCOUNT:root\"\n            },\n            \"Action\": \"sts:AssumeRole\",\n            \"Condition\": {}\n        }\n    ]\n   }\n   ```\n\n2. Add the managed policy `Ec2ImageBuilderCrossAccountDistributionAccess` to the role.\n3. Add this inline policy to the role:\n   ```json\n   {\n\t\"Version\": \"2012-10-17\",\n\t\"Statement\": [\n\t\t{\n\t\t\t\"Sid\": \"AllowRoleToPerformKMSOperationsOnBehalfOfTheDestinationAccount\",\n\t\t\t\"Effect\": \"Allow\",\n\t\t\t\"Action\": [\n\t\t\t\t\"kms:Encrypt\",\n\t\t\t\t\"kms:Decrypt\",\n\t\t\t\t\"kms:ReEncrypt*\",\n\t\t\t\t\"kms:GenerateDataKey*\",\n\t\t\t\t\"kms:DescribeKey\",\n\t\t\t\t\"kms:CreateGrant\",\n\t\t\t\t\"kms:ListGrants\",\n\t\t\t\t\"kms:RevokeGrant\"\n\t\t\t],\n\t\t\t\"Resource\": \"*\"\n\t\t}\n\t]\n   }\n   ```\n\n### Other integrations\n\nAdditional access might be required for automation, since now services that will use your AMI will require access to the KMS CMK Key in cross-account setup.\n\n```json\n{\n   \"Sid\": \"\",\n   \"Effect\": \"Allow\",\n   \"Principal\": {\n         \"AWS\": [\n            \"arn:aws:iam::ACCOUNT_A:role/YourRoleStage\",\n            \"arn:aws:iam::ACCOUNT_B:role/YourRoleProduction\"\n         ]\n   },\n   \"Action\": [\n         \"kms:Encrypt\",\n         \"kms:Decrypt\",\n         \"kms:ReEncrypt*\",\n         \"kms:GenerateDataKey*\",\n         \"kms:DescribeKey\"\n   ],\n   \"Resource\": \"*\"\n},\n{\n   \"Sid\": \"\",\n   \"Effect\": \"Allow\",\n   \"Principal\": {\n         \"AWS\": [\n            \"arn:aws:iam::ACCOUNT_A:role/YourRoleStage\",\n            \"arn:aws:iam::ACCOUNT_B:role/YourRoleProduction\"\n         ]\n   },\n   \"Action\": \"kms:CreateGrant\",\n   \"Resource\": \"*\",\n   \"Condition\": {\n         \"Bool\": {\n            \"kms:GrantIsForAWSResource\": \"true\"\n         }\n   }\n}\n```\n\n---\n\n### Clean-up\n\nDestroy the resources after use:\n\n```sh\nterraform destroy -auto-approve\n```\n\n\n[1]: https://repost.aws/questions/QUwGgIFpv8SuyY6uvxlWIcyg/where-to-find-ec2-image-builder-managed-images\n[2]: https://github.com/epomatti/aws-rds-tailscale-vpn\n[3]: https://tailscale.com/kb/1019/subnets\n[4]: https://tailscale.com/kb/1320/performance-best-practices#ethtool-configuration\n[5]: https://canonical-aws.readthedocs-hosted.com/en/latest/aws-how-to/instances/find-ubuntu-images/\n[6]: https://docs.aws.amazon.com/imagebuilder/latest/userguide/cross-account-dist.html\n[7]: https://repost.aws/knowledge-center/image-builder-distr-error-encrypted-ami\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepomatti%2Faws-ec2-imagebuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fepomatti%2Faws-ec2-imagebuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fepomatti%2Faws-ec2-imagebuilder/lists"}