Skip to content

AWS Client VPN Module

This module creates an AWS Client VPN endpoint for secure, direct network access to private ROSA HCP cluster VPCs. Recommended as the default access method for private clusters (replacing sshuttle over bastion).

Overview

AWS Client VPN provides an OpenVPN-compatible managed VPN service. Users connect with standard VPN clients (AWS VPN Client, OpenVPN, Tunnelblick) and get full VPC network access including DNS resolution for cluster endpoints.

Key Features

  • Direct Network Access: Connect to any resource in the VPC without port forwarding
  • VPC DNS Resolution: Resolve cluster endpoints (api., apps.) natively
  • No Certificate Warnings: Proper TLS works because DNS resolves correctly
  • OpenVPN Compatible: Works with AWS VPN Client, OpenVPN, or Tunnelblick
  • Mutual TLS Authentication: Self-signed certificates generated by Terraform
  • Split Tunneling: Only VPC traffic goes through VPN (configurable, default: true)

Usage

Enable via root module variables:

enable_client_vpn         = true
vpn_client_cidr_block    = "10.100.0.0/22"  # Must not overlap with VPC CIDR
vpn_split_tunnel         = true
vpn_session_timeout_hours = 12

Standalone Module Usage

module "client_vpn" {
  source = "../modules/infrastructure/client-vpn"

  cluster_name       = "my-rosa-cluster"
  vpc_id             = local.network.vpc_id
  vpc_cidr           = var.vpc_cidr
  subnet_ids         = [local.network.private_subnet_ids[0]]  # Single subnet for cost savings
  client_cidr_block  = "10.100.0.0/22"
  output_dir         = "${path.root}/../clusters/${var.cluster_name}"
  cluster_domain     = module.cluster.cluster_domain  # Optional, for .ovpn file instructions

  tags = var.tags
}

Cost Comparison

Access Method Typical Monthly Cost Best For
Bastion (sshuttle) $5-20 Cost-sensitive, occasional access
Client VPN (1 subnet) $100-150 Development teams, reliable access
Client VPN (3 subnets) $300-350 Production access, high availability

Client VPN costs more but provides reliable, cross-platform access without per-user setup issues.

Input Variables

Name Description Type Default Required
cluster_name Name of the ROSA cluster string n/a yes
vpc_id VPC ID string n/a yes
vpc_cidr VPC CIDR block string n/a yes
subnet_ids Subnet IDs to associate list(string) n/a yes
client_cidr_block CIDR for VPN clients string "10.100.0.0/22" no
dns_servers DNS servers for VPN clients list(string) VPC DNS no
service_cidr Kubernetes service CIDR (auth rule) string null no
split_tunnel Enable split tunneling bool true no
session_timeout_hours Session timeout (8-24) number 12 no
certificate_validity_days Certificate validity number 365 no
certificate_organization Organization for cert subject string "ROSA HCP" no
kms_key_arn KMS key for log encryption string null no
output_dir Directory for .ovpn file string n/a yes
cluster_domain Cluster domain (for instructions) string null no
tags Tags for resources map(string) {} no

Outputs

Name Description
vpn_endpoint_id Client VPN endpoint ID
vpn_endpoint_dns VPN endpoint DNS name
client_config_path Path to .ovpn file
certificate_expiry When certs expire
connection_instructions How to connect

Connecting

  1. Install VPN client: AWS VPN Client (recommended) or OpenVPN
  2. Import config: Use the .ovpn file from clusters/<name>/<name>-vpn-client.ovpn
  3. Connect: Connect via the client; access cluster API/console directly