Thursday 9 May 2024

Provionsing AWS EKS Cluster with Terraform





Source code: Github Link
https://github.com/prasad-moru/aws_eks_terraform.git

├── README.md
├── csi_driver.tf
├── data-source.tf
├── ebs-csi-policy.json
├── ebs_addon.tf
├── eks_cluster.tf
├── oidc_eks.tf
├── outputs.tf
├── providers.tf
├── terraform.tfvars
├── variables.tf
├── vpc.tf
└── worker_nodes.tf


AWS Resources

·                 EC2      
·       AutoScalling Groups
·       IAM
·       Security Groups
·       VPC
·       Subnets
·       RouteTable
·       Internet Gateway
·       Managed Worker Nodes
·       EKS Controller
·       OIDC provider

vpc.tf 

  1. VPC Creation: Defines a VPC with specified CIDR block and enables DNS support and hostnames.

  2. Public Subnets Creation: Creates public subnets within the VPC across multiple availability zones. These subnets have routes for internet traffic and are associated with a route table that directs traffic to an internet gateway.

  3. Private Subnets Creation: Creates private subnets within the VPC across multiple availability zones. These subnets do not have direct internet access and are typically used for resources that should not be publicly accessible.

  4. Internet Gateway: Creates an internet gateway and attaches it to the VPC to allow communication between instances in the VPC and the internet.

  5. Route Tables: Creates a main route table and associates it with the public subnets to route internet-bound traffic through the internet gateway.

  6. NAT Gateway: Creates a NAT gateway in the public subnet to enable instances in the private subnet to initiate outbound traffic to the internet while preventing inbound traffic from reaching those instances directly.

  7. Security Groups: Defines security groups for various components:

    • public_sg: For resources in the public subnet, allowing inbound traffic on ports 80 and 443 and outbound traffic to anywhere.
    • data_plane_sg: For worker nodes, allowing inbound traffic from other worker nodes within the VPC and from specified subnets, and allowing outbound traffic to anywhere.
    • control_plane_sg: For control plane components, allowing inbound traffic from worker nodes within the VPC and allowing outbound traffic to anywhere.
  8. Security Group Rules: Defines specific ingress and egress rules for each security group to control traffic flow.



csi_driver.tf

  1. data "aws_iam_policy_document" "csi": This data block fetches information to create an IAM policy document. It defines a policy statement that allows assuming a role with web identity under certain conditions. The condition checks if the subject of the web identity token (JWT) matches a specific service account (kube-system:ebs-csi-controller-sa) from the EKS cluster. This is often used for granting specific permissions to Kubernetes service accounts running in your EKS cluster.

  2. resource "aws_iam_role" "eks_ebs_csi_driver": This resource block defines an IAM role named eks-ebs-csi-driver. The assume_role_policy attribute is set to the JSON representation of the IAM policy document defined in the data block. This IAM role is intended to be assumed by entities that match the conditions specified in the policy document.

  3. resource "aws_iam_role_policy_attachment" "amazon_ebs_csi_driver": This resource block attaches the IAM policy AmazonEBSCSIDriverPolicy to the IAM role eks_ebs_csi_driver. This policy provides the necessary permissions for the Amazon EBS CSI driver to interact with AWS services.


data-source.tf


  • data "aws_availability_zones" "available": This block defines a data source named available that queries AWS for information about available Availability Zones. The state parameter specifies that it should fetch information about currently available zones.

This data source is useful for dynamically discovering the availability zones in which you can deploy resources within your Terraform configurations. It can be particularly handy when you want to ensure high availability or distribute resources across multiple zones for fault tolerance.

ebs-csi-policy.json


  1. The first statement allows various EC2 actions on all resources.
  2. The second statement allows creating tags for EC2 volumes and snapshots, but only when the action is "CreateVolume" or "CreateSnapshot".
  3. The third statement allows deleting tags from EC2 volumes and snapshots.
  4. The fourth statement allows creating volumes when the request has a specific tag ("ebs.csi.aws.com/cluster" with the value "true").
  5. The fifth statement allows creating volumes when the request has a tag named "CSIVolumeName" with any value.
  6. The sixth statement allows deleting volumes when the resource has a specific tag ("ebs.csi.aws.com/cluster" with the value "true").
  7. The seventh statement allows deleting volumes when the resource has a tag named "CSIVolumeName" with any value.
  8. The eighth statement allows deleting volumes when the resource has a tag named "kubernetes.io/created-for/pvc/name" with any value.
  9. The ninth statement allows deleting snapshots when the resource has a tag named "CSIVolumeSnapshotName" with any value.
  10. The tenth statement allows deleting snapshots when the resource has a specific tag ("ebs.csi.aws.com/cluster" with the value "true").

