Skip to content
This repository has been archived by the owner on Mar 5, 2022. It is now read-only.

Commit

Permalink
Import Terraform configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
rdumont committed Jul 31, 2019
1 parent 8e6bdf7 commit be36c88
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 0 deletions.
229 changes: 229 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
###############
# Cluster IAM #
###############

resource "aws_iam_role" "cluster" {
name = "${var.cluster-name}-cluster"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}

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

resource "aws_iam_role_policy_attachment" "cluster-AmazonEKSServicePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
role = aws_iam_role.cluster.name
}

##########################
# Cluster Security Group #
##########################

resource "aws_security_group" "cluster" {
name = "${var.cluster-name}-cluster"
description = "Cluster communication with worker nodes"
vpc_id = var.vpc_id

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = var.cluster-name
}
}

######################
# Cluster Definition #
######################

resource "aws_eks_cluster" "cluster" {
name = var.cluster-name
role_arn = aws_iam_role.cluster.arn

vpc_config {
security_group_ids = [aws_security_group.cluster.id]
subnet_ids = var.subnet_ids
}

depends_on = [
"aws_iam_role_policy_attachment.cluster-AmazonEKSClusterPolicy",
"aws_iam_role_policy_attachment.cluster-AmazonEKSServicePolicy",
]
}

#############
# Nodes IAM #
#############

resource "aws_iam_role" "nodes" {
name = "${var.cluster-name}-nodes"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}

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

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

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

resource "aws_iam_instance_profile" "nodes" {
name = "${var.cluster-name}-nodes"
role = aws_iam_role.nodes.name
}

#########################
# Nodes Security Groups #
#########################

resource "aws_security_group" "nodes" {
name = "${var.cluster-name}-nodes"
description = "Security group for all nodes in the cluster"
vpc_id = var.vpc_id

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = "${
map(
"Name", var.cluster-name,
"kubernetes.io/cluster/${var.cluster-name}", "owned",
)
}"
}

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

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

resource "aws_security_group_rule" "ingress-node-https" {
description = "Allow pods to communicate with the cluster API Server"
from_port = 443
protocol = "tcp"
security_group_id = aws_security_group.cluster.id
source_security_group_id = aws_security_group.nodes.id
to_port = 443
type = "ingress"
}

######################
# Auto-scaling Group #
######################

data "aws_ami" "eks-worker" {
filter {
name = "name"
values = ["amazon-eks-node-${aws_eks_cluster.cluster.version}-v*"]
}

most_recent = true
owners = ["602401143452"] # Amazon EKS AMI Account ID
}

# EKS currently documents this required userdata for EKS worker nodes to
# properly configure Kubernetes applications on the EC2 instance.
# We implement a Terraform local here to simplify Base64 encoding this
# information into the AutoScaling Launch Configuration.
# More information: https://docs.aws.amazon.com/eks/latest/userguide/launch-workers.html
locals {
nodes-userdata = <<USERDATA
#!/bin/bash
set -o xtrace
/etc/eks/bootstrap.sh --apiserver-endpoint '${aws_eks_cluster.cluster.endpoint}' --b64-cluster-ca '${aws_eks_cluster.cluster.certificate_authority.0.data}' '${var.cluster-name}'
USERDATA
}

resource "aws_launch_configuration" "nodes" {
associate_public_ip_address = true
iam_instance_profile = aws_iam_instance_profile.nodes.name
image_id = data.aws_ami.eks-worker.id
instance_type = var.node-instance-type
name_prefix = var.cluster-name
security_groups = [aws_security_group.nodes.id]
user_data_base64 = base64encode(local.nodes-userdata)

lifecycle {
create_before_destroy = true
}
}

resource "aws_autoscaling_group" "nodes" {
desired_capacity = var.asg-desired-capacity
launch_configuration = aws_launch_configuration.nodes.id
max_size = var.asg-max-size
min_size = var.asg-min-size
name = "${var.cluster-name}-nodes"
vpc_zone_identifier = var.subnet_ids

tag {
key = "Name"
value = "${var.cluster-name}-nodes"
propagate_at_launch = true
}

tag {
key = "kubernetes.io/cluster/${var.cluster-name}"
value = "owned"
propagate_at_launch = true
}
}
60 changes: 60 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
locals {
config_map_aws_auth = <<CONFIGMAPAWSAUTH
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: ${aws_iam_role.nodes.arn}
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
mapUsers: |
%{for u in var.map-users~}
- userarn: ${u.userarn}
username: ${u.username}
groups:
- system:masters
%{endfor~}
CONFIGMAPAWSAUTH
}

output "config_map_aws_auth" {
value = local.config_map_aws_auth
}

locals {
kubeconfig = <<KUBECONFIG
apiVersion: v1
clusters:
- cluster:
server: ${aws_eks_cluster.cluster.endpoint}
certificate-authority-data: ${aws_eks_cluster.cluster.certificate_authority.0.data}
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: aws
name: aws
current-context: aws
kind: Config
preferences: {}
users:
- name: aws
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: aws-iam-authenticator
args:
- "token"
- "-i"
- "${var.cluster-name}"
KUBECONFIG
}

output "kubeconfig" {
value = local.kubeconfig
}
42 changes: 42 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
variable "region" {
type = string
}

variable "availability_zone_names" {
type = "list"
}

variable "vpc_id" {
type = string
}

variable "subnet_ids" {
type = list(string)
}

variable "cluster-name" {
type = string
}

variable "node-instance-type" {
type = string
}

variable "asg-desired-capacity" {
type = number
default = 2
}

variable "asg-max-size" {
type = number
default = 2
}

variable "asg-min-size" {
type = number
default = 1
}

variable "map-users" {
type = list(object({ userarn = string, username = string }))
}

0 comments on commit be36c88

Please sign in to comment.