Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions reference-architectures/nat-gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# NAT Gateway for DOKS and Droplet

Note: This RA is currently a WIP.

## Overview
This RA demonstrates a simple, reproducible pattern for making all egress traffic originate from a single static IP via NAT, for both cluster workloads and a non-Kubernetes host(droplet).
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#cloud-config
# Route Droplet egress through NAT Gateway while preserving access to DigitalOcean metadata endpoint.
package_update: false
package_upgrade: false

write_files:
- path: /etc/netplan/99-natgw.yaml
permissions: '0644'
content: |
network:
version: 2
ethernets:
eth0:
routes:
- to: 169.254.169.254/32
via: ${original_gateway}
eth1:
routes:
- to: 0.0.0.0/0
via: ${nat_gateway_gateway_ip}

runcmd:
- original_gw=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/gateway)
- ip route add 169.254.169.254 via $original_gw dev eth0 || true
- ip route replace default via ${nat_gateway_gateway_ip}
- netplan apply || true
63 changes: 63 additions & 0 deletions reference-architectures/nat-gateway/terraform/1-infra/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
terraform {
required_version = "~> 1.0"
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
provider "digitalocean"{
token = var.do_token
}

# Resource 1: VPC
resource "digitalocean_vpc" "ra-nat-gateway-vpc" {
name = "ra-nat-gateway-vpc"
region = var.region
ip_range = "192.168.44.0/24"
}

# Resource 2: NAT Gateway
resource "digitalocean_vpc_nat_gateway" "this" {
name = var.nat_gateway_name
type = "PUBLIC"
region = var.region
size = 1
vpcs {
vpc_uuid = digitalocean_vpc.ra-nat-gateway-vpc.id
}
}

locals {
nat_gateway_ip = tolist(digitalocean_vpc_nat_gateway.this.vpcs)[0].gateway_ip
cloud_config = templatefile("${path.module}/cloud-config.yaml", {
original_gateway = "192.168.44.1"
nat_gateway_gateway_ip = local.nat_gateway_ip
})
}

# Resource 3: Droplet(non K8 host)
resource "digitalocean_droplet" "non-k8-host-droplet" {
image = var.droplet_image
size = var.droplet_size
name = "non-k8-host-droplet"
vpc_uuid = digitalocean_vpc.ra-nat-gateway-vpc.id
user_data = local.cloud_config
depends_on = [digitalocean_vpc_nat_gateway.this]
}

# Resource 4: K8 cluster
resource "digitalocean_kubernetes_cluster" "k8-cluster" {
name = "k8-cluster"
region = var.region
version = "latest"
routing_agent {
enabled = true
}
node_pool {
name = "worker-pool"
size = "s-2vcpu-2gb"
node_count = var.node_count
}
}
28 changes: 28 additions & 0 deletions reference-architectures/nat-gateway/terraform/1-infra/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
variable do_token {}

variable region {
type = string
default = "blr1"
}

variable "nat_gateway_name" {
type = string
default = "nat-gateway"
}

# Resource 3: Droplet(non K8 host) related
variable "droplet_image" {
type = string
default = "ubuntu-24-04-x64"
}

variable "droplet_size" {
type = string
default = "s-1vcpu-512mb-10gb"
}

# Resource 4: K8 cluster related
variable "node_count" {
type = number
default = 2
}