Location>code7788 >text

The most complete Terraform Getting Started tutorial ever, to help you get started without the pitfalls!

Popularity:125 ℃/2024-10-28 09:48:45

In the wave of cloud computing, infrastructure management becomes more and more complex. How to efficiently configure and manage cloud resources has become a challenge that every developer and operations engineer must face.Terraform, as a powerful Infrastructure-as-Code (IaC) tool, provides us with a concise and effective solution.

In this blog, I will delve into the features and usage scenarios of Terraform to help you understand its importance in cloud resource management. At the same time, I'll go through the installation steps of Terraform so you can get started quickly.

This blog is particularly suitable for entry-level readers and is detailed and easy to understand, ensuring that even beginners can follow along smoothly. I will go through the hands-on process of creating various infrastructure resources on AWS using Terraform, including VPCs, subnets, routing tables, gateways, security groups, EC2 instances, EBS volumes, and Elastic IP (EIP). In addition, I will share how to create IAM roles for EKS, define Terraform profiles for EKS, and how to configure IAM roles and node groups for EKS Node Groups to create an EKS cluster step by step.

Each Terraform file will be accompanied by a thorough explanation, allowing you to clearly understand what each line of code means and does. Whether you are new to cloud computing or a professional looking to upgrade your skills, this blog will provide you with practical guidance and insights that will help you step into the world of Terraform with ease. Let's get started on this fun-filled learning journey together!

One,About Terraform

1. Characteristics and scenarios of use

Terraform is an open source Infrastructure as Code (IaC) tool developed by HashiCorp. It allows users to programmatically manage resources for cloud infrastructure, physical devices, and other services through configuration files. Below are some of the key features and usage scenarios of Terraform:

Infrastructure as Code

Terraform uses a simple declarative configuration language (HCL, HashiCorp Configuration Language) to enable users to define and manage their infrastructure. This approach brings several advantages:

  • version control: By storing configuration files in the version control system, users can track historical changes to the infrastructure and easily roll back to a previous state.
  • Sharing and reuse: Configuration files can be shared as part of a codebase, facilitating collaboration and the transfer of best practices among team members.
  • Audit and compliance: Explicit profiles make auditing and compliance checking of infrastructure easy, and inconsistencies can be quickly identified by comparing profiles to actual states.

Multi-Cloud Support

Terraform supports multiple cloud service providers, including AWS, Azure, Google Cloud, AliCloud, etc., allowing users to manage resources from different cloud environments simultaneously in a single profile. This multi-cloud management capability brings the following benefits:

  • dexterity: Enterprises can choose the right cloud service provider based on requirements and cost optimization without having to rewrite a lot of configuration code.
  • disaster recovery: Enables resource backup and failover in different cloud environments to enhance business continuity.
  • integration capability: Services from different cloud providers can be seamlessly integrated to build cross-cloud application architectures.

Status Management

Terraform maintains a file on the current state of the infrastructure (status file) to track and manage the status of resources during subsequent changes. The benefits of state management include:

  • consistency: The status file ensures that user operations on resources are based on the latest state, preventing conflicts caused by concurrent modifications.
  • Change Detection: Before applying a new configuration, Terraform provides a clear change plan based on a comparison of the status file with the configuration file, ensuring that users are aware of upcoming actions.
  • remote state: Support for storing status files on a remote backend (e.g., S3) for easy team collaboration and increased security.

Resource dependency management

Terraform is able to automate the handling of dependencies between resources, ensuring that when resources are created or modified, they are done in the correct order. This reduces the complexity of manually handling dependencies and increases the level of automation. Specifically:

  • automatic sorting: Users do not have to specify the creation order manually, Terraform handles it automatically based on the referential relationships between resources.
  • parallel processing: By recognizing independent resources, Terraform can create or delete resources in parallel, reducing overall execution time.

scalability

Terraform offers a rich set of plug-ins and modules that allow users to customize modules to extend the functionality of Terraform for more complex infrastructure architectures. Extensibility features include:

  • Community Contributions: Terraform has an active community where users can easily find off-the-shelf modules and integrate them, reducing duplication of effort.
  • modular design: Users can encapsulate frequently used configurations into modules to improve reusability and readability of configurations.

Cross-team collaboration

Terraform profiles can be used in conjunction with version control systems such as Git to support team collaboration. Advantages of team collaboration include:

  • Code review:: Team members can review infrastructure changes to ensure that they are fully validated and improve infrastructure stability.
  • transparency:: Through version control, all team members have a clear view of the infrastructure's change history and decision-making process, facilitating knowledge sharing.

Usage Scenarios

  • Creating and managing cloud infrastructure: With Terraform, users can easily create and manage a variety of cloud resources, such as VPCs, EC2 instances, RDS databases, EKS clusters, and more, improving management efficiency.
  • Automating Infrastructure in Continuous Integration and Continuous Delivery (CI/CD): Incorporate infrastructure configuration into the CI/CD process to ensure environmental consistency and reduce the risk of manual operations.
  • Configure and manage multiple environments: With Terraform, users can easily configure and manage the infrastructure of their development, test and production environments, ensuring consistency between environments.
  • Infrastructure reuse through modular design: Users can create and share modules to reuse the same infrastructure configuration across projects.

In short, Terraform is a powerful and flexible tool that enables development teams to efficiently manage cloud infrastructure in a code-based manner, improving O&M efficiency and flexibility. With Terraform, users can automate and standardize on multi-cloud environments and adapt to rapidly changing business needs.

2. Terraform principles and workflows

Terraform is an Infrastructure as Code (IaC) tool that manages infrastructure through several steps:

  1. Configuration file (.tf file): The user first defines the required infrastructure by writing Terraform configuration files. These files use the HCL (HashiCorp Configuration Language) language, which describes the types, attributes, and configurations of the resources.

  2. Initialization (terraform init): Before starting to use Terraform, users need to run theterraform init command. This step initializes the working directory, downloads the required providers (e.g. AWS, Azure, etc.), and prepares for subsequent operations.

  3. Generate an execution plan (terraform plan): Useterraform plan command, Terraform reads the configuration file and generates an execution plan showing the actions that will be performed (such as creating, updating, or deleting resources). This step allows the user to preview the upcoming changes and avoid unintended actions.

  4. Application of changes (terraform apply): After confirming the execution plan, the user can run theterraform apply commands, Terraform actually performs the appropriate actions based on the generated plan, creating, updating, or deleting cloud resources.

  5. Status Management: Terraform maintains a status file () that documents the current state of the infrastructure. This file is used to track the actual state of resources for comparison and management in subsequent operations.

  6. Change Management: When changes to the infrastructure are required, the user simply modifies the configuration file and repeats the processplan cap (a poem)apply Processes.Terraform automatically recognizes changes to resources and updates them accordingly.

  7. Destruction of resources (terraform destroy): When certain resources are no longer needed, the user can run theterraform destroy command, Terraform removes all resources defined in the configuration file, ensuring a tidy cleanup.

Through these steps, Terraform is able to manage and deploy infrastructure in a consistent and predictable manner, allowing users to maintain control and management of resources throughout the infrastructure lifecycle.

3. Terraform basic usage concepts

3.1 Provider

  • define: Providers are plug-ins for Terraform to interact with external services such as AWS, Azure, Google Cloud, etc. They are responsible for managing the lifecycle of resources.
  • utilization: In document, it is common to define the desired cloud service provider. For example, for AWS, you might write the following:
    terraform {
      required_providers {
        aws = {
          source = "hashicorp/aws"
          version = "~> 3.0"
        }
      }
    }
    
    provider "aws" {
      region = "us-west-1"
    # access_key = var.aws_access_key #This article usesaws cliIt's defined in that piece.key
    # secret_key = var.aws_secret_key
    }
  • Here.required_providers Defines the required AWS providers and their versions.
  • provider The block then sets the specific parameters for accessing the service, such as zones and credentials.

3.2 Terraform Status File

  • define: is a file used by Terraform to track the status of managed resources. It stores detailed information about the current infrastructure.
  • corresponds English -ity, -ism, -ization:: This file helps Terraform to execute the program (terraform plan) and applications (terraform apply) when it comes to knowing which resources have been created and which need to be updated or deleted.
  • caveat:: Status files are sensitive and important, and should be stored securely to avoid direct modification. For added security, it is often recommended to use a remote backend (e.g. S3) to store the status file.

3.3 Terraform configuration files

  • define: Terraform's configuration file begins with.tf is the extension that contains the definition and configuration of all infrastructure resources.
  • element: Each configuration file can contain resource definitions, variables, outputs, and so on. For example. can contain definitions of VPCs, subnets, and EC2 instances.
  • typical example
    resource "aws_vpc" "my_vpc" {
      cidr_block = "10.0.0.0/16"
      enable_dns_support = true
      enable_dns_hostnames = true
    }

3.4 Variable files

  • define: The variable file (usually named) is used to define variables that can be used in more than one place to increase flexibility.
  • utilization: You can reference these variables in your configuration to customize them for different environments (e.g., development, test, production). Example:
    variable "region" {
      description = "The AWS region to deploy resources"
      type        = string
      default     = "us-west-1"
    }

3.5 Output files

  • define: The output file (usually named) is used to define the information that you want to be output after Terraform is executed, making it easy for the user to access key information about the resource.
  • corresponds English -ity, -ism, -ization: The output can be the public IP address of the EC2 instance, security group ID, etc. Example:
    output "instance_ip" {
      value = aws_instance.my_instance.public_ip
    }

Two,environmental preparation

1. Installation of Terraform

Please refer to /terraform/install according to your operating system, this article lists common operating system installation methods.

macOS

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Windows

/terraform/1.9.8/terraform_1.9.8_windows_amd64.zip