ebs_addon.tf

  • resource "aws_eks_addon" "csi_driver": This declares a resource named csi_driver of type aws_eks_addon, which represents an addon for an EKS cluster.

    • cluster_name: Specifies the name of the EKS cluster to which the addon will be applied. It references the name attribute of an existing EKS cluster resource (aws_eks_cluster.this.name).

    • addon_name: Specifies the name of the addon being added to the EKS cluster, which is "aws-ebs-csi-driver" in this case.

    • addon_version: Specifies the version of the addon to be installed. Here, it's set to "v1.23.0-eksbuild.1".

    • service_account_role_arn: Specifies the ARN (Amazon Resource Name) of the IAM role that will be used by the addon. It references the ARN of an IAM role defined elsewhere in the Terraform configuration (aws_iam_role.eks_ebs_csi_driver.arn).

eks_cluster.tf

  1. EKS Cluster:

    • resource "aws_eks_cluster" "this": Defines the EKS cluster.
      • name: Specifies the name of the cluster using a variable.
      • role_arn: Specifies the ARN of the IAM role for the EKS cluster. It references an IAM role defined elsewhere in the configuration.
      • version: Specifies the Kubernetes version for the cluster.
      • vpc_config: Configures the VPC settings for the cluster, including subnet IDs, endpoint access settings, and CIDR blocks for public access.
      • tags: Assigns tags to the EKS cluster.
      • depends_on: Specifies dependencies, ensuring that the EKS cluster is created after the IAM role policy attachment.
  2. EKS Cluster IAM Role:

    • resource "aws_iam_role" "cluster": Defines the IAM role for the EKS cluster.
      • name: Specifies the name of the IAM role.
      • assume_role_policy: Defines the trust policy allowing the EKS service to assume this role.
  3. EKS Cluster IAM Role Policy Attachment:

    • resource "aws_iam_role_policy_attachment" "cluster_AmazonEKSClusterPolicy": Attaches the Amazon EKS cluster policy to the IAM role.
      • policy_arn: Specifies the ARN of the Amazon EKS cluster policy.
      • role: Specifies the name of the IAM role to which the policy is attached.
  4. EKS Cluster Security Group:

    • resource "aws_security_group" "eks_cluster": Defines the security group for the EKS cluster.
      • name: Specifies the name of the security group.
      • description: Provides a description for the security group.
      • vpc_id: Specifies the ID of the VPC to which the security group belongs.
      • tags: Assigns tags to the security group.
  5. Security Group Rules:

    • resource "aws_security_group_rule" "cluster_inbound": Allows inbound traffic from worker nodes to the EKS cluster API server on port 443.
    • resource "aws_security_group_rule" "cluster_outbound": Allows outbound traffic from the EKS cluster API server to worker nodes on ports 1024-65535.

oidc_eks.tf

  1. Data Source for TLS Certificate:

    • data "tls_certificate" "eks": This data source retrieves a TLS certificate from the provided URL, which is the issuer URL of the OIDC identity provider associated with the EKS cluster.
      • url: Specifies the URL from which to retrieve the TLS certificate.
  2. AWS IAM OpenID Connect Provider:

    • resource "aws_iam_openid_connect_provider" "eks": This resource defines an OIDC provider for AWS IAM.
      • client_id_list: Specifies a list of client IDs that are associated with the provider. In this case, it includes only the client ID for the AWS Security Token Service (STS).
      • thumbprint_list: Specifies a list of certificate thumbprints that are associated with the provider. Here, it uses the SHA-1 fingerprint of the TLS certificate retrieved from the data source.
      • url: Specifies the URL of the OIDC provider. It references the same issuer URL used in the data source.

These configurations ensure that an OIDC provider is set up correctly for the EKS cluster, allowing integration with IAM for authentication and authorization purposes. The TLS certificate is used to establish trust between the OIDC provider and AWS services like IAM.


outputs.tf


  1. Cluster Name Output:

    • output "cluster_name": This output block defines an output named cluster_name.
      • value: Specifies the value of the output, which is the name of the EKS cluster (aws_eks_cluster.this.name).
  2. Cluster Endpoint Output:

    • output "cluster_endpoint": This output block defines an output named cluster_endpoint.
      • value: Specifies the value of the output, which is the endpoint URL of the EKS cluster (aws_eks_cluster.this.endpoint).
  3. Cluster CA Certificate Output:

    • output "cluster_ca_certificate": This output block defines an output named cluster_ca_certificate.
      • value: Specifies the value of the output, which is the CA (Certificate Authority) certificate data of the EKS cluster (aws_eks_cluster.this.certificate_authority[0].data).

These outputs provide essential information about the EKS cluster, such as its name, endpoint URL, and CA certificate data, which can be used for various purposes such as configuring Kubernetes clients, accessing the cluster programmatically, or providing information to users.


