TheArchitect

NAT Instance (cheap NAT for dev/test)

AWS architecture template · A t3.nano EC2 NAT instance costs ~$3.80/mo vs NAT Gateway ~$32+/mo. Valid for dev/test VPCs with low egress. Not HA — use NAT Gateway for production.

NAT Instance (cheap NAT for dev/test) is a free AWS architecture template built with EC2 and CloudWatch. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.

Public Subnet 10.0.1.0/24Private Subnet 10.0.11.0/24Dev/Test VPC 10.0.0.0/16NAT Instance (…App Server (pr…NAT CPU Alarm
NAT Instance (cheap NAT for dev/test) architecture diagram

AWS services in this template

  • EC2×2
  • CloudWatch

Deployment notes

Needs input

  • Set source/destination check to DISABLED on the NAT instance after launch.
  • Update private subnet route table: 0.0.0.0/0 → nat-instance-id (not an IGW or NAT GW).
  • Not HA by default — single point of failure. For production, use NAT Gateway per AZ instead.
  • Cost: t3.nano ~$3.80/mo + data transfer. NAT Gateway: $0.045/hr (~$32/mo) + $0.045/GB processed.

Generated CloudFormation — 33 resources

Logical IDResource type
DevTestVPC1000016vpcAWS::EC2::VPC
DevTestVPC1000016vpcedgewebsgSecurityGroupAWS::EC2::SecurityGroup
DevTestVPC1000016vpcappruntimesgSecurityGroupAWS::EC2::SecurityGroup
DevTestVPC1000016vpcappruntimesgSecurityGroupIngressRuleAWS::EC2::SecurityGroupIngress
DevTestVPC1000016vpcworkersgSecurityGroupAWS::EC2::SecurityGroup
DevTestVPC1000016vpcdatastoresgSecurityGroupAWS::EC2::SecurityGroup
DevTestVPC1000016vpcdatastoresgSecurityGroupIngressRuleAWS::EC2::SecurityGroupIngress
DevTestVPC1000016vpccontrolplanesgSecurityGroupAWS::EC2::SecurityGroup
DevTestVPC1000016vpcPublicSubnet1AWS::EC2::Subnet
DevTestVPC1000016vpcPublicSubnet2AWS::EC2::Subnet
DevTestVPC1000016vpcPrivateSubnet1AWS::EC2::Subnet
DevTestVPC1000016vpcPrivateSubnet2AWS::EC2::Subnet
DevTestVPC1000016vpcPrivateSubnet3AWS::EC2::Subnet
DevTestVPC1000016vpcPrivateSubnet4AWS::EC2::Subnet
DevTestVPC1000016vpcInternetGatewayAWS::EC2::InternetGateway
DevTestVPC1000016vpcGatewayAttachmentAWS::EC2::VPCGatewayAttachment
DevTestVPC1000016vpcPublicRouteTableAWS::EC2::RouteTable
DevTestVPC1000016vpcPublicRouteAWS::EC2::Route
DevTestVPC1000016vpcPublicSubnet1RTAAWS::EC2::SubnetRouteTableAssociation
DevTestVPC1000016vpcPublicSubnet2RTAAWS::EC2::SubnetRouteTableAssociation
DevTestVPC1000016vpcNatEIPAWS::EC2::EIP
DevTestVPC1000016vpcNatGatewayAWS::EC2::NatGateway
DevTestVPC1000016vpcPrivateRouteTableAWS::EC2::RouteTable
DevTestVPC1000016vpcPrivateRouteAWS::EC2::Route
DevTestVPC1000016vpcPrivateSubnet1RTAAWS::EC2::SubnetRouteTableAssociation
DevTestVPC1000016vpcPrivateSubnet2RTAAWS::EC2::SubnetRouteTableAssociation
DevTestVPC1000016vpcPrivateSubnet3RTAAWS::EC2::SubnetRouteTableAssociation
DevTestVPC1000016vpcPrivateSubnet4RTAAWS::EC2::SubnetRouteTableAssociation
PublicSubnet1001024subnetAWS::EC2::Subnet
PrivateSubnet10011024subnetAWS::EC2::Subnet
NATInstancet3nanoec2AWS::EC2::Instance
AppServerprivateec2AWS::EC2::Instance
NATCPUAlarmcloudwatchAWS::CloudWatch::Alarm
View the full CloudFormation template
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
  "Resources": {
    "DevTestVPC1000016vpc": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.0.0.0/16",
        "EnableDnsHostnames": true,
        "EnableDnsSupport": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-nat-vpc"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcedgewebsgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "edge-web-sg",
        "GroupDescription": "Allow HTTPS from the internet to public load balancers",
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edge-web-sg"
          }
        ],
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 443,
            "ToPort": 443,
            "CidrIp": "0.0.0.0/0"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcappruntimesgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "app-runtime-sg",
        "GroupDescription": "Allow application traffic from the edge tier",
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "app-runtime-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcappruntimesgSecurityGroupIngressRule": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {
          "Ref": "DevTestVPC1000016vpcappruntimesgSecurityGroup"
        },
        "IpProtocol": "tcp",
        "FromPort": 80,
        "ToPort": 80,
        "SourceSecurityGroupId": {
          "Ref": "DevTestVPC1000016vpcedgewebsgSecurityGroup"
        }
      }
    },
    "DevTestVPC1000016vpcworkersgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "worker-sg",
        "GroupDescription": "Private worker runtime egress only",
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "worker-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcdatastoresgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "data-store-sg",
        "GroupDescription": "Allow PostgreSQL from application runtimes",
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "data-store-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcdatastoresgSecurityGroupIngressRule": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {
          "Ref": "DevTestVPC1000016vpcdatastoresgSecurityGroup"
        },
        "IpProtocol": "tcp",
        "FromPort": 5432,
        "ToPort": 5432,
        "SourceSecurityGroupId": {
          "Ref": "DevTestVPC1000016vpcappruntimesgSecurityGroup"
        }
      }
    },
    "DevTestVPC1000016vpccontrolplanesgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "control-plane-sg",
        "GroupDescription": "Private EKS control plane attachment group",
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "control-plane-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPublicSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.1.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "public-edge-a"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPublicSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.2.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "public-edge-b"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.11.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-app-a"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.12.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-app-b"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet3": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.21.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-data-a"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet4": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "CidrBlock": "10.10.22.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-data-b"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcInternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-nat-vpc-igw"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "InternetGatewayId": {
          "Ref": "DevTestVPC1000016vpcInternetGateway"
        }
      }
    },
    "DevTestVPC1000016vpcPublicRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-nat-vpc-public-rt"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPublicRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": [
        "DevTestVPC1000016vpcGatewayAttachment"
      ],
      "Properties": {
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPublicRouteTable"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {
          "Ref": "DevTestVPC1000016vpcInternetGateway"
        }
      }
    },
    "DevTestVPC1000016vpcPublicSubnet1RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPublicSubnet1"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPublicRouteTable"
        }
      }
    },
    "DevTestVPC1000016vpcPublicSubnet2RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPublicSubnet2"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPublicRouteTable"
        }
      }
    },
    "DevTestVPC1000016vpcNatEIP": {
      "Type": "AWS::EC2::EIP",
      "DependsOn": [
        "DevTestVPC1000016vpcGatewayAttachment"
      ],
      "Properties": {
        "Domain": "vpc"
      }
    },
    "DevTestVPC1000016vpcNatGateway": {
      "Type": "AWS::EC2::NatGateway",
      "Properties": {
        "AllocationId": {
          "Fn::GetAtt": [
            "DevTestVPC1000016vpcNatEIP",
            "AllocationId"
          ]
        },
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPublicSubnet1"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-nat-vpc-nat"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-nat-vpc-private-rt"
          }
        ]
      }
    },
    "DevTestVPC1000016vpcPrivateRoute": {
      "Type": "AWS::EC2::Route",
      "Properties": {
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPrivateRouteTable"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "NatGatewayId": {
          "Ref": "DevTestVPC1000016vpcNatGateway"
        }
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet1RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPrivateSubnet1"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPrivateRouteTable"
        }
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet2RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPrivateSubnet2"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPrivateRouteTable"
        }
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet3RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPrivateSubnet3"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPrivateRouteTable"
        }
      }
    },
    "DevTestVPC1000016vpcPrivateSubnet4RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "DevTestVPC1000016vpcPrivateSubnet4"
        },
        "RouteTableId": {
          "Ref": "DevTestVPC1000016vpcPrivateRouteTable"
        }
      }
    },
    "PublicSubnet1001024subnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "CidrBlock": "10.0.1.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-pub-subnet"
          }
        ],
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        }
      }
    },
    "PrivateSubnet10011024subnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "CidrBlock": "10.0.11.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "cost-priv-subnet"
          }
        ],
        "VpcId": {
          "Ref": "DevTestVPC1000016vpc"
        }
      }
    },
    "NATInstancet3nanoec2": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId": "ami-nat-instance",
        "InstanceType": "t3.nano",
        "SourceDestCheck": false,
        "SubnetId": {
          "Ref": "PublicSubnet1001024subnet"
        },
        "SecurityGroupIds": [
          {
            "Fn::GetAtt": [
              "DevTestVPC1000016vpc",
              "DefaultSecurityGroup"
            ]
          }
        ]
      }
    },
    "AppServerprivateec2": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "InstanceType": "t3.micro",
        "SubnetId": {
          "Ref": "PrivateSubnet10011024subnet"
        },
        "SecurityGroupIds": [
          {
            "Fn::GetAtt": [
              "DevTestVPC1000016vpc",
              "DefaultSecurityGroup"
            ]
          }
        ]
      }
    },
    "NATCPUAlarmcloudwatch": {
      "Type": "AWS::CloudWatch::Alarm",
      "Properties": {
        "AlarmName": "cost-nat-cpu",
        "AlarmDescription": "Alert when NAT instance CPU > 80 % — consider upgrading instance type or moving to NAT Gateway",
        "Namespace": "AWS/EC2",
        "MetricName": "CPUUtilization",
        "Statistic": "Average",
        "Period": 300,
        "EvaluationPeriods": 3,
        "Threshold": 80,
        "ComparisonOperator": "GreaterThanThreshold",
        "TreatMissingData": "notBreaching"
      }
    }
  }
}

Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.

Related templates