Ubuntu/Debian

wget -O- /gpg | sudo gpg --dearmor -o /usr/share/keyrings/
echo "deb [signed-by=/usr/share/keyrings/]  $(lsb_release -cs) main" | sudo tee /etc/apt//
sudo apt update && sudo apt install terraform

CentOS/RHEL

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo /RHEL/
sudo yum -y install terraform

2. Configuring the AWS CLI

Ensure that the configured access key has sufficient privileges.

Details are available:/Sunzz/p/18432935

2.1 Creation~/.aws/config file

The content is as follows:

[default]
region = us-west-1

In which region please modify according to your actual situation can be

2.2 Creation~/.aws/credentials file

The content is as follows:

[default]
aws_access_key_id = AKIA2LXD....
aws_secret_access_key = ZvQllpYL.....

Reproduced with the famous original address:/Sunzz/p/18498915

3. Initializationterraform

3.1 Creationfile

Used to store variables that are used multiple times

The content is as follows:

variable "aws_region" {
  default = "us-west-1"
}

Defines the region to be used, here us-west-1 is used, please modify it according to your actual situation.

3.2 Creation file

The configuration defines what Terraform uses for theproviders

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

account for

  • terraform lump (of earth): Specifies basic settings for Terraform, including dependent providers.

  • required_providers: Define a list of providers that a Terraform project depends on to interact with a particular platform, such as AWS or to generate TLS keys.

    • aws provider

      • source: Specify the source of this provider, i.e.hashicorp/awsIf you are using HashiCorp, you are using the official AWS provider published by HashiCorp.
      • version: Specify the use of4.0 version and above, but will not upgrade to the latest version of the5.0 Above.

3.3 Initialization

The initialization process will use some foreign web resources, due to well-known reasons, there may be some problems with the download, here it is recommended to just use your tool directly.

Modify ip and port as appropriate

export https_proxy=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
terraform init

The output is as follows:

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching ">= 4.0.0"...
- Installing hashicorp/aws v5.72.1...
- Installed hashicorp/aws v5.72.1 (signed by HashiCorp)
Terraform has created a lock file . to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

 

Creating aws web resources

Before each creation of this article I create the tf file of the corresponding resource, one tf file for one kind of resource, for example all the ec2 in one file.

Then both will executeterraform plan -out= to preview the results of the execution and prevent errors.

terraform plan -out= It is a "preview" tool. It doesn't actually create or change resources, but generates a detailed plan that tells us "what specific changes will be made if we execute". This plan can be saved as a file (like here)), so that we can check it first to make sure it's okay before we actually go ahead and execute it. This not only reduces the chance of errors, but also lets us know at all times which resources will be created, modified or deleted.

1. Create vpc

Preparation of documents

resource "aws_vpc" "tf_vpc" {
  cidr_block = "10.10.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "tf-vpc"
  }
}

Explanation:

  • resource "aws_vpc" "tf_vpc": Defines an AWS VPC resource with the nametf_vpc. You can reference this name in the Terraform configuration.

  • cidr_block = "10.10.0.0/16": This is the CIDR (Classless Inter-Domain Routing) block of the VPC that specifies the IP address range.10.10.0.0/16 Indicates that this VPC can use the data from the10.10.0.0 until (a time)10.10.255.255 All of the IP addresses of the

  • enable_dns_hostnames = true: Enable DNS hostname. Set totrue When you do, AWS assigns DNS hostnames to the EC2 instances in the VPC so that you can access them by DNS name instead of IP address.

  • enable_dns_support = true: Enable DNS support. This means that VPC will be able to resolve DNS names. This is important for communication between using AWS services and instances within VPC.

  • tags = { Name = "tf-vpc" }: Add tags to VPC. In the AWS console, tags help you identify and manage resources. The label here names the VPC as "tf-vpc".

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_vpc.tf_vpc will be created
  + resource "aws_vpc" "tf_vpc" {
      + arn                                  = (known after apply)
      + cidr_block                           = "10.10.0.0/16"
      + default_network_acl_id               = (known after apply)
      + default_route_table_id               = (known after apply)
      + default_security_group_id            = (known after apply)
      + dhcp_options_id                      = (known after apply)
      + enable_dns_hostnames                 = true
      + enable_dns_support                   = true
      + enable_network_address_usage_metrics = (known after apply)
      + id                                   = (known after apply)
      + instance_tenancy                     = "default"
      + ipv6_association_id                  = (known after apply)
      + ipv6_cidr_block                      = (known after apply)
      + ipv6_cidr_block_network_border_group = (known after apply)
      + main_route_table_id                  = (known after apply)
      + owner_id                             = (known after apply)
      + tags                                 = {
          + "Name" = "tf-vpc"
        }
      + tags_all                             = {
          + "Name" = "tf-vpc"
        }
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Create vpc

terraform apply 
aws_vpc.tf_vpc: Creating...
aws_vpc.tf_vpc: Still creating... [10s elapsed]
aws_vpc.tf_vpc: Creation complete after 13s [id=vpc-0f2e1cdca0cf5a306]

Reproduced with the famous original address:/Sunzz/p/18498915

2. Creating subnets

New variables

do sth (for sb)Add the following:

variable "az_1" {
  description = "Availability Zone for the first subnet"
  type        = string
  default     = "us-west-1a"
}

variable "az_2" {
  description = "Availability Zone for the second subnet"
  type        = string
  default     = "us-west-1b"
}

Explanation:

variable "az_1/2":

  • description: A short description is provided that specifies that this variable represents the first subnet's available zone.
  • type: Specifies that the data type of the variable is a string (string)。
  • default: Set the default value to"us-west-1a/b". If no other value is provided for this variable in the Terraform configuration, this default value will be used.

Files that define the subnet configuration

# Define the first subnet tf-subnet01 (10.10.1.0/24, use variables to specify available zones)
resource "aws_subnet" "tf_subnet01" {
  vpc_id = aws_vpc.tf_vpc.id
  cidr_block = "10.10.1.0/24"
  availability_zone = var.az_1 # Use variables instead of hard-coded availability zones
  tags = {
    Name = "tf-subnet01"
  }
}

# Define the second subnet tf-subnet02 (10.10.2.0/24, use variables to specify availability zones)
resource "aws_subnet" "tf_subnet02" {
  vpc_id = aws_vpc.tf_vpc.id
  cidr_block = "10.10.2.0/24"
  availability_zone = var.az_2
  tags = {
    Name = "tf-subnet02"
  }
}

Explanation:

  • resource "aws_subnet" "tf_subnet01": declaration creates a file namedtf_subnet01 of subnet resources.

  • vpc_id = aws_vpc.tf_vpc.id: Associate this subnet to a previously defined virtual private cloud (VPC).aws_vpc.tf_vpc.id References the ID of a created VPC.

  • cidr_block = "10.10.1.0/24": Defines the CIDR block for the subnet, where it indicates that the IP address range for the subnet is10.10.1.0 until (a time)10.10.1.255The total number of addresses (including network and broadcast addresses) is 256.

  • availability_zone = var.az_1: Specifies the available zone in which this subnet is located, using the previously defined variableaz_1, rather than hard-coding. This makes the configuration more flexible and easier to modify and maintain.

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_subnet.tf_subnet01 will be created
  + resource "aws_subnet" "tf_subnet01" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-west-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.10.1.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "tf-subnet01"
        }
      + tags_all                                       = {
          + "Name" = "tf-subnet01"
        }
      + vpc_id                                         = "vpc-0f2e1cdca0cf5a306"
    }

  # aws_subnet.tf_subnet02 will be created
  + resource "aws_subnet" "tf_subnet02" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-west-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.10.2.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = false
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "tf-subnet02"
        }
      + tags_all                                       = {
          + "Name" = "tf-subnet02"
        }
      + vpc_id                                         = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Creating Subnets

terraform apply ""
terraform apply ""
aws_subnet.tf_subnet01: Creating...
aws_subnet.tf_subnet02: Creating...
aws_subnet.tf_subnet01: Creation complete after 2s [id=subnet-08f8e4b2c62e27989]
aws_subnet.tf_subnet02: Creation complete after 2s [id=subnet-019490723ad3e940a]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

3. Create Gateway

Creating the internet_gateway.tf file that defines a gateway

resource "aws_internet_gateway" "tf_igw" {
  vpc_id = aws_vpc.tf_vpc.id
  tags = {
    Name = "tf-igw"
  }
}

account for

  • resource "aws_internet_gateway" "tf_igw": declaration creates a file namedtf_igw of Internet gateway resources.

  • vpc_id = aws_vpc.tf_vpc.id: Associate this Internet Gateway with a previously created Virtual Private Cloud (VPC). By referencing theaws_vpc.tf_vpc.idto ensure that this gateway can be used with the specified VPC.

  • tags:: Labeling of Internet gateways.Name = "tf-igw". Labels help users manage and identify this resource in the AWS console.

pre-execution

terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_internet_gateway.tf_igw will be created
  + resource "aws_internet_gateway" "tf_igw" {
      + arn      = (known after apply)
      + id       = (known after apply)
      + owner_id = (known after apply)
      + tags     = {
          + "Name" = "tf-igw"
        }
      + tags_all = {
          + "Name" = "tf-igw"
        }
      + vpc_id   = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Perform gateway creation

terraform apply ""

The output is as follows:

aws_internet_gateway.tf_igw: Creating...
aws_internet_gateway.tf_igw: Creation complete after 2s [id=igw-08ec2f3357e8725df]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

4. Creation of routing tables

Define route_table.tf

resource "aws_route_table" "tf_route_table" {
  vpc_id = aws_vpc.tf_vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.tf_igw.id
  }
  tags = {
    Name = "tf-route-table"
  }
}

