Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: terraform aws eks #12

Open
wants to merge 4 commits into
base: external-secrets
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
module "eks" {
source = "./modules/eks"
module "network" {
source = "./modules/networking"

vpc_name = "main"
vpc_cidr_block = "10.0.0.0/16"

vpc_id = var.vpc_id
cluster_name = "test"
public_subnets = {
"ap-southeast-1a" = "10.0.1.0/24"
"ap-southeast-1b" = "10.0.2.0/24"
"ap-southeast-1c" = "10.0.3.0/24"
}

private_subnets = {
"ap-southeast-1a" = "10.0.11.0/24"
"ap-southeast-1b" = "10.0.12.0/24"
"ap-southeast-1c" = "10.0.13.0/24"
}
}

module "self-managed" {
source = "./modules/k8s-self-managed"
module "cluster" {
source = "./modules/eks"

vpc_id = var.vpc_id
cluster_name = "self_managed"
cluster_name = "test"
nodegroup_name = "test"
vpc_id = module.network.vpc_id
worker_subnet_ids = module.network.private_subnet_ids
}
43 changes: 43 additions & 0 deletions terraform/modules/eks/cluster.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
resource "aws_security_group" "cluster" {
name = "${var.cluster_name}_eks_cluster_sg"
description = "EKS cluster security group."
vpc_id = var.vpc_id
tags = {
"Name" = "${var.cluster_name}_eks_cluster_sg"
}
}

resource "aws_security_group_rule" "cluster_egress_internet" {
description = "Allow cluster egress access to the Internet."
protocol = "-1"
security_group_id = aws_security_group.cluster.id
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
type = "egress"
}

resource "aws_security_group_rule" "cluster_https_worker_ingress" {
description = "Allow pods to communicate with the EKS cluster API."
protocol = "tcp"
security_group_id = aws_security_group.cluster.id
source_security_group_id = aws_security_group.worker.id
from_port = 443
to_port = 443
type = "ingress"
}

resource "aws_eks_cluster" "cluster" {
depends_on = [
aws_iam_role_policy_attachment.AmazonEKSClusterPolicy,
aws_iam_role_policy_attachment.AmazonEKSServicePolicy,
]
version = var.k8s_version
name = var.cluster_name
role_arn = aws_iam_role.eks_role.arn
vpc_config {
subnet_ids = var.worker_subnet_ids
security_group_ids = [aws_security_group.cluster.id]
}
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
}
28 changes: 28 additions & 0 deletions terraform/modules/eks/cluster_roles.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
resource "aws_iam_role" "eks_role" {
name = "eks-cluster-${var.cluster_name}-role"

assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_role.name
}

resource "aws_iam_role_policy_attachment" "AmazonEKSServicePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
role = aws_iam_role.eks_role.name
}
20 changes: 20 additions & 0 deletions terraform/modules/eks/nodegroup.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "aws_eks_node_group" "default" {
depends_on = [
aws_iam_role_policy_attachment.eks_worker_AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.eks_worker_AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.eks_worker_AmazonEC2ContainerRegistryReadOnly,
aws_iam_role_policy_attachment.eks_worker_autoscaling
]

cluster_name = aws_eks_cluster.cluster.name
node_group_name = "${aws_eks_cluster.cluster.name}-managed-${var.nodegroup_name}"
node_role_arn = aws_iam_role.worker_role.arn
subnet_ids = var.worker_subnet_ids
instance_types = [var.worker_instance_type]

scaling_config {
min_size = var.min_worker_node_number
desired_size = var.desired_worker_node_number
max_size = var.max_worker_node_number
}
}
19 changes: 19 additions & 0 deletions terraform/modules/eks/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "cluster_name" {
value = aws_eks_cluster.cluster.id
}

output "endpoint" {
value = aws_eks_cluster.cluster.endpoint
}

output "kubeconfig_certificate_authority_data" {
value = aws_eks_cluster.cluster.certificate_authority[0].data
}

output "security_group_id" {
value = aws_eks_cluster.cluster.vpc_config[0].cluster_security_group_id
}

output "worker_node_role_name" {
value = aws_iam_role.worker_role.name
}
38 changes: 38 additions & 0 deletions terraform/modules/eks/variables.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,47 @@
# mandatory variables

# cluster
variable "cluster_name" {
type = string
}

variable "nodegroup_name" {
type = string
}

# networking
variable "vpc_id" {
description = "The existing VPC"
}

variable "worker_subnet_ids" {
type = list(any)
description = "the subnets where to deploy EKS"
}

# optional variables
variable "k8s_version" {
type = string
default = "1.21"
}

variable "worker_instance_type" {
description = "worker type, like t2.medium"
type = string
default = "t2.medium"
}

variable "min_worker_node_number" {
type = number
default = 2
}

variable "desired_worker_node_number" {
type = number
default = 2
}

variable "max_worker_node_number" {
type = number
default = 2
}
79 changes: 79 additions & 0 deletions terraform/modules/eks/worker_node_roles.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
resource "aws_iam_role" "worker_role" {
name = "eks-cluster-${var.cluster_name}-worker-node-role"
path = "/"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy_attachment" "eks_worker_AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.worker_role.name
}

resource "aws_iam_role_policy_attachment" "eks_worker_AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.worker_role.name
}

