Transcript for:
Amazon EKS Tutorial: Part 1

This is the first part of the Amazon EKS tutorial. Here, we're going to create all  the necessary network components,   starting with a VPC using Terraform. Terraform is widely adopted  and is the de facto standard   in our industry for managing infrastructure. We'll start by creating four different subnets,   two private and two public, in  two different availability zones. EKS requires you to provide multiple subnets  in at least two different availability zones. We'll use private subnets to deploy Kubernetes   nodes and use public subnets to provision  network and application load balancers. Later in the tutorial, we'll use both  the native Ingress provided by the AWS   LoadBalancer Controller as well as the  open-source NGINX Ingress Controller,   and secure it with a TLS certificate. We'll also cover the necessary subnet tags that   must be present for EKS to  properly discover subnets. Then, we'll create an internet  gateway and attach it to our VPC. It is used to provide internet  access to any virtual machines   that have a public IP address and  are located in public subnets. Then, we'll create a NAT gateway and  place it in one of the public subnets. It is used to translate private virtual  machine IP addresses located in private   subnets to a public one, and it allows  internet access within private subnets. Then, we'll create a public route table with  a default route to the internet gateway. For example, when the destination IP address  of the request is located inside the VPC,   the main route is used, but when the  destination IP address is outside the VPC,   the request will be routed using the default  route, and in this case, the internet gateway. We'll also create another private route table  with a default route to the NAT gateway,   which allows virtual machines with private  IP addresses to reach the internet,   for example, to download a Python  package or access an external API. And finally, we'll attach these route tables to   our four subnets. That would  be the scope of this section. A little bit about AWS network  and Terraform to get you started. You can clone my public GitHub repo to follow  along. I would also suggest deleting all the   Terraform files under the Terraform folder  and creating them with me from scratch. Now personally, I don’t like to  use a lot of variables when I try   to teach something. In production code, you would,   of course, refactor and parameterize most  of the values in the code. But anyway,   let’s define the most common parameters that  we’ll use in Terraform as local variables. First of all, we need to define the  environment variable. We frequently   create multiple environments, such as  development, staging, and production,   in a single AWS account. In order to do  that, we need to use the environment as   a prefix for objects such as IAM roles,  policies, and the EKS clusters themselves. Also, I use numbers to prefix Terraform  files. It’s intentional, just to clarify   the order in which you would create resources.  In real code, you would not use such prefixes.  Then we have a region where we  want to create our infrastructure. When you create an EKS cluster, it requires you  to have multiple subnets in at least two different   availability zones. You can think of an  availability zone as a separate data center,   so this is done to improve your  availability. If something happens   in one zone, you would still  have an operational cluster. Then we have the EKS cluster name, which we will  also use as a prefix for IAM roles and policies,   just in case we create multiple EKS  clusters in the same AWS account. And finally, we need to specify the EKS version;  at this moment, 1.29 is the latest supported   Kubernetes version in AWS. You can always  check this page to find the latest version. Next, let’s create a providers file.  You can think of a provider as a set   of functions specific to a cloud or open-source  project. Of course, we need to define the AWS   provider and specify the region. In this  case, we use the local variable ‘region'. Then we can define some constraints on the  Terraform version and the provider itself.   For example, at this moment 5.49 is the  latest version. Throughout the tutorial,   we’ll use 4 or 5 additional providers such as  Helm, TLS, and Kubernetes. If you create a module,   the best practice is to define the  version constraints for all of them. Next, let’s create a VPC object using Terraform  as well. You would define the CIDR. The most   important part is to come up with a CIDR  range that is large enough and will not clash   with other VPCs or external networks in case  you want to peer VPCs or use site-to-site VPN. Next, let’s enable DNS support in the VPC.  It is a requirement for some add-ons such   as the EFS CSI driver or even client VPN, so I  would suggest keeping this enabled. And finally,   we can define a tag with an environment prefix. Next, we need to create an Internet Gateway.  It is used to provide internet access to public   subnets. First, we need to attach it to the VPC  and additionally add a Name tag. A Name tag, which   starts with a capital 'N,' is a special tag that  will be visible by default in the AWS console. Now let’s create 4 subnets: 2 private and 2  public subnets in 2 different availability zones.  First, let's define the private zone. Attach it to the VPC using resource   reference. Define the CIDR block. I like to  use online CIDR calculators to come up with   ranges. They will show you how many IPs  you have and the last usable IP address.  Next is the availability  zone. This one is us-east-2a.  And we also need to create some tags. First, let’s use the environment prefix,   type of the subnet, and the availability zone.  Next, 'internal-elb' is a special tag that is  used by EKS to create private load balancers   in case you want to expose your service  internally within the VPC. And the last   tag is optional but recommended if you decide  to provision multiple EKS clusters in a single   AWS account. This is the EKS cluster name, and  the value can be either 'owned' or ‘shared'. Next, let’s create another private  subnet with a different CIDR range and   place this subnet in a different  availability zone, us-east-2b. Next, let’s create a public subnet. Use the same  VPC, provide the CIDR range, and also place it in   the first us-east-2a availability zone. Now, some  services and VMs may require public IP addresses,   so let’s enable this. If you create a  Virtual Machine in the public subnet,   AWS automatically assigns it a public  IP address so that it can reach the   internet. Even without this option,  you can assign a public IP manually. Next, we need to define a few tags. The  first one is the same, just a name tag. Then,   a slightly different ELB tag is very important.  EKS will use it to discover subnets to create   public load balancers. And the last is to  establish a relationship with the EKS cluster. And finally, the last public subnet  in the us-east-2b availability zone.   Just make sure that you use a  different CIDR range and zone. So far we have created 4 subnets, but for now,   they are neither public nor private;  they don’t have any default routes. Next, let’s go ahead and create a NAT gateway.  It is used to translate private virtual machine   IP addresses into public ones to provide  internet access to private subnets. But   before we create the NAT, I would highly  recommend allocating a static public IP   manually. We’ll use it in the NAT gateway. In the  future, in case your clients require a webhook or   something similar, you can easily provide  and whitelist this IP address; otherwise,   it will be created and managed  automatically by the NAT gateway. Also, make sure you place the NAT  gateway in one of the public subnets   with a default route to the internet gateway. We can also use a 'depends on' clause to  wait until the internet gateway is created.  The final step for this section is to  create private and public route tables. First of all, let’s create a private table. Define  the CIDR block that indicates the default route,   which means if no other routes match the  request, this route will be used. By 'the   request,' I mean the destination IP address. And  as the gateway, let’s use NAT. So in this case,   if your application wants to send a request and  the destination IP address is not within your   VPC range, it will be routed outside of your VPC  using the NAT gateway. And let’s set a Name tag. Next, let’s create a public route table. The only   difference here is that we use the  internet gateway as a default route. And finally, we need to associate these  two route tables with our 4 subnets. First,   let’s assign the private route table  to the first private subnet. Then,   assign it to the second private subnet. Keep  in mind, some may recommend creating multiple   NAT gateways in different availability zones  and creating multiple private route tables.   I have never found this particularly  useful in real environments. Next, assign the public route  table to the 2 public subnets.   That’s pretty much all for the  creation of a VPC from scratch. Let’s switch to the Terraform directory and  initialize the state. Terraform will download   all the providers used in the code and initialize  the local state file. In production, you would   use a remote state in an S3 bucket. I have a  video on best practices if you're interested. Now, just because in the following section  I'll show you how to add additional users   and IAM roles to an EKS cluster,  let me show you from scratch how   to initialize your first default  local profile. For this tutorial,   I’ll be using my own user that is already  placed in the Admin group, but I still need   to generate an access key. Let’s go to security  credentials and click on 'Create Access Key’. Now, just to avoid any warnings, let’s select  'Other' for the purpose. And here we go,   we have the credentials. I’ll delete all  the users and keys after this tutorial,   so you will need to generate your own. Now, to create the default profile, you  need to run 'aws configure'. Enter the   key ID and the secret access key.  You can leave other settings empty. Alright, now the AWS Terraform provider  will use this default profile. You can   use other authentication methods;  generally, the best practice is   not to use authentication methods with  long-lived credentials and instead use   IAM roles with short-lived credential tokens.  But that’s out of the scope of this tutorial. So, these are your default  credentials and the default profile.  Alright, let’s go ahead and apply Terraform. It’ll   take maybe 2 or 3 minutes to  create the VPC and subnets. Let me show you in the  console what we have so far. We have a staging-main VPC. 4 subnets: 2 private and two public.  By the way, you may have a default  VPC which is used only in tutorials;   it is never used in real environments so  you can safely delete the default VPC and   all corresponding subnets. It’ll make  your life easier. And just in case you   want it back, it’s very easy to create  a default VPC with one single click. Now, for example, the private subnet  has a default route to the NAT gateway.  And the public subnet has a default  route to the internet gateway.  We also have 2 route tables. An internet gateway.  And the NAT gateway. I have only one; the first  one is from the previous tutorial. Alright,   that’s pretty much all for the first section.