<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Noura Hussein</title>
    <description>The latest articles on DEV Community by Noura Hussein (@noura_hussein).</description>
    <link>https://dev.to/noura_hussein</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F772814%2F66d1b0ba-73dd-4f38-a143-9e7f2f9fa99f.jpeg</url>
      <title>DEV Community: Noura Hussein</title>
      <link>https://dev.to/noura_hussein</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noura_hussein"/>
    <language>en</language>
    <item>
      <title>Create a simple Ingress NGINX Controller on Amazon EKS Cluster with full example</title>
      <dc:creator>Noura Hussein</dc:creator>
      <pubDate>Mon, 31 Oct 2022 15:51:40 +0000</pubDate>
      <link>https://dev.to/aws-builders/create-a-simple-ingress-nginx-controller-on-amazon-eks-cluster-with-full-example-5ei1</link>
      <guid>https://dev.to/aws-builders/create-a-simple-ingress-nginx-controller-on-amazon-eks-cluster-with-full-example-5ei1</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyogsthbcuuroj6yau62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyogsthbcuuroj6yau62.png" alt="Ingress"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before talking about the ingress controller lets know first&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Ingress?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster. Traffic routing is controlled by rules defined on the Ingress resource.&lt;/p&gt;

&lt;p&gt;Ingress is not actually a type of service. Instead, it is an entry point that sits in front of multiple services in the cluster. It can be defined as a collection of routing rules that govern how external users access services running inside a Kubernetes cluster.&lt;/p&gt;

&lt;p&gt;Above image is a simple example where an Ingress sends all its traffic to one Service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is an Ingress controller?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An Ingress controller is responsible for fulfilling the Ingress, usually with a load balancer, though it may also configure your edge router or additional frontends to help handle the traffic.&lt;/p&gt;

&lt;p&gt;In order for the Ingress resource to work, the cluster must have an ingress controller running.&lt;br&gt;
Only creating an Ingress resource has no effect.&lt;/p&gt;

&lt;p&gt;Unlike other types of controllers which run as part of the &lt;code&gt;kube-controller-manager&lt;/code&gt; binary, Ingress controllers are not started automatically with a cluster.&lt;/p&gt;

&lt;p&gt;Kubernetes as a project supports and maintains &lt;a href="https://github.com/kubernetes-sigs/aws-load-balancer-controller#readme" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;, &lt;a href="https://git.k8s.io/ingress-gce/README.md#readme" rel="noopener noreferrer"&gt;GCE&lt;/a&gt;, and &lt;a href="https://git.k8s.io/ingress-nginx/README.md#readme" rel="noopener noreferrer"&gt;nginx&lt;/a&gt; ingress controllers.&lt;/p&gt;




&lt;p&gt;In this article, I will create an Ingress NGINX Controller and then will create a full example to show you the traffic flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u1g9jonqumo6rr8y3vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3u1g9jonqumo6rr8y3vh.png" alt="Full example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've implemented a terraform module to create an NGINX ingress controller with the full example above in my GitHub repo &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller" rel="noopener noreferrer"&gt;create-simple-nginx-controller&lt;/a&gt;&lt;br&gt;
please have a look at &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller#:~:text=with%20basic%20requirments.-,Getting%20started,-have%20a%20look" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt; part in the README file to able to use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1- Terraform Tool: An IAC tool, use version &amp;gt;= 0.13.1.&lt;br&gt;
2- An existing EKS cluster if you don't know how to create an EKS cluster please have a look at &lt;a href="https://dev.to/aws-builders/create-a-simple-eks-cluster-394a"&gt;my previous article&lt;/a&gt; where I explained to you how to create a simple EKS cluster using terraform.&lt;br&gt;
3- AWS CLI: A command line tool for working with Amazon EKS.&lt;br&gt;
4- &lt;code&gt;kubectl&lt;/code&gt;: A command line tool for working with Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;br&gt;
1- Create EKS cluster.&lt;br&gt;
2- Create an Ingress NGINX controller.&lt;br&gt;
3- Create PODs for app1 and app2.&lt;br&gt;
4- Create Services for app1 and app2.&lt;br&gt;
5- Create an Ingress resource.&lt;br&gt;
6- Run the code.&lt;br&gt;
7- Try to connect to your PODs using the LoadBalancer URL.&lt;br&gt;
8- Clean Up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;1- Create EKS cluster&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
I'll use the &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster" rel="noopener noreferrer"&gt;terraform module&lt;/a&gt; that I've created before &lt;br&gt;
that module will create a VPC containing 2 public subnets with its public route tables, internet gateway attached to the VPC, and EKS cluster on it with two worker nodes.&lt;/p&gt;

