EKS AI Langchain - Part 1 Setting Up the Landing Zone for EKS
Before deploying our super cool infrastructure, setting up a landing zone is essential. A landing zone is a foundational infrastructure setup that inclu...

Todd Bernson
2024-10-15
Before deploying our super cool infrastructure, setting up a landing zone is essential. A landing zone is a foundational infrastructure setup that includes networking, security, and essential services required for a secure and scalable environment. In this article, I'll guide you through setting up a landing zone for your EKS cluster using Terraform.
Clone the repo here.
Prerequisites
Ensure you have the following tools installed and configured:
- Terraform installed.
- AWS CLI installed and configured with necessary permissions (BlueSentry cross-account role).
Step 1: Define Variables
First, create a terraform.tfvars file with the necessary variables:
company = ""
domain = ""
openvpn_instance_type = ""
region = ""
Step 2: Create VPC Configuration
Create a vpc.tf file to define the Virtual Private Cloud (VPC), subnets, and related networking components:
data "aws_availability_zones" "main" {}
locals {
availability_zones = [
data.aws_availability_zones.main.names[0],
data.aws_availability_zones.main.names[1],
data.aws_availability_zones.main.names[2],
]
public_subnets = [
cidrsubnet(var.vpc_cidr, 6, 0),
cidrsubnet(var.vpc_cidr, 6, 1),
cidrsubnet(var.vpc_cidr, 6, 2),
]
private_subnets = [
cidrsubnet(var.vpc_cidr, 6, 4),
cidrsubnet(var.vpc_cidr, 6, 5),
cidrsubnet(var.vpc_cidr, 6, 6),
]
database_subnets = [
cidrsubnet(var.vpc_cidr, 6, 7),
cidrsubnet(var.vpc_cidr, 6, 8),
cidrsubnet(var.vpc_cidr, 6, 9),
]
vpc_route_tables = flatten([
module.vpc.private_route_table_ids,
module.vpc.public_route_table_ids,
])
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.8.1"
azs = local.availability_zones
cidr = var.vpc_cidr
create_database_subnet_group = true
create_flow_log_cloudwatch_iam_role = true
create_flow_log_cloudwatch_log_group = true
database_subnets = local.database_subnets
enable_dhcp_options = true
enable_dns_hostnames = true
enable_dns_support = true
enable_flow_log = true
enable_nat_gateway = true
flow_log_cloudwatch_log_group_retention_in_days = 7
flow_log_max_aggregation_interval = 60
name = var.environment
one_nat_gateway_per_az = var.vpc_redundancy ? true : false
private_subnet_suffix = "private"
private_subnets = local.private_subnets
public_subnets = local.public_subnets
public_subnet_tags = {
"kubernetes.io/cluster/${module.eks.cluster_name}" = "shared"
"kubernetes.io/role/elb" = 1
}
single_nat_gateway = var.vpc_redundancy ? false : true
tags = local.tags
}
module "vpc_endpoints" {
source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints"
version = "~> 5.8.1"
vpc_id = module.vpc.vpc_id
tags = local.tags
endpoints = {
s3 = {
route_table_ids = local.vpc_route_tables
service = "s3"
service_type = "Gateway"
tags = { Name = "s3-vpc-endpoint" }
}
}
}
Step 3: OpenVPN
Create a openvpn.tf file for security groups and roles and EC2:
data "aws_ami" "openvpnas" {
most_recent = true
filter {
name = "name"
values = [
"OpenVPN Access Server Community Image-fe8020db-5343-4c43-9e65-5ed4a825c931*"
]
}
owners = [
"679593333241",
]
include_deprecated = true
}
data "aws_iam_policy_document" "ec2_role" {
statement {
effect = "Allow"
principals {
identifiers = ["ec2.amazonaws.com"]
type = "Service"
}
actions = ["sts:AssumeRole"]
}
}
data "aws_iam_policy" "AmazonSSMManagedInstanceCore" {
name = "AmazonSSMManagedInstanceCore"
}
data "aws_route53_zone" "this" {
name = var.domain
}
locals {
openvpn_name = "openvpn"
}
resource "aws_eip" "vpn" {
tags = merge(var.tags, { Name = "openvpn" })
lifecycle {
create_before_destroy = true
}
}
resource "aws_eip_association" "eip_vpn" {
instance_id = aws_instance.openvpn.id
allocation_id = aws_eip.vpn.id
}
resource "aws_iam_instance_profile" "this" {
name = "${var.company}_ec2_role"
role = aws_iam_role.ec2_role.name
tags = var.tags
}
resource "aws_iam_role" "ec2_role" {
name = "${var.company}_ec2_role"
assume_role_policy = data.aws_iam_policy_document.ec2_role.json
tags = var.tags
}
resource "aws_iam_role_policy_attachment" "AmazonSSMManagedInstanceCore" {
role = aws_iam_role.ec2_role.name
policy_arn = data.aws_iam_policy.AmazonSSMManagedInstanceCore.arn
}
resource "aws_instance" "openvpn" {
ami = data.aws_ami.openvpnas.id
disable_api_termination = true
ebs_optimized = true
iam_instance_profile = aws_iam_instance_profile.this.name
instance_type = var.openvpn_instance_type
key_name = module.dev.ssh_keypair
monitoring = true
subnet_id = module.dev.public_subnets[0]
vpc_security_group_ids = [aws_security_group.openvpn.id]
metadata_options {
http_endpoint = "enabled"
http_put_response_hop_limit = 3
http_tokens = "required"
}
tags = merge(var.tags, {
"Name" = local.openvpn_name
"Patch Group" = "A"
"backup" = "true"
})
volume_tags = merge(var.tags, {
"Name" = "${local.openvpn_name}_vol"
"backup" = "true"
})
root_block_device {
encrypted = true
volume_type = "gp3"
}
lifecycle {
ignore_changes = [user_data, ami]
}
}
resource "aws_route53_record" "vpn" {
zone_id = data.aws_route53_zone.this.zone_id
name = "vpn"
type = "A"
ttl = "300"
records = [aws_eip.vpn.public_ip]
}
resource "aws_security_group" "openvpn" {
name = local.openvpn_name
vpc_id = module.dev.vpc_id
description = "OpenVPN security group"
tags = merge(var.tags, { Name = "${local.openvpn_name}-sg" })
}
resource "aws_security_group_rule" "egress_all" {
type = "egress"
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.openvpn.id
}
resource "aws_security_group_rule" "ingress_tcp443" {
type = "ingress"
protocol = "tcp"
from_port = 443
to_port = 443
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.openvpn.id
}
resource "aws_security_group_rule" "ingress_tcp80" {
type = "ingress"
protocol = "tcp"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.openvpn.id
}
resource "aws_security_group_rule" "ingress_udp1194" {
type = "ingress"
protocol = "udp"
from_port = 1194
to_port = 1194
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.openvpn.id
}
Step 4: S3 Buckets for State Management
Create a backend file to define S3 buckets for storing Terraform state files:
terraform {
backend "s3" {
bucket = <BUCKET_NAME>
key = "infra/terraform.tfstate"
region = "us-east-1"
}
}
Step 5: Initialize and Apply Terraform
Initialize Terraform and apply the configuration:
terraform init
terraform validate
terraform plan -out=plan.out
terraform apply plan.out
You've successfully set up a landing zone for your EKS cluster. This foundational setup includes networking components, security configurations, and essential services, providing a secure and scalable environment for deploying your EKS cluster.
Visit my website here.
Read More
View all posts
AI/ML
Why Enterprise AI Must Be Application-Led, Not Agent-Led
A deep dive by Todd Bernson, CTO and Chief AI Officer, on why enterprise AI systems should be architected as application-led, deterministic platforms with embedded agentic AI—not fully autonomous agents. This article explains how API-first, governed, multi-channel architectures deliver higher reliability, compliance, scalability, and business value in real-world Fortune-500 environments.

Todd Bernson
2025-12-02

AI/ML
Application-First Agentic AI
Application-first agentic AI is emerging as the only reliable path to real enterprise ROI. In this in-depth analysis, Todd Bernson, CTO & CAIO, breaks down why most generative AI initiatives stall in production—and how disciplined enterprise architecture, deterministic workflows, and narrowly scoped AI agents can finally unlock repeatable business value. Using a real sprint-intelligence system as a case study, the article shows how organizations can combine serverless engineering, structured orchestration, and constrained LLM reasoning to reduce reporting effort, increase trust, eliminate hallucinations, and deliver actionable insights across engineering, operations, compliance, and customer experience.

Todd Bernson
2025-11-28
AI/ML
Why 95% of AI Projects Fail and How to Be Among the 5% That Succeed

Lee Hylton
2025-08-22