providers.tf


  • Terraform Block:

    • required_version: Specifies the minimum Terraform version required to apply this configuration. In this case, it's set to ">= 1.1.0", meaning Terraform version 1.1.0 or later is needed.
    • required_providers: Specifies the required providers and their versions.
      • aws: Specifies the AWS provider.
        • source: Specifies the source of the provider. In this case, it's "hashicorp/aws", which is the official AWS provider maintained by HashiCorp.
        • version: Specifies the version constraints for the provider. Here, it's set to "~> 4.0", meaning any version in the 4.x series is acceptable.
  • Provider Block:

    • provider "aws": Configures the AWS provider.
      • region: Specifies the AWS region to use. It's set to a variable var.region, meaning the region will be provided as input when applying the Terraform configuration.
      • access_key: Specifies the AWS access key to use for authentication. It's set to a variable var.aws_access_key, which likely holds the access key as sensitive input.
      • secret_key: Specifies the AWS secret key to use for authentication. It's set to a variable var.aws_secret_key, which likely holds the secret key as sensitive input.

This configuration sets up Terraform to use the AWS provider with specified region and authentication credentials, ensuring that the correct provider version is used and that the necessary AWS resources are managed appropriately.


terraform.tfvars


  1. aws_access_key: Your AWS access key. This is used for authentication with AWS services.

  2. aws_secret_key: Your AWS secret key. Like the access key, this is used for authentication with AWS services.

  3. region: The AWS region in which you want to deploy your infrastructure. In this case, it's set to "us-east-1".

  4. availability_zones_count: The number of availability zones you want to deploy resources in. It's set to 2.

  5. project: The name of your project or application. It's set to "TFEKSWorkshop".

  6. vpc_cidr: The CIDR block for your Virtual Private Cloud (VPC). In this example, it's set to "10.0.0.0/16".

  7. subnet_cidr_bits: The number of bits to allocate for subnet CIDR blocks. It's set to 8, which means each subnet will have a CIDR block with a prefix length of /24 (since there are 256 possible IP addresses in a /24 subnet).

These values will be used in your Terraform configuration to provision AWS resources according to your specifications. Make sure to replace "place_your_aws_access_key" and "place_your_aws_secret_key" with your actual AWS credentials before running the Terraform script. Additionally, ensure that you have appropriate permissions set up in AWS for the provided access key and secret key.

variables.tf

variables.tf file defines Terraform variables for your AWS access key, AWS secret key, region, availability zone count, project name, VPC CIDR block, subnet CIDR bits,

These variables provide flexibility and customization options for your Terraform configuration, allowing you to easily adjust settings such as region, VPC configuration, and resource tagging according to your requirements.

vpc.tf

This Terraform configuration defines several AWS resources for setting up a VPC with public and private subnets, an internet gateway, route tables, NAT gateway, security groups, and associated rules. Here's a brief overview:

  1. VPC (aws_vpc): Creates a Virtual Private Cloud with DNS support enabled.

  2. Public Subnets (aws_subnet): Creates public subnets within the VPC, each associated with an availability zone. Public subnets typically host resources that need to be publicly accessible, such as load balancers.

  3. Private Subnets (aws_subnet): Creates private subnets within the VPC, also associated with availability zones. Private subnets typically host resources that should not be publicly accessible, such as database servers.

  4. Internet Gateway (aws_internet_gateway): Attaches an internet gateway to the VPC to enable internet access for resources in the public subnets.

  5. Route Tables (aws_route_table): Creates route tables for the VPC. The main route table is associated with the public subnets and routes internet-bound traffic through the internet gateway.

  6. Route Table Associations (aws_route_table_association): Associates the public subnets with the main route table to enable routing of internet-bound traffic.

  7. NAT Gateway (aws_nat_gateway): Creates a NAT gateway in a public subnet to allow private subnets to initiate outbound internet traffic while keeping resources within private subnets secure.

  8. Route (aws_route): Adds a route to the main route table for directing internet-bound traffic through the NAT gateway.

  9. Security Groups (aws_security_group): Defines security groups for public, data plane, and control plane resources, allowing control over inbound and outbound traffic.

  10. Security Group Rules (aws_security_group_rule): Configures rules for allowing inbound and outbound traffic for various security groups.

This configuration provides a basic setup for a VPC with public and private subnets, ensuring proper routing and security measures are in place for resources deployed within the VPC.

worker_nodes.tf


  1. EKS Node Group (aws_eks_node_group): Defines an EKS node group within the cluster. It specifies parameters such as the cluster name, node group name, node role ARN, subnet IDs, scaling configuration, instance type, etc. This resource manages the underlying EC2 instances in the node group.

  2. EKS Node IAM Role (aws_iam_role): Creates an IAM role for EKS nodes. This role allows EC2 instances in the node group to assume the role, enabling them to interact with other AWS services.

  3. IAM Role Policy Attachments: Attaches policies to the IAM role for EKS nodes. These policies grant necessary permissions to the nodes for interacting with EKS, EC2, networking, and EBS CSI drivers.

  4. EKS Node Security Group (aws_security_group): Defines a security group for EKS nodes. This security group controls inbound and outbound traffic for the nodes within the cluster.

  5. Security Group Rules: Configures rules for the EKS node security group to allow communication between nodes, inbound traffic from the cluster control plane, and outbound internet access.

Overall, this configuration ensures that EKS node groups have the required permissions and network configurations to function within the Kubernetes cluster securely.