> ## Documentation Index
> Fetch the complete documentation index at: https://ona.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup AWS runner

Deploy your AWS Runner using CloudFormation. This guide walks through creating the runner in Ona, configuring the CloudFormation template, deploying, and verifying connectivity.

## Prerequisites

1. **AWS account** with permissions to deploy CloudFormation stacks and create IAM resources. See [detailed access requirements](/ona/runners/aws/detailed-access-requirements).
2. **Capacity planning** for instance types and concurrency. See [capacity planning](/ona/runners/aws/capacity-planning). Ensure sufficient EC2 service quotas.
3. **AMI allowlisting** if your organization restricts AMI usage. Allowlist owner account `995913728426` (AMI: `gitpod/images/gitpod-next/ec2-runner-ami-*`).
4. **VPC and subnets** in 2-3 availability zones. EC2 subnets for environment instances, load balancer subnets routable from your users' network. Review [networking](/ona/runners/aws/networking) to choose a connectivity option.
5. **Domain name** that you control with DNS modification capabilities.
6. **SSL/TLS certificate** in ACM with SANs for `yourdomain.com` and `*.yourdomain.com`.

## Create runner in Ona

1. In the Ona dashboard, go to **Settings > Runners** and click **Set up a new runner**
2. Select **AWS** as the provider
3. Enter a **name**, select the **AWS region**, and click **Create**

The dashboard generates a CloudFormation link with your **Runner ID**, **Exchange Token**, and **API Endpoint** pre-filled.

<Note>
  Runners are regional and can only launch environments in the AWS region they are deployed in. For multi-region support, set up multiple runners in different regions. The region cannot be changed after deployment.
</Note>

## CloudFormation template deployment

Ensure you are signed into the correct AWS account, then click **Open AWS CloudFormation** in the runner details page. This opens the AWS console with the template pre-loaded.

Most parameters are auto-filled. The template is organized into the parameter groups described below.

### Ona configuration

The Runner ID, Exchange Token, and API Endpoint are auto-generated. Do not modify these values.

| Parameter          | Description                                                                                                                                  | Required            |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| **Runner ID**      | Unique identifier for your runner                                                                                                            | ✅ Yes (auto-filled) |
| **Exchange Token** | Authentication token for the runner                                                                                                          | ✅ Yes (auto-filled) |
| **API Endpoint**   | Ona management plane API URL                                                                                                                 | ✅ Yes (auto-filled) |
| **Runner Size**    | Infrastructure size. Start with `small` for most deployments. Switch to `large` if you experience performance issues under heavy agent load. | ✅ Yes               |
| **Cache Engine**   | Data store for AI execution. `MemoryDB` (default) or `ElastiCache`. Use ElastiCache only if MemoryDB is unavailable in your region.          | ✅ Yes               |

### Network configuration

VPC and subnet settings for the runner and environments.

| Parameter                 | Description                                                                                                                                                                   | Example Value                  | Default | Required |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------- | -------- |
| **VPC**                   | The VPC where the runner will be deployed                                                                                                                                     | `vpc-12345abcd`                | N/A     | ✅ Yes    |
| **Availability Zones**    | AZs for high availability (select 2-3)                                                                                                                                        | `us-east-1a, us-east-1b`       | N/A     | ✅ Yes    |
| **EC2 Instances Subnet**  | Private subnets for EC2 environment instances. Should match the number of AZs.                                                                                                | `subnet-123abc, subnet-456def` | N/A     | ✅ Yes    |
| **Load Balancer Subnets** | Subnets for the load balancer, routable from your users' network. Should match the number of AZs.                                                                             | `subnet-123abc, subnet-456def` | N/A     | ✅ Yes    |
| **Assign Public IP**      | Assign a public IP address to the runner tasks. Set to `true` if using an Internet Gateway for outbound connectivity. Set to `false` if using a NAT gateway or VPC endpoints. | `true`                         | `false` | ✅ Yes    |

<Warning>
  If your runner subnets use an **internet gateway** for outbound connectivity (no NAT gateway, no VPC endpoints), you **must** set **Assign Public IP** to `true`. Without a public IP, the runner tasks will have no outbound connectivity and the runner will fail to start.
</Warning>

**Recommendations:**

* Select 2-3 Availability Zones for high availability
* **EC2 subnets**: use private subnets sized for your expected workload
* **Load balancer subnets**: must have CIDR ranges routable from your users' network
* Ensure connectivity from user locations via VPN, Direct Connect, or Transit Gateway

### DNS configuration

Domain name, SSL certificate, and load balancer visibility.

| Parameter                    | Description                          | Example Value                                              | Required |
| ---------------------------- | ------------------------------------ | ---------------------------------------------------------- | -------- |
| **Load Balancer Visibility** | `internal` or `internet-facing`      | `internal`                                                 | ✅ Yes    |
| **Domain Name**              | Your domain name for runner access   | `yourdomain.com`                                           | ✅ Yes    |
| **Certificate ARN**          | ARN of your SSL certificate from ACM | `arn:aws:acm:us-east-1:123456789012:certificate/abc123...` | ✅ Yes    |

**Load balancer visibility options:**

* **internal**: load balancer is only accessible from within your VPC (recommended for private deployments)
* **internet-facing**: load balancer is accessible from the public internet (requires public subnets)

### Advanced configuration

The settings below are for organizations with additional network or security requirements. Most deployments do not need these.

#### Load balancer ingress control

| Parameter                 | Description                                                                                     | Example Value  |
| ------------------------- | ----------------------------------------------------------------------------------------------- | -------------- |
| **Custom Security Group** | Security group to attach to the load balancer. Must allow incoming traffic on port 443 (HTTPS). | `sg-abcdef123` |

