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.