# Migrate from AWS VPC to Quake AI

Source: https://docs.quake.ai/docs/network/migration/migrate-from-aws-vpc
Markdown: https://docs.quake.ai/docs/network/migration/migrate-from-aws-vpc.md

---

# Migrate from AWS VPC to Quake AI

AWS VPC exposes more networking primitives than the other major cloud providers, so it has the largest gap to bridge when migrating to Quake AI. The core shift: AWS layers subnets, an Internet Gateway, NAT Gateways, route tables, and NACLs into a multi-component stack. On Quake AI, the Network service ([OpenStack Neutron](/resources/migration/openstack)) composes three objects: a **network**, a **subnet**, and a **router**. The router replaces both the Internet Gateway and NAT Gateway in a single resource.

## Service mapping

<MigrationTable provider="aws" service="network" />


## Prerequisites

- A Quake AI account with [application credentials](/docs/tools/generate-app-credentials)
- The [OpenStack CLI](/docs/tools/install-openstack-client) installed and configured
- An inventory of your AWS VPC resources: subnets, security groups, NACLs, Elastic IPs, load balancers, and Route 53 zones
- An SSH key pair imported to Quake AI (run `openstack keypair create` with `--public-key`)

## Topology mapping

The AWS public-subnet/IGW/NACL stack collapses into a single Neutron router with an external gateway. NACLs are dropped entirely. Security groups map closely.

<Figure caption="AWS VPC components map to a single Neutron router plus tenant network with security groups and floating IPs">

```d2
direction: down

aws: AWS VPC {
  igw: Internet Gateway {shape: cloud}
  public: Public Subnet
  private: Private Subnet
  nat: NAT Gateway
  nacl: NACL
  eip: Elastic IP
  sg: Security Group
  igw -> public
  public -> nat
  nat -> private
  eip -> public
  nacl -> public: subnet-level
  sg -> public: instance-level
}

neutron: Quake AI Neutron {
  router: Router (gateway + SNAT)
  network: Tenant Network
  subnet: Subnet
  fip: Floating IP
  sg: Security Group
  router -> network
  network -> subnet
  fip -> network
  sg -> network: port-level
}

aws -> neutron: maps to
```

</Figure>

| AWS concept | Neutron equivalent | Notes |
|---|---|---|
| VPC | Network (project scope) | No strict regional boundary in Neutron; region is a deployment choice |
| Subnet (public) | Subnet on tenant network + floating IP | Floating IP provides public access |
| Subnet (private) | Subnet on tenant network | Standard model |
| Internet Gateway | Router external gateway | Implicit when you create a router with an external network |
| NAT Gateway | Router (SNAT) | Router provides outbound SNAT automatically; no separate object or charge |
| Route Table | Router static routes | `openstack router add route` for custom entries |
| NACL | **No equivalent** | Absorb allow rules into security groups; see below |
| Security Group | Security Group | Same operating model: both stateful, allow-only, per-instance |
| Elastic IP | Floating IP | Region-scoped, re-assignable; one per port |
| ENI | Port | Virtual NIC; security groups bind to ports |
| VPC Peering | **No equivalent** | No network peering on Quake AI |
| Transit Gateway | **No equivalent** | No multi-VPC routing hub |
| VPC Endpoint | **No equivalent** | No PrivateLink-style internal service access |

### Set up the Neutron equivalent

Create the network, subnet, and router that replace your VPC stack:

```bash
openstack network create MY_NETWORK

openstack subnet create MY_SUBNET \
  --network MY_NETWORK \
  --subnet-range 10.0.0.0/24 \
  --gateway 10.0.0.1 \
  --dns-nameserver 8.8.8.8

openstack router create MY_ROUTER
openstack router set MY_ROUTER --external-gateway PublicStatic
openstack router add subnet MY_ROUTER MY_SUBNET
```

This single router replaces your Internet Gateway (inbound through floating IPs), NAT Gateway (outbound through SNAT), and route tables (default route through the router).

## Security rule translation

AWS has two firewall layers: Security Groups (stateful, allow-only, per-ENI) and NACLs (stateless, allow+deny, per-subnet). Neutron has one layer: Security Groups (stateful, allow-only, per-port).

