Skip to content

Amazon Web Services (AWS)

Arrow produces a stream-optimized VMDK image for AWS. The import process uses import-snapshot (not import-image) to support custom Linux kernels.

Each Arrow AWS build produces a ZIP package containing:

  • The disk image (.vmdk)
  • Deployment instructions (text file)
  • An automated import script (bash for macOS/Linux, PowerShell for Windows)

ToolInstall Link
AWS CLI (aws)Install AWS CLI

Configure your credentials:

Terminal window
aws configure

Required IAM permissions:

  • s3:PutObject, s3:GetObject, s3:ListBucket
  • ec2:ImportSnapshot, ec2:DescribeImportSnapshotTasks
  • ec2:RegisterImage, ec2:RunInstances, ec2:Describe*
  • iam:CreateRole, iam:PutRolePolicy (for vmimport role setup)

Extract the ZIP and run the import script:

Terminal window
unzip kali-arrow-client-aws-*.zip
cd kali-arrow-client-aws-*/
chmod +x import-to-aws.sh
Terminal window
./import-to-aws.sh

The script will:

  1. S3 Upload — Upload VMDK to your S3 bucket (checks for existing file first)
  2. IAM Role — Create the vmimport service role if it doesn’t exist
  3. Snapshot Import — Import the VMDK as an EBS snapshot with live progress bar
  4. AMI Registration — Register an AMI from the snapshot (UEFI, ENA-enabled, gp3 volume)
  5. Instance Launch — Optionally launch an EC2 instance with interactive VPC, subnet, security group, key pair, and instance type selection
  6. Cleanup — Optionally remove the VMDK from S3
Terminal window
# Interactive — lists available Arrow AMIs
./import-to-aws.sh --launch
# Specify AMI ID directly
./import-to-aws.sh --launch ami-0123456789abcdef0
Terminal window
./import-to-aws.sh --cleanup

Scans for and offers to delete:

  • Arrow AMIs and associated EBS snapshots
  • The vmimport IAM role and policies

Terminal window
# Extract the ZIP
Expand-Archive kali-arrow-client-aws-*.zip -DestinationPath .\aws-import
# Run the script
cd aws-import
.\Import-To-AWS.ps1

Same modes are available:

Terminal window
# Import (default)
.\Import-To-AWS.ps1
# Launch an instance
.\Import-To-AWS.ps1 -Launch
# Launch from a specific AMI
.\Import-To-AWS.ps1 -Launch -AmiId "ami-0123456789abcdef0"
# Cleanup all Arrow resources
.\Import-To-AWS.ps1 -Cleanup

Terminal window
aws s3 cp kali-arrow-client-aws.vmdk s3://<your-bucket>/vm-imports/

Step 2: Create the vmimport IAM Role (one-time setup)

Section titled “Step 2: Create the vmimport IAM Role (one-time setup)”

Create trust-policy.json:

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "vmie.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"sts:Externalid": "vmimport"}
}
}]
}

Create the role:

Terminal window
aws iam create-role --role-name vmimport \
--assume-role-policy-document file://trust-policy.json

Create role-policy.json (replace <your-bucket>):

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject",
"s3:GetBucketAcl"
],
"Resource": [
"arn:aws:s3:::<your-bucket>",
"arn:aws:s3:::<your-bucket>/*"
]
}, {
"Effect": "Allow",
"Action": [
"ec2:ModifySnapshotAttribute",
"ec2:CopySnapshot",
"ec2:RegisterImage",
"ec2:Describe*",
"ec2:ImportSnapshot"
],
"Resource": "*"
}]
}

Attach the policy:

Terminal window
aws iam put-role-policy --role-name vmimport \
--policy-name vmimport \
--policy-document file://role-policy.json
Terminal window
aws ec2 import-snapshot \
--description "Arrow VM Image" \
--disk-container '{
"Description": "Arrow VM Image",
"Format": "vmdk",
"UserBucket": {
"S3Bucket": "<your-bucket>",
"S3Key": "vm-imports/kali-arrow-client-aws.vmdk"
}
}'

Monitor progress:

Terminal window
aws ec2 describe-import-snapshot-tasks \
--import-task-ids import-snap-xxxxxxxxx

Once the snapshot import completes, note the SnapshotId and register the AMI:

Terminal window
aws ec2 register-image \
--name "kali-arrow-client" \
--description "Arrow VM Image" \
--architecture x86_64 \
--root-device-name /dev/sda1 \
--boot-mode uefi \
--ena-support \
--block-device-mappings '[{
"DeviceName": "/dev/sda1",
"Ebs": {
"SnapshotId": "snap-xxxxxxxxx",
"VolumeType": "gp3",
"DeleteOnTermination": true
}
}]' \
--virtualization-type hvm
Terminal window
aws ec2 run-instances \
--image-id ami-xxxxxxxxx \
--instance-type t3.xlarge \
--key-name <key-pair> \
--security-group-ids <sg-id> \
--subnet-id <subnet-id> \
--count 1

TypevCPURAMUse Case
t3.large28 GBMinimum
t3.xlarge416 GBRecommended
m5.2xlarge832 GBHigh performance

IssueSolution
import-image fails with kernel errorArrow uses import-snapshot instead, which bypasses kernel checks. Use the provided script.
Snapshot import stuck at 0%Wait 5-10 minutes — AWS sometimes takes time before showing progress
AMI shows “pending”AMI registration can take a few minutes. Use aws ec2 wait image-available --image-ids ami-xxx
Instance won’t bootEnsure the AMI was registered with --boot-mode uefi and --ena-support
Can’t SSH into the instanceEnsure the security group allows inbound port 22
Desktop doesn’t loadArrow VMs include noVNC — connect on port 6901 if configured
Password doesn’t workCredentials are generated at build time. Retrieve them from the ARROW Portal under your device’s details page.