account for

  • vpc_id = aws_vpc.tf_vpc.id: Associate this routing table with a previously created Virtual Private Cloud (VPC). By referencing theaws_vpc.tf_vpc.id, ensure that the routing table applies to the specified VPC.

  • route { ... }: This block defines a route in the routing table.

    • cidr_block = "0.0.0.0/0":
      • Specify the target CIDR block as0.0.0.0/0, indicating that the route applies to all traffic (i.e., Internet traffic).
    • gateway_id = aws_internet_gateway.tf_igw.id:
      • Points traffic to a previously created Internet gateway. This means that any traffic destined for the Internet will pass through this Internet gateway.

Pre-execute creation of routing tables

terraform plan
 terraform plan -out=

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_route_table.tf_route_table will be created
  + resource "aws_route_table" "tf_route_table" {
      + arn              = (known after apply)
      + id               = (known after apply)
      + owner_id         = (known after apply)
      + propagating_vgws = (known after apply)
      + route            = [
          + {
              + cidr_block                 = "0.0.0.0/0"
              + gateway_id                 = "igw-08ec2f3357e8725df"
                # (12 unchanged attributes hidden)
            },
        ]
      + tags             = {
          + "Name" = "tf-route-table"
        }
      + tags_all         = {
          + "Name" = "tf-route-table"
        }
      + vpc_id           = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Performs the creation of a routing table

terraform apply ""

The output is as follows:

aws_route_table.tf_route_table: Creating...
aws_route_table.tf_route_table: Creation complete after 3s [id=rtb-0ae4b29ae8d6881ed]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

5. Associated routing tables and subnets

Create route_table_association.tf

# Associated subnets and routing tables
resource "aws_route_table_association" "tf_route_table_association_01" {
  subnet_id = aws_subnet.tf_subnet01.id
  route_table_id = aws_route_table.tf_route_table.id
}

resource "aws_route_table_association" "tf_route_table_association_02" {
  subnet_id = aws_subnet.tf_subnet02.id
  route_table_id = aws_route_table.tf_route_table.id
}

account for

  • resource "aws_route_table_association" "tf_route_table_association_01": declaration creates a file namedtf_route_table_association_01 The routing table association resource. This resource is used to associate subnets with routing tables.

  • subnet_id = aws_subnet.tf_subnet01.id: Specify the subnet to associate with, referencing a previously created subnettf_subnet01 ID. which means that this routing table will be applied to all instances in this subnet.

  • route_table_id = aws_route_table.tf_route_table.id: Specify the routing table to associate with, referencing a previously created routing tabletf_route_table ID. by this reference. ensure that the routing table is associated with the specified subnet.

pre-executionterraform plan -out=

View Code
  terraform plan -out=
  
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_route_table_association.tf_route_table_association_01 will be created
  + resource "aws_route_table_association" "tf_route_table_association_01" {
      + id = (known after apply)
      + route_table_id = "rtb-0ae4b29ae8d6881ed"
      + subnet_id = "subnet-08f8e4b2c62e27989"
    }

  # aws_route_table_association.tf_route_table_association_02 will be created
  + resource "aws_route_table_association" "tf_route_table_association_02" {
      + id = (known after apply)
      + route_table_id = "rtb-0ae4b29ae8d6881ed"
      + subnet_id = "subnet-019490723ad3e940a"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to:

To perform exactly these actions, run the following command to apply:
    terraform apply ""
Reproduced with permission from the original source:/Sunzz/p/18498915

executable link

terraform apply ""

The output is as follows:

aws_route_table_association.tf_route_table_association_01: Creating...
aws_route_table_association.tf_route_table_association_02: Creating...
aws_route_table_association.tf_route_table_association_01: Creation complete after 1s [id=rtbassoc-0999e44cc1cfb7f09]
aws_route_table_association.tf_route_table_association_02: Creation complete after 1s [id=rtbassoc-0190cb61bd5850d86]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

iv. creation of ec2

1. Creating key pairs

Generate key pairs

 ssh-keygen -t rsa -b 4096 -f ~/.ssh/tf-keypair

Create the key_pair.tf file

resource "aws_key_pair" "tf-keypair" {
  key_name   = "tf-keypair"
  public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC42p8Ly5xXtaQPbBoKiVVSuU0HKhK38I5DtPhijhZrVZmhRpW5yD6pbCXmFLnIFTFNb....."
}

Explanation:

  • resource "aws_key_pair" "tf-keypair": declaration creates a file namedtf-keypair The key pair resource. This is an AWS EC2 key pair for accessing EC2 instances via SSH.

  • key_name = "tf-keypair": Specify the name of the key pair astf-keypair. In the AWS console, the key pair will be displayed with this name.

  • public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC42p8Ly5xXtaQPbBoKiVVSuU0HKhK38I5DtPhijhZrVZmhRpW5yD6pbCXmFLnIFTFNb.....":

    • Provide the contents of a public key, using the SSH public key format. This public key will be stored in AWS, while the corresponding private key will be held by the user and used to connect to the EC2 instance via SSH.
    • Note: The public key must be in a valid SSH public key format and will usually start with assh-rsa begins, followed by the key data and optional comments.
    • where public_key is theContents of ~/.ssh/

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_key_pair.tf-keypair will be created
  + resource "aws_key_pair" "tf-keypair" {
      + arn             = (known after apply)
      + fingerprint     = (known after apply)
      + id              = (known after apply)
      + key_name        = "tf-keypair"
      + key_name_prefix = (known after apply)
      + key_pair_id     = (known after apply)
      + key_type        = (known after apply)
      + public_key      = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC42p8Ly5xXtaQPbBoKiVVSuU0HKhK38ua0arfBYQF++/QFRJZ7+/fmeES7P0+//+vKjWnwdf67BIu0RyoA+MFpztYn58hDKdAmSeEXCpp4cOojgFmgnf1+p3MdaOvnT379YT....."
      + tags_all        = (known after apply)
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Execute Create Key Pair

terraform apply ""

The results are as follows:

aws_key_pair.tf-keypair: Creating...
aws_key_pair.tf-keypair: Creation complete after 1s [id=tf-keypair]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

2. Create a security group

Create the security_group.tf file

resource "aws_security_group" "tf_security_group" {
  name = "tf-security-group"
  description = "Security group for allowing specific inbound traffic"
  vpc_id = aws_vpc.tf_vpc.id

  # ICMP (ping) Inbound Rules
  ingress {
    from_port = -1
    to_port = -1
    protocol = "icmp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow ICMP (ping) traffic"
  }

  # SSH (22) Inbound Rules
  ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow SSH traffic"
  }

  # HTTP (80) Inbound Rules
  ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow HTTP traffic"
  }

  # HTTPS (443) Inbound Rules
  ingress {
    from_port = 443
    to_port = 443
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow HTTPS traffic"
  }

  # Default Outbound Rules:Allow all outbound traffic
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
    description = "Allow all outbound traffic"
  }

  tags = {
    Name = "tf-security-group"
  }
}

account for

  • ingress rules and regulations
    • icmp Release all ICMP traffic for allowing pinging.
    • tcp The rule releases ports 22 (SSH), 80 (HTTP), 443 (HTTPS).
  • egress rules and regulations
    • All protocols and ports are allowed by default for outbound traffic.

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=
aws_key_pair.tf-keypair: Refreshing state... [id=tf-keypair]
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.tf_security_group will be created
  + resource "aws_security_group" "tf_security_group" {
      + arn                    = (known after apply)
      + description            = "Security group for allowing specific inbound traffic"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow all outbound traffic"
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow HTTP traffic"
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 80
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow HTTPS traffic"
              + from_port        = 443
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 443
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow ICMP (ping) traffic"
              + from_port        = -1
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "icmp"
              + security_groups  = []
              + self             = false
              + to_port          = -1
            },
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = "Allow SSH traffic"
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
        ]
      + name                   = "tf-security-group"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "tf-security-group"
        }
      + tags_all               = {
          + "Name" = "tf-security-group"
        }
      + vpc_id                 = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Perform creation of security groups

terraform apply ""

The output is as follows:

terraform apply ""
aws_security_group.tf_security_group: Creating...
aws_security_group.tf_security_group: Creation complete after 5s [id=sg-0907b4ae2d4bd9592]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

3. Create ec2

Define ami content first to facilitate the direct use of back-end role variables, editingAdded the following. Here amazon linux and ubuntu 24.04 images are used

modifications

variable "amazon_linux_ami" {
  description = "AMI ID for Amazon Linux"
  type = string
  default = "ami-0cf4e1fcfd8494d5b" # Replace yourAmazon Linux AMI ID
}

variable "ubuntu_ami" {
  description = "AMI ID for Ubuntu"
  type = string
  default = "ami-0da424eb883458071" # Replace yourUbuntu 24.04 AMI ID
}

Creating Documents

# first EC2 an actual example
resource "aws_instance" "tf-ec2-01" {
  ami = var.amazon_linux_ami
  instance_type = ""
  subnet_id = aws_subnet.tf_subnet01.id
  key_name = aws_key_pair.tf-keypair.key_name
  vpc_security_group_ids = [aws_security_group.tf_security_group.id]

  root_block_device {
    volume_size = 10
  }

  tags = {
    Name = "tf-ec2-01"
  }
}

# second reason EC2 an actual example
resource "aws_instance" "tf-ec2-02" {
  ami = var.ubuntu_ami
  instance_type = ""
  subnet_id = aws_subnet.tf_subnet02.id
  key_name = aws_key_pair.tf-keypair.key_name
  vpc_security_group_ids = [aws_security_group.tf_security_group.id]

  root_block_device {
    volume_size = 10
  }

  tags = {
    Name = "tf-ec2-02"
  }
}

