A production-ready AWS CDK application that deploys a scalable WireGuard VPN infrastructure using AWS best practices. This project provisions a highly available VPN solution with EC2 instances behind a Network Load Balancer, designed for secure remote access and privacy protection.
This CDK application creates a complete VPN infrastructure consisting of:
- VPC with Multi-AZ Setup: Custom VPC (172.31.0.0/16) spanning configurable Availability Zones with public subnets
- Network Load Balancer: Internet-facing NLB handling UDP traffic on port 443 for VPN clients
- EC2 WireGuard Server: Ubuntu 22.04 instances (t3.medium) with automated WireGuard and dependency installation
- Security Groups: Layered security with separate groups for NLB and EC2 instances
- Target Groups: Health-checked routing from NLB to WireGuard servers
- Wireguard Mangement and Dependencies: Automated WireGuard and dependency install with wireguard-manager git repo cloned from ComplexOrganizations.
- VPN clients connect to the NLB public endpoint on UDP:443
- NLB distributes traffic to WireGuard servers on configurable WireGuard port
- WireGuard servers handle VPN tunneling and routing
- Admin access via SSH is restricted to specified IP address
- High Availability: Multi-AZ deployment with automatic failover
- Scalable: Easy to add more WireGuard servers by adjusting instance count
- Secure: Network segmentation with least-privilege security groups
- Automated: Complete infrastructure provisioning and WireGuard installation
- Cost-Effective: Uses efficient t3.medium instances with no NAT gateways
- Monitoring: Built-in health checks and CloudFormation outputs for monitoring
- AWS CLI configured with appropriate credentials
- Node.js and npm installed
- AWS CDK CLI installed (
npm install -g aws-cdk) - An existing EC2 Key Pair in your target region (configurable name)
Before deploying, you must configure these key settings:
Update the environment configuration with your AWS account details:
const envConfig = {
account: 'YOUR_AWS_ACCOUNT_ID', // β οΈ REQUIRED: Your 12-digit AWS account ID
region: 'YOUR_AWS_REGION' // β οΈ REQUIRED: Your target AWS region
};// Inbound rule for SSH
this.serverSecurityGroup.addIngressRule(
ec2.Peer.ipv4('YOUR_ADMIN_IP/32'), // β οΈ REQUIRED: Replace with your public IP
ec2.Port.tcp(22),
'Allow SSH from admin IP only'
);Configure the WireGuard server port:
// Target Group configuration (line ~60)
const targetGroup = new elbv2.NetworkTargetGroup(this, 'FluffyEngineTargetGroup', {
vpc: this.vpc,
port: 51280, // β οΈ CONFIGURE: Your WireGuard server port
protocol: elbv2.Protocol.UDP,
// ... rest of config
});
// Security Group rule (line ~90)
this.serverSecurityGroup.addIngressRule(
ec2.Peer.securityGroupId(this.nlbSecurityGroup.securityGroupId),
ec2.Port.udp(51280), // β οΈ CONFIGURE: Must match target group port above
'Allow VPN traffic from NLB only'
);Set the number of WireGuard servers (line ~15):
// Create 1 or more EC2 Instances
const instanceCount = 1; // β οΈ CONFIGURE: Number of EC2 instancesSet your EC2 Key Pair name (line ~30):
keyPair: ec2.KeyPair.fromKeyPairName(this, `ImportedKeyPair=${i}`, 'fluffyengine'),
// β
// β οΈ CONFIGURE: Your key pair nameConfigure the number of Availability Zones:
// VPC
this.vpc = new ec2.Vpc(this, 'FluffyEngineVPC', {
ipAddresses: ec2.IpAddresses.cidr('172.31.0.0/16'),
maxAzs: 2, // β οΈ CONFIGURE: Number of AZs (1-6, recommend 2-3 for HA)
natGateways: 0,
// ... rest of config
});-
Create EC2 Key Pair (if you don't have one):
aws ec2 create-key-pair --key-name YOUR_KEY_PAIR_NAME --query 'KeyMaterial' --output text > your-key.pem chmod 400 your-key.pem
Or create it in the AWS management console
-
Get your public IP for admin access if logged in:
curl -s https://checkip.amazonaws.com
Or get the IP from the instance in AWS management console
-
Bootstrap CDK (first time only):
cdk bootstrap
-
Deploy the infrastructure:
npm install npm run build cdk deploy --all
-
Get the NLB Target Group ARN and EC2 instance ID from the CloudFormation outputs and manually register the EC2 instance with the Target Group.
aws elbv2 register-targets --target-group-arn YOUR_TARGET_GROUP_ARN --targets Id=INSTANCE_ID
-
Get the NLB DNS name from the CloudFormation outputs and use it as your WireGuard endpoint.
After deployment, configure your WireGuard clients with:
[Interface]
# Your client configuration
[Peer]
Endpoint = YOUR_NLB_DNS_NAME:443
# Additional peer configurationExample endpoint: my-nlb-4e2d1f8bb2751e6a.elb.us-east-1.amazonaws.com:443
The deployment provides several CloudFormation outputs:
- VPC ID: For network reference
- NLB DNS Name: Your VPN endpoint
- Target Group ARN: For monitoring target health
- Instance IDs: For direct instance management
- Public IPs: For SSH access and troubleshooting
- Horizontal Scaling: Increase
instanceCountfor more servers - Vertical Scaling: Change instance type from
ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM - Geographic Scaling: Adjust
maxAzsfor wider distribution
- VPC CIDR: Change from
172.31.0.0/16to your preferred range - Subnet Configuration: Modify subnet CIDR masks and types
- Load Balancer: Adjust NLB settings for different traffic patterns
- Admin Access: SSH restricted to specified IP addresses only
- Network Isolation: VPN traffic isolated using security group rules
- Minimal Attack Surface: No inbound internet access except VPN and admin SSH
- Health Monitoring: Continuous health checks ensure service availability
- Key Management: EC2 instances use specified key pairs for secure access
- Multiple Admin IPs: Add additional SSH access rules as needed
- Custom Ports: Change default ports for your needs
- VPC Flow Logs: Add logging for network traffic analysis
- No NAT Costs: Uses public subnets only (no NAT Gateway fees)
- Efficient Instances: t3.medium instances with burstable performance
- Optimized Load Balancer: Network Load Balancer optimized for UDP traffic
- Direct Routing: Minimal data transfer costs with direct internet routing
npm run build- Compile TypeScript to JavaScriptnpm run watch- Watch for changes and compile automaticallynpm run test- Run Jest unit testscdk deploy- Deploy stacks to AWScdk diff- Compare deployed stack with current statecdk synth- Generate CloudFormation templatescdk destroy- Remove all deployed resources
- Security: Always restrict admin IP access to specific IP addresses
- Ports: Ensure WireGuard port consistency between target group and security group
- Key Pairs: Verify your key pair exists in the target region before deployment
- Costs: Monitor AWS costs, especially for multiple instances and data transfer
- Updates: Regularly update the Ubuntu AMI and WireGuard software