By default, the CloudFormation template creates a security group that allows all traffic (`0.0.0.0/0`) to ports 80 and 443 on the load balancer. To restrict ingress to specific source IP ranges or security groups, provide your own security group.

#### HTTP proxy configuration

For environments behind corporate firewalls or proxies:

| Parameter       | Description                                   | Example Value                                           |
| --------------- | --------------------------------------------- | ------------------------------------------------------- |
| **HTTP Proxy**  | HTTP proxy server URL                         | `http://proxy.company.com:8080`                         |
| **HTTPS Proxy** | HTTPS proxy server URL                        | `https://proxy.company.com:8080`                        |
| **All Proxy**   | All-protocol proxy server URL                 | `http://proxy.company.com:8080`                         |
| **No Proxy**    | Comma-separated list of hosts to bypass proxy | `.internal,169.254.0.0/16,app.gitpod.io,.amazonaws.com` |

When configuring a proxy, `No Proxy` must include at minimum: `.internal`, `169.254.0.0/16`, `app.gitpod.io`, and `.amazonaws.com`.

**When proxy changes take effect:**

* **Runner infrastructure**: immediately after CloudFormation update
* **Content initialization**: after environment restart
* **Devcontainer**: after rebuild
* **Docker in Docker**: after container recreation

#### Custom CA certificate

If your network uses a corporate proxy or internal services with certificates signed by a private Certificate Authority, configure the runner to trust your CA.

| Parameter                  | Description                                                                                   | Example Value                            |
| -------------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------- |
| **Custom CA Trust Bundle** | PEM-encoded CA certificate bundle, provided as an S3 URL, HTTPS URL, or SSM dynamic reference | `s3://gitpod-myorg/shared/ca-bundle.pem` |

<Warning>
  Custom CA certificates work in runner, content init (SCM), and docker pull operations. However, they are **not supported** in devcontainer and devcontainer image build phases. You must add CA certificates to your images for these use cases.
</Warning>

<Note>
  This is commonly needed alongside [HTTP proxy configuration](#http-proxy-configuration) when the proxy performs TLS inspection with a corporate CA.
</Note>

There are three ways to provide the certificate:

**1. Store the certificate in an S3 bucket (recommended)**

This avoids the EC2 user data size limit and is the recommended approach for bundles with multiple certificates.

1. Create an S3 bucket with a name starting with `gitpod-` (e.g. `gitpod-myorg`)
2. Upload your `.pem` file to the bucket (e.g. `s3://gitpod-myorg/shared/ca-bundle.pem`)
   ```
   s3://gitpod-myorg/shared/ca-bundle.pem
   ```
3. Ensure the bucket is accessible by the runner's IAM role (buckets prefixed with `gitpod-` are allowed by default)
4. Set the `CustomCATrustBundle` parameter to the S3 URL

**2. Reference the certificate from an HTTPS endpoint**

If your CA bundle is hosted on an internal web server accessible from the runner's VPC, provide the URL directly:

```
https://internal-pki.example.com/ca-bundle.pem
```

**3. Store the certificate in SSM Parameter Store**

Use CloudFormation dynamic references to retrieve certificates from AWS SSM Parameter Store. For syntax details, see [SSM Parameter Store](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references-ssm.html) documentation.

```
{{resolve:ssm:/ona/ca-cert}}
```

<Warning>
  Use an S3 URL if your CA bundle contains multiple certificates. SSM dynamic references embed the full certificate into EC2 user data, which has a 16 KB limit, and can fail with `"User data is limited to 16384 bytes"`. See [Custom CA certificate troubleshooting](/ona/runners/aws/troubleshooting-runners#custom-ca-certificate-issues) for related issues.
</Warning>

## Deploy

1. Review all parameters
2. Check the box acknowledging CloudFormation will create IAM resources
3. Click **Create stack**

<Info>Deployment typically takes 20-25 minutes. Monitor progress in the CloudFormation **Events** tab.</Info>

## Configure DNS

After deployment, get the load balancer DNS name from the CloudFormation **Outputs** tab (look for **LoadBalancerDNS**).

Create DNS records pointing to this value for both the root domain and wildcard.

### Route 53

Create alias records pointing to your Network Load Balancer:

| Type  | Name               | Alias Target                                  |
| ----- | ------------------ | --------------------------------------------- |
| **A** | `yourdomain.com`   | Alias to Network Load Balancer in your region |
| **A** | `*.yourdomain.com` | Alias to Network Load Balancer in your region |

### Other DNS providers

Create CNAME records pointing to your load balancer DNS:

| Type  | Name               | Value                                                         | TTL |
| ----- | ------------------ | ------------------------------------------------------------- | --- |
| CNAME | `yourdomain.com`   | `internal-LoadBa-XXXXX-123456789.us-east-1.elb.amazonaws.com` | 300 |
| CNAME | `*.yourdomain.com` | `internal-LoadBa-XXXXX-123456789.us-east-1.elb.amazonaws.com` | 300 |

DNS changes typically propagate within 5-60 minutes.

## Verify deployment

Once DNS propagates, verify the runner is healthy:

```bash theme={null}
curl -k https://yourdomain.com/_health
nslookup yourdomain.com
```

Check the runner status in the Ona dashboard under **Settings > Runners** to confirm it shows as connected.

## Next steps

* [Configure repository access](/ona/runners/configuring-repository-access) - Set up access to your Git repositories
* [Environment classes](/ona/runners/aws/environment-classes) - Configure compute resources for environments
* [Dev container image cache](/ona/runners/devcontainer-image-cache) - Speed up environment starts
* [Troubleshooting](/ona/runners/aws/troubleshooting-runners) - Common problems and diagnostic steps