Configuration

  • AMI ID Parameterization:: To allow flexibility in specifying AMI in different environments
  • instance_type: Specify instance specifications
  • subnet_id: Specify the subnet, here use the previously created
  • Security Groups and Key Pairskey_name and vpc_security_group_ids, respectively, to the previously createdtf-keypair cap (a poem)tf-security-group
  • root_block_device: Willvolume_size Set to 10GB to specify the system disk size for each instance.

Reproduced with the famous original address:/Sunzz/p/18498915

pre-execution

terraform plan -out=
terraform plan
terraform plan -out=
aws_key_pair.tf-keypair: Refreshing state... [id=tf-keypair]
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_security_group.tf_security_group: Refreshing state... [id=sg-0907b4ae2d4bd9592]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.tf-ec2-01 will be created
  + resource "aws_instance" "tf-ec2-01" {
      + ami                                  = "ami-0cf4e1fcfd8494d5b"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = ""
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "tf-keypair"
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = "subnet-08f8e4b2c62e27989"
      + tags                                 = {
          + "Name" = "tf-ec2-01"
        }
      + tags_all                             = {
          + "Name" = "tf-ec2-01"
        }
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = [
          + "sg-0907b4ae2d4bd9592",
        ]

      + capacity_reservation_specification (known after apply)

      + cpu_options (known after apply)

      + ebs_block_device (known after apply)

      + enclave_options (known after apply)

      + ephemeral_block_device (known after apply)

      + maintenance_options (known after apply)

      + metadata_options (known after apply)

      + network_interface (known after apply)

      + private_dns_name_options (known after apply)

      + root_block_device {
          + delete_on_termination = true
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 10
          + volume_type           = (known after apply)
        }
    }

  # aws_instance.tf-ec2-02 will be created
  + resource "aws_instance" "tf-ec2-02" {
      + ami                                  = "ami-0da424eb883458071"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + host_resource_group_arn              = (known after apply)
      + iam_instance_profile                 = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = ""
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = "tf-keypair"
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = "subnet-019490723ad3e940a"
      + tags                                 = {
          + "Name" = "tf-ec2-02"
        }
      + tags_all                             = {
          + "Name" = "tf-ec2-02"
        }
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = [
          + "sg-0907b4ae2d4bd9592",
        ]

      + capacity_reservation_specification (known after apply)

      + cpu_options (known after apply)

      + ebs_block_device (known after apply)

      + enclave_options (known after apply)

      + ephemeral_block_device (known after apply)

      + maintenance_options (known after apply)

      + metadata_options (known after apply)

      + network_interface (known after apply)

      + private_dns_name_options (known after apply)

      + root_block_device {
          + delete_on_termination = true
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 10
          + volume_type           = (known after apply)
        }
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Execute the creation of ec2

terraform apply ""

Output:

aws_instance.tf-ec2-01: Creating...
aws_instance.tf-ec2-02: Creating...
aws_instance.tf-ec2-02: Still creating... [10s elapsed]
aws_instance.tf-ec2-01: Still creating... [10s elapsed]
aws_instance.tf-ec2-01: Creation complete after 16s [id=i-0f8d63e600d93f6b0]
aws_instance.tf-ec2-02: Creation complete after 16s [id=i-0888d477cdf36aea0]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

4. Create ebs

New Culture

resource "aws_ebs_volume" "ebs_ec2_01" {
  availability_zone = var.az_1 # Use variables instead of hard-coded availability zones
  size = 20
  type = "gp3"
  tags = {
    Name = "ebs-ec2-01"
  }
}

resource "aws_ebs_volume" "ebs_ec2_02" {
  availability_zone = var.az_2
  size = 20
  type = "gp3"
  tags = {
    Name = "ebs-ec2-02"
  }
}

account for

  • resource "aws_ebs_volume" "ebs_ec2_01": declaration creates a file namedebs_ec2_01 EBS volume resources.

  • availability_zone = var.az_1: Specify the available zones for this EBS volume, using the previously defined variableaz_1This allows flexibility in selecting the availability zone where the volume is located without hard-coding.

  • size = 20: Sets the size of the EBS volume to 20 GB. this parameter determines the storage capacity of the volume.

  • type = "gp3": Specifies that the type of EBS volume isgp3This is a general-purpose SSD volume type offered by AWS that is suitable for most workloads.

  • tags = { Name = "ebs-ec2-01" }: Add a label to the EBS volume, specifying its name asebs-ec2-01that are easy to identify and manage in the AWS console.

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=
aws_key_pair.tf-keypair: Refreshing state... [id=tf-keypair]
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_security_group.tf_security_group: Refreshing state... [id=sg-0907b4ae2d4bd9592]
aws_instance.tf-ec2-02: Refreshing state... [id=i-0888d477cdf36aea0]
aws_instance.tf-ec2-01: Refreshing state... [id=i-0f8d63e600d93f6b0]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_ebs_volume.ebs_ec2_01 will be created
  + resource "aws_ebs_volume" "ebs_ec2_01" {
      + arn               = (known after apply)
      + availability_zone = "us-west-1a"
      + encrypted         = (known after apply)
      + final_snapshot    = false
      + id                = (known after apply)
      + iops              = (known after apply)
      + kms_key_id        = (known after apply)
      + size              = 20
      + snapshot_id       = (known after apply)
      + tags              = {
          + "Name" = "ebs-ec2-01"
        }
      + tags_all          = {
          + "Name" = "ebs-ec2-01"
        }
      + throughput        = (known after apply)
      + type              = "gp3"
    }

  # aws_ebs_volume.ebs_ec2_02 will be created
  + resource "aws_ebs_volume" "ebs_ec2_02" {
      + arn               = (known after apply)
      + availability_zone = "us-west-1b"
      + encrypted         = (known after apply)
      + final_snapshot    = false
      + id                = (known after apply)
      + iops              = (known after apply)
      + kms_key_id        = (known after apply)
      + size              = 20
      + snapshot_id       = (known after apply)
      + tags              = {
          + "Name" = "ebs-ec2-02"
        }
      + tags_all          = {
          + "Name" = "ebs-ec2-02"
        }
      + throughput        = (known after apply)
      + type              = "gp3"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Perform creation of ebs

terraform apply ""

The output is as follows:

terraform apply ""
aws_ebs_volume.ebs_ec2_02: Creating...
aws_ebs_volume.ebs_ec2_01: Creating...
aws_ebs_volume.ebs_ec2_02: Still creating... [10s elapsed]
aws_ebs_volume.ebs_ec2_01: Still creating... [10s elapsed]
aws_ebs_volume.ebs_ec2_01: Creation complete after 12s [id=vol-0aac9f1302376328a]
aws_ebs_volume.ebs_ec2_02: Creation complete after 12s [id=vol-06bd472f44eadaf02]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

5. Attach an EBS disk to EC2

Added ebs_attachment.tf file

resource "aws_volume_attachment" "attach_ebs_to_ec2_01" {
  device_name = "/dev/xvdh" # Equipment Name,Can be changed on request
  volume_id = aws_ebs_volume.ebs_ec2_01.id
  instance_id = aws_instance.
}

resource "aws_volume_attachment" "attach_ebs_to_ec2_02" {
  device_name = "/dev/xvdh"
  volume_id = aws_ebs_volume.ebs_ec2_02.id
  instance_id = aws_instance.
}

account for

  • resource "aws_volume_attachment" "attach_ebs_to_ec2_01": Declares a file namedattach_ebs_to_ec2_01 The EBS Volume Attachment resource, which is part of theaws_volume_attachment Type. This resource is responsible for associating EBS volumes with EC2 instances.

  • device_name = "/dev/xvdh": Specifies the device name of the EBS volume on the EC2 instance. This is used here as the/dev/xvdh, which can be changed on demand. This name will be used in the instance to refer to this EBS volume.

  • volume_id = aws_ebs_volume.ebs_ec2_01.id: referencing a previously created EBS volumeebs_ec2_01 ID of the resource to specify the volume to be attached. By referencing the ID of a resource, you can ensure that you are operating on the correct resource.

  • instance_id = aws_instance.: references the EC2 instance to which the EBS volume is to be attachedtf-ec2-01 This allows you to explicitly specify which instance will use this EBS volume.

pre-execution

terraform plan -out=
terraform plan
 terraform plan -out=
aws_ebs_volume.ebs_ec2_02: Refreshing state... [id=vol-06bd472f44eadaf02]
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_ebs_volume.ebs_ec2_01: Refreshing state... [id=vol-0aac9f1302376328a]
aws_key_pair.tf-keypair: Refreshing state... [id=tf-keypair]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_security_group.tf_security_group: Refreshing state... [id=sg-0907b4ae2d4bd9592]
aws_instance.tf-ec2-01: Refreshing state... [id=i-0f8d63e600d93f6b0]
aws_instance.tf-ec2-02: Refreshing state... [id=i-0888d477cdf36aea0]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_volume_attachment.attach_ebs_to_ec2_01 will be created
  + resource "aws_volume_attachment" "attach_ebs_to_ec2_01" {
      + device_name = "/dev/xvdh"
      + id          = (known after apply)
      + instance_id = "i-0f8d63e600d93f6b0"
      + volume_id   = "vol-0aac9f1302376328a"
    }

  # aws_volume_attachment.attach_ebs_to_ec2_02 will be created
  + resource "aws_volume_attachment" "attach_ebs_to_ec2_02" {
      + device_name = "/dev/xvdh"
      + id          = (known after apply)
      + instance_id = "i-0888d477cdf36aea0"
      + volume_id   = "vol-06bd472f44eadaf02"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Performing Attachment of Disks

terraform apply ""

Output:

aws_volume_attachment.attach_ebs_to_ec2_01: Creating...
aws_volume_attachment.attach_ebs_to_ec2_02: Creating...
aws_volume_attachment.attach_ebs_to_ec2_02: Still creating... [10s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_01: Still creating... [10s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_01: Still creating... [20s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_02: Still creating... [20s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_02: Still creating... [30s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_01: Still creating... [30s elapsed]
aws_volume_attachment.attach_ebs_to_ec2_02: Creation complete after 33s [id=vai-439503465]
aws_volume_attachment.attach_ebs_to_ec2_01: Creation complete after 33s [id=vai-1312740159]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

6. Create eip and associate eip to ec2 instances

Additional documents

# Create EIP for tf-ec2-01
resource "aws_eip" "tf_eip_01" {
  vpc = true
  tags = {
    Name = "tf-eip-01"
  }
}

# Create EIP for tf-ec2-02
resource "aws_eip" "tf_eip_02" {
  vpc = true
  tags = {
    Name = "tf-eip-02"
  }
}

account for

  • resource "aws_eip" "tf_eip_01": Declares a file namedtf_eip_01 elastic IP resources that are part of theaws_eip Type. Elastic IP is a static IPv4 address provided by AWS that can be dynamically migrated between different EC2 instances.

  • vpc = true: Specifies that this elastic IP is for VPC (Virtual Private Cloud). If set totrueIn the case of a VPC, the resilient IP will be associated with the VPC. This is because the elastic IP address used in VPC is different from the traditional EC2 instance elastic IP.

  • tags = { Name = "tf-eip-01" }: Add a label for this resilient IP with the nametf-eip-01. Tags are used to manage and identify resources, making it easier to find and manage that resource in the AWS console or when using other tools.

Added eip_association.tf file

# related parties EIP until (a time) tf-ec2-01 an actual example
resource "aws_eip_association" "tf_eip_association_01" {
  instance_id = aws_instance.
  allocation_id = aws_eip.tf_eip_01.id
}

# related parties EIP until (a time) tf-ec2-02 an actual example
resource "aws_eip_association" "tf_eip_association_02" {
  instance_id = aws_instance.
  allocation_id = aws_eip.tf_eip_02.id
}

account for

  • resource "aws_eip_association" "tf_eip_association_01": Declares a file namedtf_eip_association_01 resources that are part of theaws_eip_association Type. This resource is used to establish an association between an Elastic IP and an EC2 instance.

  • instance_id = aws_instance.: Specifies the ID of the EC2 instance to be associated with the resiliency IP, which is referenced here as a previously defined EC2 instancetf-ec2-01 The ID of the

  • allocation_id = aws_eip.tf_eip_01.id: Specify the assigned ID of the resilient IP to be associated with, which references a previously created resilient IP.tf_eip_01 The ID of the

pre-execution

terraform plan -out=

terraform plan
terraform plan -out=
aws_key_pair.tf-keypair: Refreshing state... [id=tf-keypair]
aws_ebs_volume.ebs_ec2_01: Refreshing state... [id=vol-0aac9f1302376328a]
aws_ebs_volume.ebs_ec2_02: Refreshing state... [id=vol-06bd472f44eadaf02]
aws_vpc.tf_vpc: Refreshing state... [id=vpc-0f2e1cdca0cf5a306]
aws_internet_gateway.tf_igw: Refreshing state... [id=igw-08ec2f3357e8725df]
aws_subnet.tf_subnet02: Refreshing state... [id=subnet-019490723ad3e940a]
aws_subnet.tf_subnet01: Refreshing state... [id=subnet-08f8e4b2c62e27989]
aws_security_group.tf_security_group: Refreshing state... [id=sg-0907b4ae2d4bd9592]
aws_route_table.tf_route_table: Refreshing state... [id=rtb-0ae4b29ae8d6881ed]
aws_instance.tf-ec2-01: Refreshing state... [id=i-0f8d63e600d93f6b0]
aws_instance.tf-ec2-02: Refreshing state... [id=i-0888d477cdf36aea0]
aws_route_table_association.tf_route_table_association_02: Refreshing state... [id=rtbassoc-0190cb61bd5850d86]
aws_route_table_association.tf_route_table_association_01: Refreshing state... [id=rtbassoc-0999e44cc1cfb7f09]
aws_volume_attachment.attach_ebs_to_ec2_01: Refreshing state... [id=vai-1312740159]
aws_volume_attachment.attach_ebs_to_ec2_02: Refreshing state... [id=vai-439503465]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # aws_eip.tf_eip_01 will be created
  + resource "aws_eip" "tf_eip_01" {
      + allocation_id        = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = (known after apply)
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + tags                 = {
          + "Name" = "tf-eip-01"
        }
      + tags_all             = {
          + "Name" = "tf-eip-01"
        }
      + vpc                  = true
    }

  # aws_eip.tf_eip_02 will be created
  + resource "aws_eip" "tf_eip_02" {
      + allocation_id        = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = (known after apply)
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + tags                 = {
          + "Name" = "tf-eip-02"
        }
      + tags_all             = {
          + "Name" = "tf-eip-02"
        }
      + vpc                  = true
    }

  # aws_eip_association.tf_eip_association_01 will be created
  + resource "aws_eip_association" "tf_eip_association_01" {
      + allocation_id        = (known after apply)
      + id                   = (known after apply)
      + instance_id          = "i-0f8d63e600d93f6b0"
      + network_interface_id = (known after apply)
      + private_ip_address   = (known after apply)
      + public_ip            = (known after apply)
    }

  # aws_eip_association.tf_eip_association_02 will be created
  + resource "aws_eip_association" "tf_eip_association_02" {
      + allocation_id        = (known after apply)
      + id                   = (known after apply)
      + instance_id          = "i-0888d477cdf36aea0"
      + network_interface_id = (known after apply)
      + private_ip_address   = (known after apply)
      + public_ip            = (known after apply)
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Execute create eip and associate ec2

terraform apply ""

The results are as follows:

aws_eip.tf_eip_02: Creating...
aws_eip.tf_eip_01: Creating...
aws_eip.tf_eip_01: Creation complete after 2s [id=eipalloc-0a9cdbc84013614f5]
aws_eip.tf_eip_02: Creation complete after 2s [id=eipalloc-0ed1c932d9a7a305a]
aws_eip_association.tf_eip_association_01: Creating...
aws_eip_association.tf_eip_association_02: Creating...
aws_eip_association.tf_eip_association_02: Creation complete after 1s [id=eipassoc-0b517a49d76639054]
aws_eip_association.tf_eip_association_01: Creation complete after 1s [id=eipassoc-0e0359ad952266802]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Reproduced with the famous original address:/Sunzz/p/18498915

7. View the results of the creation through the control background

As you can see through the console, the instance name, type, availability zone, public IP, security group, key, disk, etc. all match what we defined in tf.

Then log on directly to the server and look at it to make sure the network and security groups are all available

ssh [email protected] -i ~/.ssh/tf-keypair

V. Creation of EKS

1. Network resources required to create an EKS

Create subnets used by eks and associate routing table files

The contents of eks_subnets.tf are as follows

resource "aws_subnet" "tf_eks_subnet1" {
  vpc_id = aws_vpc.tf_vpc.id
  cidr_block = "10.10.81.0/24"
  availability_zone = var.az_1
  map_public_ip_on_launch = true

  tags = {
    Name = "tf_eks_subnet1"
  }
}

resource "aws_subnet" "tf_eks_subnet2" {
  vpc_id = aws_vpc.tf_vpc.id
  cidr_block = "10.10.82.0/24"
  availability_zone = var.az_2
  map_public_ip_on_launch = true

  tags = {
    Name = "tf_eks_subnet2"
  }
}


# Associate routing tables to subnetstf_eks_subnet1
resource "aws_route_table_association" "tf_eks_subnet1_association" {
  subnet_id = aws_subnet.tf_eks_subnet1.id
  route_table_id = aws_route_table.tf_route_table.id
}

# Associate routing tables to subnetstf_eks_subnet2
resource "aws_route_table_association" "tf_eks_subnet2_association" {
  subnet_id = aws_subnet.tf_eks_subnet2.id
  route_table_id = aws_route_table.tf_route_table.id
}

account for

  • resource "aws_subnet" "tf_eks_subnet1": Declares a file namedtf_eks_subnet1 resource of typeaws_subnetwhich is used to create a new subnet.

  • vpc_id = aws_vpc.tf_vpc.id: Specifies the ID of the virtual private cloud (VPC) to which the subnet belongs. here the previously defined VPC is referencedtf_vpc ID to associate this subnet to the appropriate VPC.

  • cidr_block = "10.10.81.0/24": A CIDR block (Classless Inter-Domain Routing) for the specified subnet, which indicates that the IP address range for the subnet is10.10.81.0 until (a time)10.10.81.255The following is a list of all the IP addresses that can be used in the network.

  • availability_zone = var.az_1: Specifies the Availability Zone in which the subnet is located, where the variableaz_1, allowing flexible configuration of the subnet's available zones.

  • map_public_ip_on_launch = true: Specifies whether instances started on this subnet are automatically assigned public IP addresses. Set totrue Indicates that newly started instances will automatically be given public IPs, allowing them to access the Internet directly.

 

  • resource "aws_route_table_association" "tf_eks_subnet1_association": Declares a file namedtf_eks_subnet1_association resource of typeaws_route_table_association, which is used to create associations between routing tables and subnets.

  • subnet_id = aws_subnet.tf_eks_subnet1.id: Specifies the ID of the subnet to be associated with, which is referenced here from the previously defined subnettf_eks_subnet1 The ID of the

  • route_table_id = aws_route_table.tf_route_table.id: Specifies the ID of the routing table to be associated with, which references a previously defined routing table.tf_route_table The ID of the

pre-creation

 terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # aws_route_table_association.tf_eks_subnet1_association will be created
  + resource "aws_route_table_association" "tf_eks_subnet1_association" {
      + id             = (known after apply)
      + route_table_id = "rtb-0ae4b29ae8d6881ed"
      + subnet_id      = (known after apply)
    }

  # aws_route_table_association.tf_eks_subnet2_association will be created
  + resource "aws_route_table_association" "tf_eks_subnet2_association" {
      + id             = (known after apply)
      + route_table_id = "rtb-0ae4b29ae8d6881ed"
      + subnet_id      = (known after apply)
    }

  # aws_subnet.tf_eks_subnet1 will be created
  + resource "aws_subnet" "tf_eks_subnet1" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-west-1a"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.10.81.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "tf_eks_subnet1"
        }
      + tags_all                                       = {
          + "Name" = "tf_eks_subnet1"
        }
      + vpc_id                                         = "vpc-0f2e1cdca0cf5a306"
    }

  # aws_subnet.tf_eks_subnet2 will be created
  + resource "aws_subnet" "tf_eks_subnet2" {
      + arn                                            = (known after apply)
      + assign_ipv6_address_on_creation                = false
      + availability_zone                              = "us-west-1b"
      + availability_zone_id                           = (known after apply)
      + cidr_block                                     = "10.10.82.0/24"
      + enable_dns64                                   = false
      + enable_resource_name_dns_a_record_on_launch    = false
      + enable_resource_name_dns_aaaa_record_on_launch = false
      + id                                             = (known after apply)
      + ipv6_cidr_block_association_id                 = (known after apply)
      + ipv6_native                                    = false
      + map_public_ip_on_launch                        = true
      + owner_id                                       = (known after apply)
      + private_dns_hostname_type_on_launch            = (known after apply)
      + tags                                           = {
          + "Name" = "tf_eks_subnet2"
        }
      + tags_all                                       = {
          + "Name" = "tf_eks_subnet2"
        }
      + vpc_id                                         = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Creating Subnets

terraform apply ""

The output is as follows:

aws_subnet.tf_eks_subnet2: Creating...
aws_subnet.tf_eks_subnet1: Creating...
aws_subnet.tf_eks_subnet1: Still creating... [10s elapsed]
aws_subnet.tf_eks_subnet2: Still creating... [10s elapsed]
aws_subnet.tf_eks_subnet2: Creation complete after 13s [id=subnet-0a30534a829758774]
aws_route_table_association.tf_eks_subnet2_association: Creating...
aws_subnet.tf_eks_subnet1: Creation complete after 13s [id=subnet-01b5d98060f0063ef]
aws_route_table_association.tf_eks_subnet1_association: Creating...
aws_route_table_association.tf_eks_subnet1_association: Creation complete after 1s [id=rtbassoc-08fef5fee4d037035]
aws_route_table_association.tf_eks_subnet2_association: Creation complete after 1s [id=rtbassoc-0ec12dc9868d6316a]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

2. Creation of EKS security groups

eks_security_group.tf

This is just for demonstration purposes, please do not use it in a production environment.

resource "aws_security_group" "eks_allow_all" {
  name = "eks_allow_all"
  description = "Security group that allows all inbound and outbound traffic"
  vpc_id = aws_vpc.tf_vpc.id


  // Allow all inbound traffic
  ingress {
    from_port = 0
    to_port = 0
    protocol = "-1" // -1 for all protocols
    cidr_blocks = ["0.0.0.0/0"] // allow traffic from all IPs
  }

  // Allow all outbound traffic
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1" // -1 for all protocols
    cidr_blocks = ["0.0.0.0/0"] // allow traffic to all IPs
  }
}

account for

  1. resource "aws_security_group" "eks_allow_all": Declare a file namedeks_allow_all resource of typeaws_security_group, which is used to create security groups.

  2. name = "eks_allow_all": Set the name of the security group toeks_allow_all

  3. description = "Security group that allows all inbound and outbound traffic": Provide a description for the security group stating that the role of this security group is to allow all inbound and outbound traffic.

  4. vpc_id = aws_vpc.tf_vpc.id: Specifies the VPC to which the security group belongs, referencing the ID of a previously defined VPC.

Inbound rules (ingress

  1. ingress { ... }:
    • Define inbound rules to allow traffic to enter the security group.

    • from_port = 0 cap (a poem)to_port = 0: This indicates that traffic is allowed on all ports (0 through 0 for all ports).

    • protocol = "-1": -1 Indicates all protocols, including TCP, UDP, and ICMP.

    • cidr_blocks = ["0.0.0.0/0"]: Allow traffic from all IP addresses (0.0.0.0/0 means any IP).

Outbound rules (egress

  1. egress { ... }:
    • Define outbound rules to allow traffic to leave the security group.

    • from_port = 0 cap (a poem)to_port = 0: Allows traffic on all ports as well.

    • protocol = "-1": Indicates all protocols.

    • cidr_blocks = ["0.0.0.0/0"]: Allow traffic to be sent to all IP addresses.

pre-creation

terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.eks_allow_all will be created
  + resource "aws_security_group" "eks_allow_all" {
      + arn                    = (known after apply)
      + description            = "Security group that allows all inbound and outbound traffic"
      + egress                 = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
                # (1 unchanged attribute hidden)
            },
        ]
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
                # (1 unchanged attribute hidden)
            },
        ]
      + name                   = "eks_allow_all"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags_all               = (known after apply)
      + vpc_id                 = "vpc-0f2e1cdca0cf5a306"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Creating Security Groups

terraform apply ""

The output is as follows:

aws_security_group.eks_allow_all: Creating...
aws_security_group.eks_allow_all: Creation complete after 7s [id=sg-0db88cd4ca4b95099]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

3. Create EKS cluster IAM roles

establisheks_iam_roles.tf file

data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = [""]
    }
    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "eks-cluster" {
  name               = "eks-cluster"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSClusterPolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.
}

resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSVPCResourceController" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
  role       = aws_iam_role.
}

account for

This code defines an IAM role and its permission policy for the creation and management of Amazon EKS clusters. The following is a detailed explanation:

Data source component

  1. data "aws_iam_policy_document" "assume_role":
    • This is a datasource of IAM policy documents used to define trust policies for roles.

    • statement { ... }:

      • effect = "Allow": Allow the use of this role.
      • principals { ... }: Defines the subjects that can use this role.
        • type = "Service": Specifies that the subject type is a service.
        • identifiers = [""]: Allow the EKS service to assume this role.
      • actions = ["sts:AssumeRole"]: The operations that the above subject is allowed to perform, i.e., the permissions of the assumed role.

IAM Role Segment

  1. resource "aws_iam_role" "eks-cluster":
    • Create a file namedeks-cluster of the IAM role.

    • assume_role_policy = data.aws_iam_policy_document.assume_role.json: Apply the previously defined trust policy to the role.

IAM Role Strategy Annex

  1. resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSClusterPolicy":

    • Associate an Amazon EKS Cluster Policy to an IAM role.
    • policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy": Specifies the policy ARN to be attached.
    • role = aws_iam_role.: Attach the policy to the previously createdeks-cluster Characters.
  2. resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSVPCResourceController":

    • Associate Amazon EKS VPC Resource Controller policies to IAM roles.
    • policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController": Specifies the policy ARN to be attached.
    • role = aws_iam_role.: Attach the policy to the previously createdeks-cluster Characters.

pre-creation

terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # aws_iam_role.eks-cluster will be created
  + resource "aws_iam_role" "eks-cluster" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = ""
                        }
                      + Sid       = ""
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "eks-cluster"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + role_last_used        = (known after apply)
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # aws_iam_role_policy_attachment.eks-cluster-AmazonEKSClusterPolicy will be created
  + resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSClusterPolicy" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
      + role       = "eks-cluster"
    }

  # aws_iam_role_policy_attachment.eks-cluster-AmazonEKSVPCResourceController will be created
  + resource "aws_iam_role_policy_attachment" "eks-cluster-AmazonEKSVPCResourceController" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
      + role       = "eks-cluster"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Create eks iam role

terraform apply ""

The output is as follows:

aws_iam_role.eks-cluster: Creating...
aws_iam_role.eks-cluster: Creation complete after 2s [id=eks-cluster]
aws_iam_role_policy_attachment.eks-cluster-AmazonEKSVPCResourceController: Creating...
aws_iam_role_policy_attachment.eks-cluster-AmazonEKSClusterPolicy: Creating...
aws_iam_role_policy_attachment.eks-cluster-AmazonEKSVPCResourceController: Creation complete after 1s [id=eks-cluster-20241027124651622300000001]
aws_iam_role_policy_attachment.eks-cluster-AmazonEKSClusterPolicy: Creation complete after 1s [id=eks-cluster-20241027124651968900000002]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

4. Creation of EKS clusters

Writing eks_cluster.tffile

resource "aws_eks_cluster" "tf-eks" {
  name = "tf-eks"
  version = var.eks_version # indicate clearly and with certainty EKS releases
  role_arn = aws_iam_role.

  vpc_config {
    subnet_ids = [
	  aws_subnet.tf_eks_subnet1.id,
	  aws_subnet.tf_eks_subnet2.id
	]
    security_group_ids = [aws_security_group.eks_allow_all.id] # Referencing a previously created security group
    endpoint_public_access = true # public access
    endpoint_private_access = true # private access
    public_access_cidrs = ["0.0.0.0/0"] # Allow access from anywhere
  }
# # Enabling Logging
# enabled_cluster_log_types = [
# "api",
# "audit",
# "authenticator",
# "controllerManager",
# "scheduler",
# ]

  depends_on = [
    aws_iam_role_policy_attachment.eks-cluster-AmazonEKSClusterPolicy,
    aws_iam_role_policy_attachment.eks-cluster-AmazonEKSVPCResourceController,
  ]
}

parameter interpretation

  • name: Specify the name of the cluster astf-eks
  • version: To specify the version of EKS, use the variablevar.eks_versionThis makes it easy to adjust in different environments.
  • role_arn: Specifies the IAM role ARN to be used for EKS clustering, usually this role needs to have a corresponding permission policy.
  • subnet_ids: Specifies the subnet on which the EKS cluster resides, allowing multiple subnet IDs to be used for deployment in high availability scenarios.
  • security_group_ids: References a previously created security group used to control network traffic to the cluster.
  • endpoint_public_access: Set totrue, indicates that the EKS API endpoint is allowed to be accessed over the public network.
  • endpoint_private_access: Set totrueThe EKS API endpoints are not accessible from within the VPC.
  • public_access_cidrs: The range of CIDRs allowed to access the cluster, set here to["0.0.0.0/0"]The following is an example of a security risk that may be posed by allowing access from any IP address.
  • The Logging section is commented out and, if enabled, you can specify the types of cluster logs that need to be logged, including APIs, audits, authenticators, controller managers, and schedulers.
  • depends_on: Ensure that the required IAM role policies have been attached before creating the EKS cluster, and that the resources are created in the correct order

pre-creation

terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # aws_eks_cluster.tf-eks will be created
  + resource "aws_eks_cluster" "tf-eks" {
      + arn                   = (known after apply)
      + certificate_authority = (known after apply)
      + cluster_id            = (known after apply)
      + created_at            = (known after apply)
      + endpoint              = (known after apply)
      + id                    = (known after apply)
      + identity              = (known after apply)
      + name                  = "tf-eks"
      + platform_version      = (known after apply)
      + role_arn              = "arn:aws:iam::xxxxxxxx:role/eks-cluster"
      + status                = (known after apply)
      + tags_all              = (known after apply)
      + version               = "1.31"

      + kubernetes_network_config (known after apply)

      + vpc_config {
          + cluster_security_group_id = (known after apply)
          + endpoint_private_access   = true
          + endpoint_public_access    = true
          + public_access_cidrs       = [
              + "0.0.0.0/0",
            ]
          + security_group_ids        = [
              + "sg-0db88cd4ca4b95099",
            ]
          + subnet_ids                = [
              + "subnet-01b5d98060f0063ef",
              + "subnet-0a30534a829758774",
            ]
          + vpc_id                    = (known after apply)
        }
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

establish

terraform apply ""

The output is as follows:

aws_eks_cluster.tf-eks: Creating...
aws_eks_cluster.tf-eks: Still creating... [10s elapsed]
aws_eks_cluster.tf-eks: Still creating... [20s elapsed]
aws_eks_cluster.tf-eks: Still creating... [30s elapsed]
......
.......
aws_eks_cluster.tf-eks: Still creating... [7m21s elapsed]
aws_eks_cluster.tf-eks: Still creating... [7m31s elapsed]
aws_eks_cluster.tf-eks: Creation complete after 7m35s [id=tf-eks]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

5. Create Node Group IAM

Create tf file

eks_node_group_iam.tf

resource "aws_iam_role" "eks-nodegroup-role" {
  name = "eks-nodegroup-role"
  assume_role_policy = jsonencode({
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = ""
      }
    }]
    Version = "2012-10-17"
  })
}

resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKSWorkerNodePolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = aws_iam_role.
}

resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKS_CNI_Policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = aws_iam_role.
}

resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.
}

account for

This code defines an IAM role for an Amazon EKS node group and attaches the necessary permission policies. The following is a detailed explanation:

IAM Role Definition

  1. resource "aws_iam_role" "eks-nodegroup-role":
    • Create a file namedeks-nodegroup-role of IAM roles for use by EKS nodes.

    • assume_role_policy = jsonencode({ ... }): Defines the trust policy for a role, allowing specific services to assume this role.

      • Statement = [{ ... }]: Defines the permission statement for the role.
        • Action = "sts:AssumeRole":: Permitted operations, i.e., assumed roles.
        • Effect = "Allow": The effect of this statement is to allow.
        • Principal = { Service = "" }: Allowed service (i.e., EC2 instance) to assume this role so that the EKS node can gain privileges.
    • Version = "2012-10-17": Defines the version of the policy language.

IAM Role Strategy Annex

  1. resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKSWorkerNodePolicy":

    • Attach the Amazon EKS Worker Node Policy to the node group role.
    • policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy": Specifies the policy ARN to be attached.
    • role = aws_iam_role.: Attach the policy to the previously createdeks-nodegroup-role Characters.
  2. resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKS_CNI_Policy":

    • Attach the Amazon EKS CNI Policy to the node group role.
    • policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy": Specifies the policy ARN to be attached.
    • role = aws_iam_role.: Attach the policy to the previously createdeks-nodegroup-role Characters.
  3. resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly":

    • Attach the Amazon EC2 Container Registry Read Only Policy to the node group role.
    • policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly": Specifies the policy ARN to be attached.
    • role = aws_iam_role.: Attach the policy to the previously createdeks-nodegroup-role Characters.