| Dimension | AWS Security Groups | AWS NACLs | Neutron Security Groups |
|---|---|---|---|
| Enforcement level | Instance (ENI) | Subnet | Port |
| Statefulness | Stateful | Stateless | Stateful |
| Rule model | Allow-only | Allow and deny | Allow-only |
| Evaluation | All rules additive | Ordered by rule number | All rules additive |
| Source types | CIDR, Security Group ID | CIDR only | CIDR, Security Group ID |
| Default inbound | Deny-all | Allow-all (default NACL only; custom NACLs start with no rules, effectively deny-all) | Deny-all |

### Translating NACLs

NACLs have no Neutron equivalent. For most deployments, the migration approach is:

1. **Convert NACL allow rules to security group rules.** Any traffic your NACLs explicitly allowed that your security groups do not already cover needs a new SG rule.
2. **Drop NACL deny rules.** Neutron's default deny-all ingress achieves the same effect. If a NACL denied traffic that a broad SG allow rule would permit (e.g., deny 10.0.0.0/8 within a 0.0.0.0/0 allow), split the SG allow into specific non-overlapping CIDRs.
3. **Accept single-layer security.** Neutron security groups are functionally comparable to AWS SGs. The NACL layer is an AWS-specific defense-in-depth measure that many deployments do not rely on.

### 3-tier app example

**AWS source:**
- NACL on public subnet: allow HTTP/HTTPS from internet, deny RFC 1918
- `web-sg`: inbound TCP 80, 443 from `0.0.0.0/0`
- `app-sg`: inbound TCP 8080 from `web-sg`
- `db-sg`: inbound TCP 5432 from `app-sg`

**Neutron target:**

```bash
openstack security group create MY_SG_WEB
openstack security group rule create MY_SG_WEB \
  --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 --ingress
openstack security group rule create MY_SG_WEB \
  --protocol tcp --dst-port 443 --remote-ip 0.0.0.0/0 --ingress

openstack security group create MY_SG_APP
openstack security group rule create MY_SG_APP \
  --protocol tcp --dst-port 8080 --remote-group MY_SG_WEB --ingress

openstack security group create MY_SG_DB
openstack security group rule create MY_SG_DB \
  --protocol tcp --dst-port 5432 --remote-group MY_SG_APP --ingress
```

You drop the NACLs. The NACL that denied RFC 1918 to the public subnet is unnecessary because Neutron does not route non-addressed traffic to your instances. You replace the NACL that denied port 3389/RDP from the internet by omitting an allow rule for port 3389 on `MY_SG_WEB`.



AWS SGs reference other SGs by ID. Neutron SGs use the same pattern with `--remote-group`. Apply `MY_SG_WEB` to all web tier ports, `MY_SG_APP` to all app tier ports, and `MY_SG_DB` to all database tier ports.



## Load balancer migration

Replace an AWS load balancer with a reverse proxy that you operate, or with an external edge service.

| AWS source | Quake AI migration pattern |
|---|---|
| Application Load Balancer | HAProxy, Nginx, Caddy, Traefik, or Envoy on a Compute instance |
| Network Load Balancer | HAProxy or Nginx stream proxy on a Compute instance |
| AWS WAF on ALB | External CDN/WAF in front of the Quake AI origin |
| Global Accelerator or cross-region routing | External DNS traffic manager or CDN |

Assign a floating IP to the proxy instance and keep application instances on a private network. Configure health checks and backend pools in the proxy. Install certificates on the proxy with Certbot or let Caddy manage ACME issuance and renewal.

## Floating IP setup