resource "aws_iam_role_policy_attachment" "eks_worker_AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.worker_role.name
}

resource "aws_iam_role_policy_attachment" "eks_worker_autoscaling" {
policy_arn = aws_iam_policy.worker_autoscaling.arn
role = aws_iam_role.worker_role.name
}

resource "aws_iam_policy" "worker_autoscaling" {
name_prefix = "eks-worker-autoscaling-${var.cluster_name}"
policy = data.aws_iam_policy_document.worker_autoscaling.json
path = "/"
}

data "aws_iam_policy_document" "worker_autoscaling" {
statement {
sid = "eksWorkerAutoscalingAll"
effect = "Allow"

actions = [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeTags",
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeInstanceTypes"
]

resources = ["*"]
}

statement {
sid = "eksWorkerAutoscalingOwn"
effect = "Allow"

actions = [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup",
"autoscaling:UpdateAutoScalingGroup",
]

resources = ["*"]
}
}
49 changes: 44 additions & 5 deletions terraform/modules/eks/worker_node_sg.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
resource "aws_security_group" "worker" {
name = "eks_cluster_${var.cluster_name}_worker_sg"
description = "Security group for all worker nodes in the cluster."

vpc_id = var.vpc_id
name = "${var.cluster_name}_eks_worker_node_sg"
description = "Security group for all nodes in the cluster."
vpc_id = var.vpc_id

lifecycle {
ignore_changes = [ingress]
}

tags = {
"Name" = "eks_cluster_${var.cluster_name}_worker_sg"
"Name" = "${var.cluster_name}_eks_worker_node_sg"
"kubernetes.io/cluster/" = var.cluster_name
}
}

resource "aws_security_group_rule" "workers_egress_internet" {
description = "Allow nodes all egress to the Internet."
protocol = "-1"
security_group_id = aws_security_group.worker.id
cidr_blocks = ["0.0.0.0/0"]
from_port = 0
to_port = 0
type = "egress"
}

resource "aws_security_group_rule" "workers_ingress_self" {
description = "Allow node to communicate with each other."
protocol = "-1"
security_group_id = aws_security_group.worker.id
source_security_group_id = aws_security_group.worker.id
from_port = 0
to_port = 65535
type = "ingress"
}

resource "aws_security_group_rule" "workers_ingress_cluster" {
description = "Allow workers pods to receive communication from the cluster control plane."
protocol = "tcp"
security_group_id = aws_security_group.worker.id
source_security_group_id = aws_security_group.cluster.id
from_port = 1025
to_port = 65535
type = "ingress"
}

resource "aws_security_group_rule" "workers_ingress_cluster_https" {
description = "Allow pods running extension API servers on port 443 to receive communication from cluster control plane."
protocol = "tcp"
security_group_id = aws_security_group.worker.id
source_security_group_id = aws_security_group.cluster.id
from_port = 443
to_port = 443
type = "ingress"
}
10 changes: 10 additions & 0 deletions terraform/modules/networking/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# AWS VPC Module

This module creates:

- VPC
- public subnets
- private subnets
- NAT gateways in each public subnet (including the EIP of course)
- routing tables and associations (each private subnet routes to the NAT gateway in the same AZ)
- Internet gateway
Loading