pre-creation

terraform plan -out=
tf plan
 Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # aws_iam_role.eks-nodegroup-role will be created
  + resource "aws_iam_role" "eks-nodegroup-role" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = ""
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "eks-nodegroup-role"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + role_last_used        = (known after apply)
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly will be created
  + resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
      + role       = "eks-nodegroup-role"
    }

  # aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKSWorkerNodePolicy will be created
  + resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKSWorkerNodePolicy" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
      + role       = "eks-nodegroup-role"
    }

  # aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKS_CNI_Policy will be created
  + resource "aws_iam_role_policy_attachment" "eks-nodegroup-role-AmazonEKS_CNI_Policy" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
      + role       = "eks-nodegroup-role"
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Create node group iam

 terraform apply ""

Output:

aws_iam_role.eks-nodegroup-role: Creating...
aws_iam_role.eks-nodegroup-role: Creation complete after 2s [id=eks-nodegroup-role]
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKS_CNI_Policy: Creating...
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly: Creating...
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKSWorkerNodePolicy: Creating...
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly: Creation complete after 1s [id=eks-nodegroup-role-20241027130604526800000001]
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKS_CNI_Policy: Creation complete after 1s [id=eks-nodegroup-role-20241027130604963000000002]
aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKSWorkerNodePolicy: Creation complete after 2s [id=eks-nodegroup-role-20241027130605372700000003]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Reproduced with the famous original address:/Sunzz/p/18498915

