This guide walks through creating a Talos AMI for AWS, importing it into your AWS account, and launching EC2 instances that can be registered with Omni.
Step 1: Set your AWS region
Define the AWS region where you want to create your Omni machines.
REGION=<your-aws-region> # e.g. us-east-1
Step 2: Identify the VPC
Your EC2 instances must run inside a VPC. Most AWS accounts have a default VPC available.
First list the VPCs in your region:
aws ec2 describe-vpcs --region $REGION
Then capture the default VPC:
VPC_ID=$(aws ec2 describe-vpcs \
--region $REGION \
--query "Vpcs[?IsDefault].VpcId" \
--output text)
echo $VPC_ID
This command stores the VPC ID in the VPC_ID variable.
Step 3: Create a subnet
Next, create a subnet within the VPC.
The subnet CIDR must fall within the VPC CIDR range. For example, if the VPC uses 172.31.0.0/16, you can create a subnet such as 172.31.128.0/20.
SUBNET_ID=$(aws ec2 create-subnet \
--region $REGION \
--vpc-id $VPC_ID \
--cidr-block 172.31.128.0/20 \
--query "Subnet.SubnetId" \
--output text)
echo $SUBNET_ID
The subnet ID will be used later when launching EC2 instances.
Step 4: Create a security group
First, create a security group that will be attached to the EC2 instances.
SECURITY_GROUP=$(aws ec2 create-security-group \
--region $REGION \
--group-name omni-aws-sg \
--description "Security group for Omni EC2 instances" \
--query "GroupId" \
--output text)
echo $SECURITY_GROUP
Next, update the security group to allow all internal traffic within the same group. This allows Kubernetes applications running on different machines to communicate with each other:
aws ec2 authorize-security-group-ingress \
--region $REGION \
--group-id $SECURITY_GROUP \
--protocol all \
--port -1 \
--source-group $SECURITY_GROUP
Step 5: Register machines to your Omni account
Talos provides an official AWS AMI that you can use directly. However, if you need to customize the AMI, for example by adding custom labels or system extensions, you must create a custom Talos AMI and bake those customizations into the image.
If you plan to create a custom Talos AMI, skip this step and continue to Step 6.
The official Talos AWS AMI includes the ecr-credential-provider system extension by default.
To register AWS EC2 instances to your Omni account using the official Talos AMI, you must add a join config to the EC2 instance user data and boot the instance with the Talos Omni AMI. This ensures the machine automatically joins your Omni account when it starts.
To register your AWS EC2 instances:
- Define environment variables that specify the machines you want to register.
These are example values. Adjust them to match your machine specifications.
- Retrieve the official Talos AWS AMI:
AMI=$(curl -sL https://github.com/siderolabs/talos/releases/download/${TALOS_VERSION}/cloud-images.json \
| jq -r '.[] | select(.region == "'"$AWS_REGION"'") | select(.arch == "'"$ARCH"'") | .id')
echo "Using AMI: $AMI"
- Generate the join configuration. This configuration allows the Talos machines to register with Omni when they boot:
USER_DATA=$(omnictl jointoken machine-config)
- Launch the EC2 instances:
aws ec2 run-instances \
--region $AWS_REGION \
--image-id $AMI \
--instance-type $INSTANCE_TYPE \
--count $CONTROL_PLANE_NO \
--iam-instance-profile Name=$AUTOSCALER_INSTANCE_PROFILE_NAME \
--user-data "$USER_DATA" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=role,Value=autoscaler-controlplane-machine}]'
Step 6: Create a custom Talos AWS AMI
If you need to customize the Talos AMI (for example by adding custom labels or system extensions), you must build a custom image with those extensions included.
In this step, you will:
- Download the Talos AWS disk image from Omni
- Upload it to Amazon S3
- Import it into EC2 as a snapshot
- Register the snapshot as an AMI
6.1: Download the Talos AWS image
You can download the Talos AWS image from the CLI or the UI:
To download the Talos AWS image from the UI:
- Log into your Omni account.
- Go to the Overview page.
- Click Download Installation Media.
- Select AWS AMI (amd64) or AWS AMI (arm64) depending on your instance architecture.
- Add any required system extensions or labels.
- Click Download.
Run the following command to download the Talos AWS image:To see available options for adding custom labels or system extensions:omnictl download aws --help
The downloaded Talos AWS image will contain a compressed archive similar to:
Extract the archive:
tar -xzf aws-amd64.tar.gz
This command will produce a disk image similar to disk.raw:
6.2: Create S3 bucket
The disk image must be uploaded to an S3 bucket before it can be imported into EC2.
Bucket names must be globally unique. The following command creates a bucket with a globally unique name using a timestamp.
BUCKET="omni-aws-$(date +%s)"
aws s3api create-bucket \
--bucket $BUCKET \
--region $REGION \
--create-bucket-configuration LocationConstraint=$REGION
6.3: Upload the disk image to S3
Upload the extracted disk image to the S3 bucket:
aws s3 cp disk.raw s3://$BUCKET/omni-aws.raw
6.4: Import the disk image as an EC2 snapshot
Next, import the uploaded disk image into EC2 as a snapshot.
IMPORT_TASK=$(aws ec2 import-snapshot \
--region $REGION \
--description "Omni AWS" \
--disk-container "Format=raw,UserBucket={S3Bucket=$BUCKET,S3Key=omni-aws.raw}" \
--query "ImportTaskId" \
--output text)
echo $IMPORT_TASK
6.5: Monitor the snapshot import
You can check the status of the import task using:
aws ec2 describe-import-snapshot-tasks \
--region $REGION \
--import-task-ids $IMPORT_TASK
Once the import completes, retrieve the snapshot ID:
SNAPSHOT=$(aws ec2 describe-import-snapshot-tasks \
--region $REGION \
--import-task-ids $IMPORT_TASK \
--query "ImportSnapshotTasks[0].SnapshotTaskDetail.SnapshotId" \
--output text)
echo $SNAPSHOT
You will use this snapshot in the next step to register the AMI.
Step 7: Register the AMI
Create an AMI from the snapshot.
AMI_ID=$(aws ec2 register-image \
--region $REGION \
--block-device-mappings "DeviceName=/dev/xvda,Ebs={DeleteOnTermination=true,SnapshotId=$SNAPSHOT,VolumeSize=14,VolumeType=gp2}" \
--root-device-name /dev/xvda \
--virtualization-type hvm \
--architecture x86_64 \
--ena-support \
--name omni-aws-ami \
--query "ImageId" \
--output text)
echo $AMI_ID
Step 8: Launch EC2 instances
Finally, create EC2 instances using the AMI.
aws ec2 run-instances \
--region $REGION \
--image-id $AMI_ID \
--count 1 \
--instance-type t3.small \
--subnet-id $SUBNET_ID \
--security-group-ids $SECURITY_GROUP \
--associate-public-ip-address \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=omni-aws-ami}]"
Cleanup
If you no longer need the resources created in this guide, remove them to avoid unnecessary AWS charges.
Terminate the EC2 instance
First, terminate the EC2 instance created from the AMI.
You can find the instance ID with:
INSTANCE_ID=$(aws ec2 describe-instances \
--region $REGION \
--filters "Name=image-id,Values=$AMI_ID" \
--query "Reservations[*].Instances[*].InstanceId" \
--output text)
echo $INSTANCE_ID
Terminate the instance:
aws ec2 terminate-instances \
--region $REGION \
--instance-ids $INSTANCE_ID
Deregister the AMI
Next, deregister the AMI created earlier:
aws ec2 deregister-image \
--region $REGION \
--image-id $AMI_ID
Delete the snapshot
After deregistering the AMI, delete the snapshot used to create it:
aws ec2 delete-snapshot \
--region $REGION \
--snapshot-id $SNAPSHOT
Remove the disk image from S3
Delete the uploaded disk image:
aws s3 rm s3://$BUCKET/omni-aws.raw
Delete the S3 bucket
After removing the object, delete the bucket:
Delete the security group
Remove the security group created for the EC2 instances:
aws ec2 delete-security-group \
--region $REGION \
--group-id $SECURITY_GROUP
Delete the subnet
Finally, delete the subnet created earlier:
aws ec2 delete-subnet \
--region $REGION \
--subnet-id $SUBNET_ID