EKS AI Langchain - Part 1 Setting Up the Landing Zone for EKS
Todd Bernson
Award Winning Technology Leader | AWS Ambassador | AWS Machine Learning Community Builder | Lifelong Learner | Data Analytics, ML, AI
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:
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.