6. Creating a Node Group

defineeks_node_group.tf file

resource "aws_eks_node_group" "node_group1" {
  cluster_name    = aws_eks_cluster.
  node_group_name = "node_group1"
  ami_type        = "AL2_x86_64"
  capacity_type   = "ON_DEMAND"
  disk_size       = 20
  instance_types   = [""]
  node_role_arn   = aws_iam_role.
  subnet_ids = [
      aws_subnet.tf_eks_subnet1.id,
      aws_subnet.tf_eks_subnet2.id
    ]

  scaling_config {
    desired_size = 1
    max_size     = 2
    min_size     = 1
  }

  update_config {
    max_unavailable = 1
  }

  depends_on = [
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKSWorkerNodePolicy,
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKS_CNI_Policy,
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly,
  ]

#  remote_access {
#    ec2_ssh_key = aws_key_pair.tf-keypair.key_name
#    source_security_group_ids = [
#	   aws_security_group.tf_security_group.id
#    ]
#  } 
}

resource "aws_eks_node_group" "node_group2" {
  cluster_name    = aws_eks_cluster.
  node_group_name = "node_group2"
  ami_type        = "AL2_x86_64"
  capacity_type   = "ON_DEMAND"
  disk_size       = 20
  instance_types  = [""]
  node_role_arn   = aws_iam_role.
  subnet_ids = [
      aws_subnet.tf_eks_subnet1.id,
      aws_subnet.tf_eks_subnet2.id
    ]

  scaling_config {
    desired_size = 1
    max_size     = 2
    min_size     = 1
  }

  update_config {
    max_unavailable = 1
  }

  depends_on = [
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKSWorkerNodePolicy,
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEKS_CNI_Policy,
    aws_iam_role_policy_attachment.eks-nodegroup-role-AmazonEC2ContainerRegistryReadOnly,
  ]

#  remote_access {
#    ec2_ssh_key = aws_key_pair.tf-keypair.key_name
#    source_security_group_ids = [
#	   aws_security_group.tf_security_group.id
#    ]
#  } 
}

account for

EKS Node Group Definition

  1. resource "aws_eks_node_group" "node_group1": Create a file namednode_group1 of the EKS node group.

  2. cluster_name = aws_eks_cluster.: Specifies the EKS cluster to which this node group belongs, referencing the previously createdtf-eks The name of the cluster.

  3. node_group_name = "node_group1": Set the name of the node group tonode_group1

  4. ami_type = "AL2_x86_64": Specifies the type of Amazon Machine Image (AMI) used by the node group, in this case the x86_64 architecture of Amazon Linux 2 (AL2). The options areAL2_x86_64 AL2_x86_64_GPU AL2_ARM_64 CUSTOM BOTTLEROCKET_ARM_64 BOTTLEROCKET_x86_64 BOTTLEROCKET_ARM_64_NVIDIA BOTTLEROCKET_x86_64_NVIDIA WINDOWS_CORE_2019_x86_64 WINDOWS_FULL_2019_x86_64 WINDOWS_CORE_2022_x86_64 WINDOWS_FULL_2022_x86_64],

  5. capacity_type = "ON_DEMAND": Set the capacity type of the instance to On-Demand, i.e., pay-as-you-use, rather than reserved.

  6. disk_size = 20: Specify the size of the root volume for each node, which is set to 20 GB here.

  7. instance_types = [""]: Specifies the instance type of the node, used here is Type.

  8. node_role_arn = aws_iam_role.: Specify the IAM role ARN for the node group that allows the node to access the necessary AWS services.

  9. subnet_ids = [ ... ]: Defines the subnet that will be used by the node group, referencing thetf_eks_subnet1 cap (a poem)tf_eks_subnet2 These subnets are the network environment in which the EKS node operates.