&lt;p&gt;please have a look at &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster#:~:text=in%20more%20details-,Getting%20started,-There%20are%20two" rel="noopener noreferrer"&gt;Getting started&lt;/a&gt; part in the README to see how to use it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

module "public_eks_cluster" {
  source         = "git::https://github.com/Noura98Houssien/simple-EKS-cluster.git?ref=v0.0.1"
  vpc_name       = "my-VPC1"
  cluster_name   = "my-EKS1"
  desired_size   = 2
  max_size       = 2
  min_size       = 1
  instance_types = ["t3.medium"]
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2- Create Ingress NGINX controller&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller/blob/master/nginx-ingress-controller.tf" rel="noopener noreferrer"&gt;nginx-ingress-controller.tf&lt;/a&gt; file I installed the Nginx controller using helm chart &lt;code&gt;nginx-ingress-controller&lt;/code&gt; from the repository &lt;code&gt;https://charts.bitnami.com/bitnami&lt;/code&gt; via helm release resource in Terraform.&lt;/p&gt;

&lt;p&gt;helm is a package manager that helps you define, install, and upgrade applications running on Kubernetes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "helm_release" "nginx-ingress-controller" {
  name       = "nginx-ingress-controller"
  repository = "https://charts.bitnami.com/bitnami"
  chart      = "nginx-ingress-controller"


  set {
    name  = "service.type"
    value = "LoadBalancer"
  }

}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The helm chart will create in a default namespace 2 replicas, 2 deployments, 2 pods, and 2 services for the Nginx ingress controller we will use that service with the type of Load balancer, and that LB will listen on ports 80 and 443 to expose our application from the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3- Create PODs for app1 and app2&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
In &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller/blob/master/k8s-pods.tf" rel="noopener noreferrer"&gt;k8s-pods.tf&lt;/a&gt; file I created two pods one for app1 and another one for app2 &lt;br&gt;
here is an example of creating a pod for app1 and the same will be for app2 but with different values.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;metadata&lt;/code&gt; section we define the pod name &lt;code&gt;my-app1&lt;/code&gt; and give it the label &lt;code&gt;app&lt;/code&gt; with the value &lt;code&gt;app1&lt;/code&gt;&lt;br&gt;
and that label we will use to select a pod while creating a service.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;spec&lt;/code&gt; section we define the container required parameters like container &lt;code&gt;name&lt;/code&gt; "my-app1", and an &lt;code&gt;image&lt;/code&gt; name "hashicorp/http-echo" this image will display the text message as in &lt;code&gt;args&lt;/code&gt; parameter "Hello from my app 1".&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "kubernetes_pod_v1" "app1" {
  metadata {
    name = "my-app1"
    labels = {
      "app" = "app1"
    }
  }

  spec {
    container {
      image = "hashicorp/http-echo"
      name  = "my-app1"
      args  = ["-text=Hello from my app 1"]
    }
  }
}



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;4- Create Services for app1 and app2&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
In &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller/blob/master/k8s-services.tf" rel="noopener noreferrer"&gt;k8s-services.tf&lt;/a&gt; file I created two services one for my-app1 pod and another one for my-app2 pod&lt;br&gt;
that we created in the previous step.&lt;/p&gt;

&lt;p&gt;Here is an example of creating a service for the "my-app1" pod and the same will be for the "my-app2" pod but with different values.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;metadata&lt;/code&gt; section define the service &lt;code&gt;name&lt;/code&gt; "my-app1-service" and in the &lt;code&gt;spec&lt;/code&gt; section select the pod that should be behind that service by using the same label we created in the pod resource.&lt;br&gt;
the &lt;code&gt;kubernetes_pod_v1.app1.metadata.0.labels.app&lt;/code&gt; should give us the value of the label &lt;code&gt;app&lt;/code&gt; in the "my-app1" pod which is "app1".and also we should define which port the service will listen to.&lt;br&gt;
the 5678 is the default port for the hashicorp image.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "kubernetes_service_v1" "app1_service" {
  metadata {
    name = "my-app1-service"
  }
  spec {
    selector = {
      app = kubernetes_pod_v1.app1.metadata.0.labels.app
    }
    port {
      port = 5678
    }
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;5- Create Ingress resource&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
In &lt;a href="https://github.com/Noura98Houssien/simple-nginx-ingress-controller/blob/master/k8s-ingress.tf" rel="noopener noreferrer"&gt;k8s-ingress.tf&lt;/a&gt; file I created an Ingress resource where we will define a collection of routing rules that govern how external users access services running inside a Kubernetes cluster.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "kubernetes_ingress_v1" "ingress" {
  wait_for_load_balancer = true
  metadata {
    name = "simple-fanout-ingress"
  }

  spec {
    ingress_class_name = "nginx"

    rule {
      http {
        path {
          backend {
            service {
              name = "my-app1-service"
              port {
                number = 5678
              }
            }
          }

          path = "/app1"
        }

        path {
          backend {
            service {
              name = "my-app2-service"
              port {
                number = 5678
              }
            }
          }

          path = "/app2"
        }
      }
    }

  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we have 2 paths, for the /app1 path the backend will be "my-app1-service" which means if the user writes "/app1" at the end of the Loadbalancer URL he should see the hello message from app1 &lt;/p&gt;

&lt;p&gt;and for the /app2 path the backend will be "my-app2-service" &lt;br&gt;
that means if the user writes "/app2" at the end of the Loadbalancer URL he should see the hello message from app2 &lt;/p&gt;

&lt;p&gt;Let's run the code to get the Load Balancer URL -that comes after creating the ingress controller- and test those paths&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;6- Run the code&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;git clone &lt;code&gt;https://github.com/Noura98Houssien/simple-nginx-ingress-controller.git&lt;/code&gt;&lt;br&gt;
cd &lt;code&gt;simple-nginx-ingress-controller/examples&lt;/code&gt;&lt;br&gt;
&lt;code&gt;terraform init&lt;/code&gt;&lt;br&gt;
&lt;code&gt;terraform plan&lt;/code&gt;&lt;br&gt;
&lt;code&gt;terraform apply&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Plan: 23 to add, 0 to change, 0 to destroy.
Outputs:
k8s_service_ingress_elb = "aa593a2f34eb34e7daf843d81ba15480-956643453.us-east-1.elb.amazonaws.com"


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;7- Try to connect to your PODs using the LoadBalancer URL&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;after applying the code you get the output &lt;code&gt;k8s_service_ingress_elb&lt;/code&gt;&lt;br&gt;
or you can get it from the services running in the cluster&lt;/p&gt;

&lt;p&gt;To see the services you need first get into your cluster &lt;br&gt;
&lt;code&gt;aws eks update-kubeconfig --region region-code --name my-cluster&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;that will update your &lt;code&gt;kubectl&lt;/code&gt; config file&lt;br&gt;
then write that command to see the services created in the default namespace &lt;code&gt;kubectl get svc&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

nginx-ingress-controller                   LoadBalancer   172.20.184.7     aa593a2f34eb34e7daf843d81ba15480-956643453.us-east-1.elb.amazonaws.com   80:30047/TCP,443:31165/TCP   13m
nginx-ingress-controller-default-backend   ClusterIP      172.20.231.41    &amp;lt;none&amp;gt;                                                                   80/TCP                       13m


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;copy and past that URL in your browser and type /app1 at the end of the URL&lt;br&gt;
you should see the page with a message "Hello from my app 1"&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lcwpu9yvh66tfp9t2hc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lcwpu9yvh66tfp9t2hc.png" alt="app1 url"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi51544n2ftggydr4g2gd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi51544n2ftggydr4g2gd.png" alt="app1 message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do the same for the /app2 and you should see the page with a message "Hello from my app 2"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7edtu5vubhsqs1opf7qm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7edtu5vubhsqs1opf7qm.png" alt="app2 url"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7xa1xcgq3gji6sg1h5l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7xa1xcgq3gji6sg1h5l.png" alt="app2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;8- Clean Up&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform destroy&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Plan: 0 to add, 0 to change, 23 to destroy.
Changes to Outputs:
  - k8s_service_ingress_elb = "aa593a2f34eb34e7daf843d81ba15480-956643453.us-east-1.elb.amazonaws.com" -&amp;gt; null


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Summary:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, I explained what ingress and ingress controllers are and how to use them. I created a simple example without diving too deep into complex details to keep it as simple as possible. I hope this has added new value to your knowledge.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>containerapps</category>
      <category>ingresscontroller</category>
    </item>
    <item>
      <title>Create a simple EKS cluster</title>
      <dc:creator>Noura Hussein</dc:creator>
      <pubDate>Fri, 21 Oct 2022 01:15:03 +0000</pubDate>
      <link>https://dev.to/aws-builders/create-a-simple-eks-cluster-394a</link>
      <guid>https://dev.to/aws-builders/create-a-simple-eks-cluster-394a</guid>
      <description>&lt;p&gt;Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that you can use to run Kubernetes on AWS without needing to install, operate, and maintain your own Kubernetes control plane or nodes. Kubernetes is an open-source system for automating the deployment, scaling, and management of containerized applications.&lt;/p&gt;

&lt;p&gt;In this article I'll help you to create a simple, default cluster without expanding into all of the available options. By using infrastructure as a code tool (IAC) &lt;strong&gt;&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;HashiCorp Terraform&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;br&gt;
1- Terraform Tool: An IAC tool, use version &amp;gt;= 0.13.1.&lt;br&gt;
2- AWS CLI: A command line tool for working with Amazon EKS.&lt;br&gt;
3- &lt;code&gt;kubectl&lt;/code&gt;: A command line tool for working with Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;I've created the all next steps in my &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; please follow the Getting started part in the readme to see how to use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to create your first EKS cluster:&lt;/strong&gt;&lt;br&gt;
1- Create VPC and subnets that meet &lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/network_reqs.html" rel="noopener noreferrer"&gt;Amazon EKS requirements&lt;/a&gt;&lt;br&gt;
2- Create Amazon EKS cluster with required IAM role.&lt;br&gt;
3- Create Amazon EKS node group with required IAM role.&lt;br&gt;
4- Run the code &lt;br&gt;
5- Get into the cluster &lt;br&gt;
6- Clean up &lt;/p&gt;

&lt;p&gt;So lets start with the first step..&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;1-Create VPC and subnets&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you create a cluster, you specify a VPC and at least two subnets that are in different Availability Zones.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;VPC requirements and considerations:&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
in the &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster/blob/master/vpc.tf" rel="noopener noreferrer"&gt;vpc.tf&lt;/a&gt; file I called the VPC module created by terraform with the required parameters to create VPC that meets the requirements of EKS cluster creation.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

locals {
  region = data.aws_region.current.name
}
module "vpc" {
  source                  = "git::https://github.com/terraform-aws-modules/terraform-aws-vpc.git?ref=v3.16.0"
  name                    = var.vpc_name
  cidr                    = var.vpc_cidr
  azs                     = ["${local.region}a", "${local.region}b"]
  public_subnets          = cidrsubnets(var.vpc_cidr, 1, 1)
  enable_dns_hostnames    = true
  enable_dns_support      = true
  map_public_ip_on_launch = true

  tags = {
    Name = var.vpc_name
  }
  public_subnet_tags = {
    Name                                        = "public subnet"
    "kubernetes.io/role/elb"                    = "1"
    "kubernetes.io/cluster/${var.cluster_name}" = "shared"
  }


}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;The VPC must have a sufficient number of IP addresses available for the cluster, any nodes, and other Kubernetes resources that you want to create.&lt;/li&gt;
&lt;li&gt;The VPC must have DNS hostname and DNS resolution support. Otherwise, nodes can't register to your cluster.&lt;/li&gt;
&lt;li&gt;The VPC might require VPC endpoints using AWS PrivateLink. we need this in cases if we want to create a private cluster but for simplicity, I'll create a public cluster so there is no need for this now. However, AWS recommends creating a private cluster for the production workload.&lt;a href="https://docs.aws.amazon.com/eks/latest/userguide/cluster-endpoint.html" rel="noopener noreferrer"&gt;read more about public and private cluster&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Subnets requirements and considerations:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The subnets must have enough available IP addresses to deploy all of your nodes and Kubernetes resources to. AWS recommend at least 16 IP addresses.&lt;/li&gt;
&lt;li&gt;The subnets can be a public or private in our case will create public subnets.&lt;/li&gt;
&lt;li&gt;The public subnet must auto-assign IPv4 because we will deploy the nodes on it.&lt;/li&gt;
&lt;li&gt;If you want to deploy load balancers to a subnet, the subnet must have the following tag:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Key                                 Value
kubernetes.io/role/elb                  1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;If you use Version 2.1.1 or earlier of the AWS Load Balancer Controller requires the following tag:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Key                                 Value
kubernetes.io/cluster/my-cluster    shared


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;at the end of this step, we will have vpc created with 2 public subnets in a different availability zone, public route table and internet gateway.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29sdmyysg8ve19r0jp2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29sdmyysg8ve19r0jp2j.png" alt="eks vpc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2-Create Amazon EKS cluster with required IAM role&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes clusters managed by Amazon EKS make calls to other AWS services on your behalf to manage the resources that you use with the service. Before you can create Amazon EKS clusters, you must create an IAM role with the following IAM policies:
&lt;code&gt;"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"&lt;/code&gt;
&lt;code&gt;"arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a default cluster (public) and specify the subnet ids to be the public subnet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and that all in &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster/blob/master/eks-cluster.tf" rel="noopener noreferrer"&gt;eks-cluster.tf&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "aws_iam_role" "eksClusterRole" {
  name = "eksClusterRole"

  assume_role_policy = &amp;lt;&amp;lt;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.eksClusterRole.name
}

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

resource "aws_eks_cluster" "this" {
  name     = var.cluster_name
  role_arn = aws_iam_role.eksClusterRole.arn

  vpc_config {
    subnet_ids = module.vpc.public_subnets
  }

  # Ensure that IAM Role permissions are created before and deleted after EKS Cluster handling.
  # Otherwise, EKS will not be able to properly delete EKS managed EC2 infrastructure such as Security Groups.
  depends_on = [
    aws_iam_role_policy_attachment.AmazonEKSClusterPolicy,
    aws_iam_role_policy_attachment.AmazonEKSVPCResourceController,
  ]
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;3- Create Amazon EKS node group with required IAM role&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Amazon EKS node kubelet daemon makes calls to AWS APIs on your behalf. Nodes receive permissions for these API calls through an IAM instance profile and associated policies. Before you can launch nodes and register them into a cluster, you must create an IAM role for those nodes to use when they are launched,So you must create an IAM role with the following IAM policies:
&lt;code&gt;"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"&lt;/code&gt;
&lt;code&gt;"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"&lt;/code&gt;
&lt;code&gt;"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a node group in the public subnet and with it's configration(max, min,and desired size) and instance type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and all that in &lt;a href="https://github.com/Noura98Houssien/simple-EKS-cluster/blob/master/eks-node-group.tf" rel="noopener noreferrer"&gt;eks-node-group.tf&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

resource "aws_iam_role" "eksWorkerNodeRole" {
  name = "eksWorkerNodeRole"

  assume_role_policy = jsonencode({
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
    Version = "2012-10-17"
  })
}

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

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

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

resource "aws_eks_node_group" "this" {
  cluster_name    = var.cluster_name
  node_group_name = "${var.cluster_name}-nodeGroup"
  node_role_arn   = aws_iam_role.eksWorkerNodeRole.arn
  subnet_ids      = module.vpc.public_subnets
  instance_types  = var.instance_types
  scaling_config {
    desired_size = var.desired_size
    max_size     = var.max_size
    min_size     = var.min_size
  }

  update_config {
    max_unavailable = 1
  }

  # Ensure that IAM Role permissions are created before and deleted after EKS Node Group handling.
  # Otherwise, EKS will not be able to properly delete EC2 Instances and Elastic Network Interfaces.
  depends_on = [
    aws_eks_cluster.this,
    aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
    aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
    aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
  ]
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;4- Run the code&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git clone https://github.com/Noura98Houssien/simple-EKS-cluster.git&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;cd simple-EKS-cluster&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a file with name terraform.tfvars and copy past the values as in terraform.tfvars.tmpl in example folder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

vpc_name       = "my-VPC1"
vpc_cidr       = "10.0.0.0/16"
cluster_name   = "my-EKS1"
desired_size   = 2
max_size       = 2
min_size       = 1
instance_types = ["t3.medium"]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;terraform plan&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform apply&lt;/code&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfxv692bwn1gbwrhl4sp.png" alt="terraform apply"&gt;
as you can see there are 17 resource will be added.
and there are some outputs will known after apply.
It takes around 10 mins to create.
after the creation your environment will be like that &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3z7biqx93ilqc54wqux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3z7biqx93ilqc54wqux.png" alt="deployment env"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;5- Get into the cluster&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;kubectl&lt;/code&gt; config file by using that command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;aws eks update-kubeconfig --region region-code --name my-cluster&lt;/code&gt;&lt;br&gt;
The example output is as follows.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Added new context arn:aws:eks:region-code:111122223333:cluster/my-cluster to /home/username/.kube/config


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Confirm communication with your cluster by running the following command. &lt;code&gt;kubectl get svc&lt;/code&gt;
The example output is as follows.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.20.0.1   &amp;lt;none&amp;gt;        443/TCP   15m


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the worker nodes created successfully by running the following command.  &lt;code&gt;kubectl get nodes&lt;/code&gt;
The example output is as follow.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

NAME                          STATUS   ROLES    AGE   VERSION
ip-10-0-171-51.ec2.internal   Ready    &amp;lt;none&amp;gt;   12m   v1.23.9-eks-ba74326
ip-10-0-94-160.ec2.internal   Ready    &amp;lt;none&amp;gt;   12m   v1.23.9-eks-ba74326


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;6- Clean up&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run that command to remove all resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;terraform destroy&lt;/code&gt;&lt;br&gt;
The example output is as follows.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Plan: 0 to add, 0 to change, 17 to destroy.


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;summary:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
In this article, we learned how to create a simple EKS cluster using Terraform, which is a powerful infrastructure as a code tool.&lt;br&gt;
Hopefully, this has added new value to your knowledge.&lt;/p&gt;

&lt;p&gt;Our next step is to deploy the application into the cluster and make it accessible through the internet. I have explained the process in detail &lt;a href="https://dev.to/aws-builders/create-a-simple-ingress-nginx-controller-on-amazon-eks-cluster-with-full-example-5ei1"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>networking</category>
      <category>eks</category>
    </item>
  </channel>
</rss>
