Skip to main content
Airship authenticates to AWS as an IAM user with a long-lived access key, and launches one EC2 instance per job.

The IAM policy

Attach AmazonEC2FullAccess. In an account dedicated to CI this is a perfectly defensible end state.
If your account sets a default EBS encryption key of its own — not the AWS-managed aws/ebs key — the user also needs kms:CreateGrant, kms:Decrypt and kms:GenerateDataKeyWithoutPlaintext on that key. Root volumes are always encrypted, so this is not optional.

The network

The default path needs a default VPC in each region you use. Airship launches into its default subnets, rotating availability zones per runner so one zone running out of capacity does not fail the job.
Empty? Either create one, or point Airship at your own subnet per definition:
A private subnet works and needs no inbound anything, but it does need a route out — the machine downloads actions/runner and talks to GitHub. See Networking for the destination list, and for the S3 gateway endpoint that pays for itself with caching on. Airship opens no inbound ports, ever. The security group it creates has no ingress rules, there is no SSH key, and IMDSv2 is required with a hop limit of 1 so a process inside a container cannot reach instance metadata.

Quotas to check

Also worth a look: EBS storage quotas per region, and GPU quotas, which are usually zero until you request an increase.

Connect it

Open Cloud → AWS, paste the access key ID and secret, and choose the default region. Airship verifies the key with sts:GetCallerIdentity before storing it, and shows you the account ID and principal ARN. Or from the developer API:

AWS settings

Set these under extra_config: machine_image takes an AMI ID, or ubuntu2204 / ubuntu2404 for Canonical’s newest image for the architecture. instance_type takes any EC2 instance type; Graviton families are detected as arm64 automatically.
airship.yaml

Verify and audit

Untagged instances are not Airship’s. Tagged ones with no live runner are terminated by the next inventory pass.

Group the bill by repository

Cost Explorer grouped by the airship:repository tag needs no extra instrumentation.

A cheap tripwire

A CloudTrail alarm on RunInstances, TerminateInstances and GetFederationToken by the Airship user.

Turning it off

Launch failures and their AWS messages are in Troubleshooting.