Extending and updating configurations

  1. scaling_config { ... }:

    • Set the extended configuration of the node group.
    • desired_size = 1: Starts a node by default.
    • max_size = 2: The node group can be expanded to a maximum of 2 nodes.
    • min_size = 1: The node group retains at least one node.
  2. update_config { ... }:

    • Configure the update policy for the node group.
    • max_unavailable = 1: At most one node can be unavailable during the update process.

dependency

  1. depends_on = [ ... ]: Specify the dependencies for this resource to ensure that the relevant IAM role policy attachment operations have been completed before the node group is created.

Remote access configuration (commented out)

  1. remote_access { ... } (commented out).
    • This section configures remote access options to allow SSH access to the node group.
    • ec2_ssh_key = aws_key_pair.tf-keypair.key_name: Specify the EC2 key pair to be used for SSH access.
    • source_security_group_ids = [ ... ]: Specify the security group that allows SSH access.

pre-creation

 terraform plan -out=
tf plan
 Terraform will perform the following actions:

  # aws_eks_node_group.node_group1 will be created
  + resource "aws_eks_node_group" "node_group1" {
      + ami_type               = "AL2_x86_64"
      + arn                    = (known after apply)
      + capacity_type          = "ON_DEMAND"
      + cluster_name           = "tf-eks"
      + disk_size              = 20
      + id                     = (known after apply)
      + instance_types         = [
          + "",
        ]
      + node_group_name        = "node_group1"
      + node_group_name_prefix = (known after apply)
      + node_role_arn          = "arn:aws:iam::xxxxxx:role/eks-nodegroup-role"
      + release_version        = (known after apply)
      + resources              = (known after apply)
      + status                 = (known after apply)
      + subnet_ids             = [
          + "subnet-01b5d98060f0063ef",
          + "subnet-0a30534a829758774",
        ]
      + tags_all               = (known after apply)
      + version                = (known after apply)

      + scaling_config {
          + desired_size = 1
          + max_size     = 2
          + min_size     = 1
        }

      + update_config {
          + max_unavailable = 1
        }
    }

  # aws_eks_node_group.node_group2 will be created
  + resource "aws_eks_node_group" "node_group2" {
      + ami_type               = "AL2_x86_64"
      + arn                    = (known after apply)
      + capacity_type          = "ON_DEMAND"
      + cluster_name           = "tf-eks"
      + disk_size              = 20
      + id                     = (known after apply)
      + instance_types         = [
          + "",
        ]
      + node_group_name        = "node_group2"
      + node_group_name_prefix = (known after apply)
      + node_role_arn          = "arn:aws:iam::xxxxx:role/eks-nodegroup-role"
      + release_version        = (known after apply)
      + resources              = (known after apply)
      + status                 = (known after apply)
      + subnet_ids             = [
          + "subnet-01b5d98060f0063ef",
          + "subnet-0a30534a829758774",
        ]
      + tags_all               = (known after apply)
      + version                = (known after apply)

      + scaling_config {
          + desired_size = 1
          + max_size     = 2
          + min_size     = 1
        }

      + update_config {
          + max_unavailable = 1
        }
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: 

To perform exactly these actions, run the following command to apply:
    terraform apply ""

Creating a Node Group

terraform apply ""

The output is as follows:

aws_eks_node_group.node_group2: Creating...
aws_eks_node_group.node_group1: Creating...
aws_eks_node_group.node_group1: Still creating... [10s elapsed]
......
aws_eks_node_group.node_group1: Creation complete after 1m41s [id=tf-eks:node_group1]
aws_eks_node_group.node_group2: Still creating... [1m50s elapsed]
aws_eks_node_group.node_group2: Creation complete after 1m52s [id=tf-eks:node_group2]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

7. Access to EKS information

Added eks_output.tf

# exports EKS Name of the cluster
output "eks_cluster_name" {
  value = aws_eks_cluster.
  description = "The name of the EKS cluster"
}

# exports EKS clustered ARN(Amazon Resource Name)
output "eks_cluster_arn" {
  value = aws_eks_cluster.
  description = "The ARN of the EKS cluster"
}

# exports EKS clustered API server endpoint
output "eks_cluster_endpoint" {
  value = aws_eks_cluster.
  description = "The endpoint of the EKS cluster"
}

# exports EKS clustered当前状态
output "eks_cluster_status" {
  value = aws_eks_cluster.
  description = "The status of the EKS cluster"
}

# exports与 EKS Cluster-associated VPC ID
output "eks_cluster_vpc_id" {
  value = aws_eks_cluster.tf-eks.vpc_config[0].vpc_id
  description = "The VPC ID associated with the EKS cluster"
}

# exports与 EKS Cluster-associated安全组 ID
output "eks_cluster_security_group_ids" {
  value = aws_eks_cluster.tf-eks.vpc_config[0].cluster_security_group_id
  description = "The security group IDs associated with the EKS cluster"
}

# exports用于访问 EKS clustered kubeconfig configure
output "kubeconfig" {
  value = <<EOT
apiVersion: v1
clusters:
- cluster:
    server: ${aws_eks_cluster.}
    certificate-authority-data: ${aws_eks_cluster.tf-eks.certificate_authority[0].data}
  name: ${aws_eks_cluster.}
contexts:
- context:
    cluster: ${aws_eks_cluster.}
    user: ${aws_eks_cluster.}
  name: ${aws_eks_cluster.}
current-context: ${aws_eks_cluster.}
kind: Config
preferences: {}
users:
- name: ${aws_eks_cluster.}
  user:
    exec:
      apiVersion: ./v1beta1
      command: aws
      args:
        - eks
        - get-token
        - --cluster-name
        - ${aws_eks_cluster.}
EOT
  description = "Kubeconfig for accessing the EKS cluster"
}

Since you are only getting information about the resources that have been created, and there is no modification of the resources involved, you can just apply

terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

eks_cluster_arn = "arn:aws:eks:us-west-1:xxxxx:cluster/tf-eks"
eks_cluster_endpoint = "https://D59BB0103962C6BEABC8271AC16B34EC."
eks_cluster_name = "tf-eks"
eks_cluster_security_group_ids = "sg-0159f56ebd2d93a38"
eks_cluster_status = "ACTIVE"
eks_cluster_vpc_id = "vpc-0361291552eab4047"
kubeconfig = <<EOT
apiVersion: v1
clusters:
- cluster:
    server: https://D59BB0103962C6BEABC8271AC16B34EC.
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJSG83cjJJV.....
  name: tf-eks
contexts:
- context:
    cluster: tf-eks
    user: tf-eks
  name: tf-eks
current-context: tf-eks
kind: Config
preferences: {}
users:
- name: tf-eks
  user:
    exec:
      apiVersion: ./v1beta1 
      command: aws
      args:
        - eks
        - get-token
        - --cluster-name
        - tf-eks

EOT

8. Configuring kubeconfig

Mode 1

Just configure ~/.kube/config according to the kubeconfig content generated above

Mode 2

Execute the command to generate the kubeconfig file

aws eks update-kubeconfig --region us-west-1 --name tf-eks

View the number of cluster nodes

 kubectl get no
 kubectl get no
NAME                                         STATUS   ROLES    AGE     VERSION
    Ready    <none>   3m48s   v1.31.0-eks-a737599
   Ready    <none>   4m1s    v1.31.0-eks-a737599

View the number of pods allowed in the cluster

kubectl get po -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-8zjcn             2/2     Running   0          4m55s
kube-system   aws-node-n4ns8             2/2     Running   0          4m42s
kube-system   coredns-6486b6fd59-hkcnb   1/1     Running   0          20m
kube-system   coredns-6486b6fd59-hz75m   1/1     Running   0          20m
kube-system   kube-proxy-fbdv9           1/1     Running   0          4m42s
kube-system   kube-proxy-nnb2r           1/1     Running   0          4m55s

9. Creating nginx applications

Edit file

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3 # Number of copies
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.26 # indicate clearly and with certainty Nginx mirror (computing)
          ports:
            - containerPort: 80 # Expose Container Port

Create nginx-deployment

kubectl apply -f 

10. Review of tf files created

At this point we have created a bunch of tf files, you can also create all the tf files together and then finally terraform plan 

Details are as follows:

9. Destruction of resources

terraform destroy

 

summarize

After a period of in-depth exploration and writing, this blog has become one of my most time-consuming and lengthy entries to date. From researching the features of Terraform to the actual practice of creating various resources on AWS, each step required meticulous scrutiny and repeated validation. Not only did it help me become more familiar with the power of Terraform, but I also gained a lot from sharing my knowledge.

In this blog post, I strive to help readers get started easily with detailed content and clear explanations, especially for those who are beginners. My hope is that these efforts will provide readers with practical guidance that will help them take a solid first step on the road to cloud computing. It's been a long journey, but every word carries my passion for Terraform and my anticipation to share my knowledge. I hope you find inspiration and enlightenment in this blog!