| AWS Elastic IP | Neutron Floating IP |
|---|---|
| Allocated to account, assigned to ENI | Allocated to project, assigned to port |
| Public IPv4 addresses are billed hourly since Feb 2024, whether attached, idle, or ephemeral; the first attached EIP was free before that change. See [AWS IPv4 pricing](https://aws.amazon.com/vpc/pricing/). | Included in Quake AI instance pricing |
| Can attach to secondary ENI IPs | One floating IP per port |
| IPv6 supported | IPv6 not documented on Quake AI |

Allocate and associate a floating IP:

```bash
openstack floating ip create PublicStatic
openstack server add floating ip MY_INSTANCE FLOATING_IP_ADDRESS
```



AWS allows multiple EIPs per instance using secondary private IPs and multiple ENIs. Neutron supports one floating IP per port. For multiple public IPs per instance, create multiple ports with a floating IP on each.



## DNS cutover

Quake AI has no managed DNS service. Route 53 must be replaced by an external provider (Cloudflare, NS1, self-hosted BIND).

1. **Lower TTLs**: 24-48 hours before cutover, reduce all record TTLs to 60-300 seconds. The NS record TTL (typically 172,800 seconds) must be reduced first; wait the full TTL period before continuing.
2. **Export records**: Use the AWS Console or CLI to export the hosted zone.
3. **Translate alias records**: Route 53 alias records (A records pointing to ELB, CloudFront) have no standard DNS equivalent. Create standard `A` or `CNAME` records that point to the reverse proxy floating IP or external edge hostname.
4. **Import at new provider**: Most DNS providers accept BIND zone file imports or Terraform configuration.
5. **Validate**: `dig @NEW_NAMESERVER example.com A`
6. **Update registrar NS records**: This step completes the cutover. DNS propagation takes up to 48 hours globally.
7. **Monitor for 48 hours**: Keep the Route 53 zone active during monitoring; rollback by reverting registrar NS records.
8. **Restore TTLs**: Raise TTLs to 3600-86400 after successful cutover.



Route 53 features with no standard DNS equivalent: alias records, weighted routing, latency-based routing, failover routing, and health-check-based routing. Replace weighted/latency routing at the CDN or application layer. Replace health-check routing with external synthetic monitoring and dynamic DNS API automation.



## Validation checklist

After completing the migration, verify:

- [ ] Neutron network, subnet, and router are operational (`openstack router show MY_ROUTER`)
- [ ] Security group rules match your AWS SG rules (compare rule counts and port/CIDR combinations)
- [ ] NACL intent is covered by security group rules (no implicit allow gaps)
- [ ] Floating IPs are associated with the correct instance ports
- [ ] Reverse proxy health checks pass for application backends
- [ ] TLS termination works on the reverse proxy or external edge
- [ ] DNS records resolve to the correct Quake AI floating IP or external edge hostname
- [ ] Applications respond correctly through the full network path
- [ ] Egress traffic routes through the router (test outbound connectivity from instances)

## Provider-specific gotchas

| Topic | Detail |
|---|---|
| Egress pricing cliff | AWS bills egress per-GB after a small free allowance, and NAT Gateway adds both an hourly and a per-GB charge. Quake AI includes bandwidth in flavor pricing. See [AWS pricing](https://aws.amazon.com/pricing/). |
| No Availability Zones | AWS multi-AZ subnet strategies do not apply. Quake AI uses regions, not AZs. HA requires multi-region deployment with application-layer or DNS-level failover. |
| VPC Endpoints / PrivateLink | No equivalent. Workloads that used VPC Endpoints for S3 or other AWS services will use direct internet egress after migration. |
| NLB static IPs | Assign a floating IP to the reverse proxy instance and communicate the new address to downstream IP-allowlisting partners. |
| EKS/ECS network integration | AWS container networking uses VPC CNI (pod IPs from VPC CIDR). Kubernetes on Quake AI uses flannel/Calico/OVN-Kubernetes CNI as an overlay on Neutron networks. |
| Security Group limits | AWS defaults to 5 security groups per network interface, adjustable to a maximum of 16. On Neutron, the security-groups-per-port limit is set by the operator; confirm the value for your project before migrating. |

## See also

- [Migrating from AWS to Quake AI](/resources/migration/from-aws): full cross-service migration hub
- [Coming from AWS](/resources/migration/coming-from-aws): concept translation reference
- [Migrate from EC2 to Quake AI Compute](/docs/compute/migration/migrate-from-ec2): compute workload migration
- [Network migration guides](/docs/network/migration): all provider guides
- [Edge reverse proxy template](/resources/iac-templates/edge-reverse-proxy): deploy a self-managed traffic entry point
