1

Friends,

I am completely new to Terraform but I am trying learn here. At the moment I am reading the book Terraform UP and Running but I need to spin up an EKS cluster to deploy one of my learning projects. For this, I am following this [tutorial][1] of Hashicorp.

My main questions are the following: Do I really need all of this (see the terraform code for aws bellow) to deploy a cluster on AWS? How could I reduce the bellow code to the minimum necessary to spin up a cluster with a master and one worker which are able to communicate with each other?

On Gloud I could spin up a cluster with just these few lines of code:

provider "google" { credentials = file(var.credentials) project = var.project region = var.region } resource "google_container_cluster" "primary" { name = var.cluster_name network = var.network location = var.region initial_node_count = var.initial_node_count } resource "google_container_node_pool" "primary_preemtible_nodes" { name = var.node_name location = var.region cluster = google_container_cluster.primary.name node_count = var.node_count node_config { preemptible = var.preemptible machine_type = var.machine_type } } 

Can I do something similar do spin up an EKS cluster? The code bellow is working but I feel like I am biting more than I can chew.

provider "aws" { region = "${var.AWS_REGION}" secret_key = "${var.AWS_SECRET_KEY}" access_key = "${var.AWS_ACCESS_KEY}" } # ----- Base VPC Networking ----- data "aws_availability_zones" "available_zones" {} # Creates a virtual private network which will isolate # the resources to be created. resource "aws_vpc" "blur-vpc" { #Specifies the range of IP adresses for the VPC. cidr_block = "10.0.0.0/16" tags = "${ map( "Name", "terraform-eks-node", "kubernetes.io/cluster/${var.cluster-name}", "shared" ) }" } resource "aws_subnet" "subnet" { count = 2 availability_zone = "${data.aws_availability_zones.available_zones.names[count.index]}" cidr_block = "10.0.${count.index}.0/24" vpc_id = "${aws_vpc.blur-vpc.id}" tags = "${ map( "Name", "blur-subnet", "kubernetes.io/cluster/${var.cluster-name}", "shared", ) }" } # The component that allows communication between # the VPC and the internet. resource "aws_internet_gateway" "gateway" { # Attaches the gateway to the VPC. vpc_id = "${aws_vpc.blur-vpc.id}" tags = { Name = "eks-gateway" } } # Determines where network traffic from the gateway # will be directed. resource "aws_route_table" "route-table" { vpc_id = "${aws_vpc.blur-vpc.id}" route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.gateway.id}" } } resource "aws_route_table_association" "table_association" { count = 2 subnet_id = "${aws_subnet.subnet.*.id[count.index]}" route_table_id = "${aws_route_table.route-table.id}" } # -- Resources required for the master setup -- # This bellow block (IAM role + Policy) allows the EKS service to # manage or retrieve data from other AWS services. # Similar to a IAM but not uniquely associated with one person. # A role can be assumed by anyone who needs it. resource "aws_iam_role" "blur-iam-role" { name = "eks-cluster" assume_role_policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } POLICY } # Attaches the policy "AmazonEKSClusterPolicy" to the role created above. resource "aws_iam_role_policy_attachment" "blur-iam-role-AmazonEKSClusterPolicy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" role = "${aws_iam_role.blur-iam-role.name}" } # Master security group # # A security group acts as a virtual firewall to control inbound and outbound traffic. # This security group will control networking access to the K8S master. resource "aws_security_group" "blur-cluster" { name = "eks-blur-cluster" description = "Allows the communucation with the worker nodes" vpc_id = "${aws_vpc.blur-vpc.id}" egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "blur-cluster" } } # The actual master node resource "aws_eks_cluster" "blur-cluster" { name = "${var.cluster-name}" # Attaches the IAM role created above. role_arn = "${aws_iam_role.blur-iam-role.arn}" vpc_config { # Attaches the security group created for the master. # Attaches also the subnets. security_group_ids = ["${aws_security_group.blur-cluster.id}"] subnet_ids = "${aws_subnet.subnet.*.id}" } depends_on = [ "aws_iam_role_policy_attachment.blur-iam-role-AmazonEKSClusterPolicy", # "aws_iam_role_policy_attachment.blur-iam-role-AmazonEKSServicePolicy" ] } # -- Resources required for the worker nodes setup -- # IAM role for the workers. Allows worker nodes to manage or retrieve data # from other services and its required for the workers to join the cluster. resource "aws_iam_role" "iam-role-worker"{ name = "eks-worker" assume_role_policy = <<POLICY { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } POLICY } # allows Amazon EKS worker nodes to connect to Amazon EKS Clusters. resource "aws_iam_role_policy_attachment" "iam-role-worker-AmazonEKSWorkerNodePolicy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" role = "${aws_iam_role.iam-role-worker.name}" } # This permission is required to modify the IP address configuration of worker nodes resource "aws_iam_role_policy_attachment" "iam-role-worker-AmazonEKS_CNI_Policy" { policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" role = "${aws_iam_role.iam-role-worker.name}" } # Allows to list repositories and pull images resource "aws_iam_role_policy_attachment" "iam-role-worker-AmazonEC2ContainerRegistryReadOnly" { policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" role = "${aws_iam_role.iam-role-worker.name}" } # An instance profile represents an EC2 instances (Who am I?) # and assumes a role (what can I do?). resource "aws_iam_instance_profile" "worker-node" { name = "worker-node" role = "${aws_iam_role.iam-role-worker.name}" } # Security group for the worker nodes resource "aws_security_group" "security-group-worker" { name = "worker-node" description = "Security group for worker nodes" vpc_id = "${aws_vpc.blur-vpc.id}" egress { cidr_blocks = [ "0.0.0.0/0" ] from_port = 0 to_port = 0 protocol = "-1" } tags = "${ map( "Name", "blur-cluster", "kubernetes.io/cluster/${var.cluster-name}", "owned" ) }" } resource "aws_security_group_rule" "ingress-self" { description = "Allow communication among nodes" from_port = 0 to_port = 65535 protocol = "-1" security_group_id = "${aws_security_group.security-group-worker.id}" source_security_group_id = "${aws_security_group.security-group-worker.id}" type = "ingress" } resource "aws_security_group_rule" "ingress-cluster-https" { description = "Allow worker to receive communication from the cluster control plane" from_port = 443 to_port = 443 protocol = "tcp" security_group_id = "${aws_security_group.security-group-worker.id}" source_security_group_id = "${aws_security_group.blur-cluster.id}" type = "ingress" } resource "aws_security_group_rule" "ingress-cluster-others" { description = "Allow worker to receive communication from the cluster control plane" from_port = 1025 to_port = 65535 protocol = "tcp" security_group_id = "${aws_security_group.security-group-worker.id}" source_security_group_id = "${aws_security_group.blur-cluster.id}" type = "ingress" } # Worker Access to Master resource "aws_security_group_rule" "cluster-node-ingress-http" { description = "Allows pods to communicate with the cluster API server" from_port = 443 to_port = "443" protocol = "tcp" security_group_id = "${aws_security_group.blur-cluster.id}" source_security_group_id = "${aws_security_group.security-group-worker.id}" type = "ingress" } # --- Worker autoscaling group --- # This data will be used to filter and select an AMI which is compatible with the specific k8s version being deployed data "aws_ami" "eks-worker" { filter { name = "name" values = ["amazon-eks-node-${aws_eks_cluster.blur-cluster.version}-v*"] } most_recent = true owners = ["602401143452"] } data "aws_region" "current" {} locals { node-user-data =<<USERDATA #!/bin/bash set -o xtrace /etc/eks/bootstrap.sh --apiserver-endpoint '${aws_eks_cluster.blur-cluster.endpoint}' USERDATA } # To spin up an auto scaling group an "aws_launch_configuration" is needed. # This ALC requires an "image_id" as well as a "security_group". resource "aws_launch_configuration" "launch_config" { associate_public_ip_address = true iam_instance_profile = "${aws_iam_instance_profile.worker-node.name}" image_id = "${data.aws_ami.eks-worker.id}" instance_type = "t2.micro" name_prefix = "terraform-eks" security_groups = ["${aws_security_group.security-group-worker.id}"] user_data_base64 = "${base64encode(local.node-user-data)}" lifecycle { create_before_destroy = true } } # Actual autoscaling group resource "aws_autoscaling_group" "autoscaling" { desired_capacity = 2 launch_configuration = "${aws_launch_configuration.launch_config.id}" max_size = 2 min_size = 1 name = "terraform-eks" vpc_zone_identifier = "${aws_subnet.subnet.*.id}" tag { key = "Name" value = "terraform-eks" propagate_at_launch = true } # "kubernetes.io/cluster/*" tag allows EKS and K8S to discover and manage compute resources. tag { key = "kubernetes.io/cluster/${var.cluster-name}" value = "owned" propagate_at_launch = true } } [1]: https://registry.terraform.io/providers/hashicorp/aws/2.33.0/docs/guides/eks-getting-started#preparation 

1 Answer 1

1

Yes, you should create most of them, because as you can see at Terraform AWS documents, VPC configuration is required to deploy EKS cluster. But you don't have to set up a security group rule for workers to access the master. Also, try to use aws_eks_node_group resource to create worker nodegroup. It will save you from creating launch configuration and autoscaling group seperately.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, @Oguzhan! I will take a look at the aws_eks_node_group resource.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.