Terraform is an open source infrastructure and code (IaC) tool that provides a consistent CLI (Command Line Interface) workflow to manage hundreds of cloud services, and encodes cloud APIs into declarative configuration files for management.
This article creates an AWS Lightsail instance to get started using Terraform.

Install Terraform CLI

To use Terramform, you must first install the Terraform command line tool on your local system. HashiCorp provides a pre-compiled binary distribution package. You can https://www.terraform.com/downolads.html) , decompress it and put it in the corresponding execution path. It can also be installed through some package management tools, such as LinuxBrew/HomeBrew on Linux/OS X, and Chocolatey on Windows.

Here our example is to use LinuxBrew to install on Linux

> brew install terraform

After the installation is complete, you can check its version

❯ terraform -version
Terraform v1.0.11
on linux_amd64

Use -help view its available commands. After the installation is successful, we can use Terraform to create the corresponding infrastructure projects.

AWS account preparation

This article will try Terraform by creating a project to manage AWS Lightsial instances. Therefore, an AWS account is required and the access credentials of the AWS CLI tool are installed and configured in the local environment.
To install and configure the AWS CLI, please refer to its documentation ( https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) . After the configuration is complete, you can access the corresponding AWS resources on the local command line terminal.

Create and initialize the Terraform project

Terraform manages the declarative code of an infrastructure project through folders locally, for example, we create a folder locally

> mkdir mylightsail
> cd mylightsail/

After entering the folder, create a file with as the suffix, such as main.tf

> touch main.tf

Then use the editor to open the file for editing and write the following code block

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

# Configure the AWS Provider
provider "aws" {
  region = "ap-southeast-1"
}

The terraform/required_providers Provider required by the project. Terraform manages the corresponding infrastructure resources through different Providers. You can go to ( https://registry.terraform.io) to find the providers you need, for example Providers such as GCP, Azure and Alibaba Cloud. Here, because the resource we want to manage is an AWS Lightsail instance, the official 1619f28df21eff hashicorp/aws used.

provider "aws" part configures some options of the Provider. For example, the region is configured here as ap-southeast-1 , so please ensure that the AWS access credentials configured above can operate resources in this region.

That is, here we define the Provider we need to use and the corresponding option configuration, then we need to use the terraform init command to initialize the project

> terraform init

Initializing provider plugins...
...
Terraform has been successfully initialized!

Initialization will download the corresponding Provider plug-in https://registry.terraform.io/) .terramorm/providers/ directory for the next commands.
At the same time, will generate a .terraform.lock.hcl file to record specific Provider version of its function is similar to the package-lock NPM file, you can submit it to the code version control repository, other members can collaborate Keep using the same plugin version.

Create infrastructure resources

After completing the initialization of the project, we can write the resource declarative configuration that needs to be created. You can directly write the corresponding configuration into the main.tf file, or you can create a new .tf . Here we create one A new resources.tf , and write the definition of the resources we need

## LightSail Resources

resource "aws_lightsail_static_ip" "Example-sig-ip" {
  name = "Example-EIP"
}

resource "aws_lightsail_instance" "Example-sig" {
  name              = "Example-Sig"
  availability_zone = "ap-southeast-1c"
  blueprint_id      = "ubuntu_20_04"
  bundle_id         = "nano_2_0"
  key_pair_name     = "LightsailDefaultKeyPair"
  tags = {
    Example = ""
  }
}

resource "aws_lightsail_static_ip_attachment" "Example-sig-ip-attache" {
  static_ip_name = aws_lightsail_static_ip.Example-sig-ip.id
  instance_name  = aws_lightsail_instance.Example-sig.id
}

resource "aws_lightsail_instance_public_ports" "Example-sig-public-ports" {
  instance_name = aws_lightsail_instance.Example-sig.name

  port_info {
    protocol  = "tcp"
    from_port = 0
    to_port   = 65535
    cidrs = [
      "0.0.0.0/0"
    ]
  }
  port_info {
    protocol  = "udp"
    from_port = 0
    to_port   = 65535
    cidrs = [
      "0.0.0.0/0"
    ]
  }
}

The format of the defined resource is resource "[provider_resource _type]" "resource_name" . The first parameter is the name of the resource type supported by the corresponding Provider, and the second parameter is the name of the resource defined by yourself (which can be used for other resource references). For example, we first define a Lightsail static IP resource, where the parameter name specifies the name of the AWS resource.

In the above definition, we declared the following resources

  • A Lightsail static IP address
  • A Lightsail computing instance and bind an SSH key LightsailDefaultKeyPair
  • Binding of static IP address and computing instance
  • The open network port group of the instance (similar to the security group definition of AWS EC2 instances)

After saving the file, we can use the terraform fmt command to format the file format, and terraform validate to check for syntax errors.

After defining the resources we want, we first terraform plan to view the specific execution changes (plan does not actually operate the corresponding resources)

❯ terraform 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_lightsail_instance.Example-sig will be created
  + resource "aws_lightsail_instance" "Example-sig" {
      + arn                = (known after apply)
      + availability_zone  = "ap-southeast-1c"
      + blueprint_id       = "ubuntu_20_04"
      + bundle_id          = "nano_2_0"
      + cpu_count          = (known after apply)
      + created_at         = (known after apply)
      + id                 = (known after apply)
      + ipv6_address       = (known after apply)
      + ipv6_addresses     = (known after apply)
      + is_static_ip       = (known after apply)
      + key_pair_name      = "LightsailDefaultKeyPair"
      + name               = "Example-Sig"
      + private_ip_address = (known after apply)
      + public_ip_address  = (known after apply)
      + ram_size           = (known after apply)
      + tags               = {
          + "Example" = ""
        }
      + tags_all           = {
          + "Example" = (known after apply)
        }
      + username           = (known after apply)
    }

  # aws_lightsail_instance_public_ports.Example-sig-public-ports will be created
  + resource "aws_lightsail_instance_public_ports" "Example-sig-public-ports" {
      + id            = (known after apply)
      + instance_name = "Example-Sig"

      + port_info {
          + cidrs     = [
              + "0.0.0.0/0",
            ]
          + from_port = 0
          + protocol  = "tcp"
          + to_port   = 65535
        }
      + port_info {
          + cidrs     = [
              + "0.0.0.0/0",
            ]
          + from_port = 0
          + protocol  = "udp"
          + to_port   = 65535
        }
    }

  # aws_lightsail_static_ip.Example-sig-ip will be created
  + resource "aws_lightsail_static_ip" "Example-sig-ip" {
      + arn          = (known after apply)
      + id           = (known after apply)
      + ip_address   = (known after apply)
      + name         = "Example-EIP"
      + support_code = (known after apply)
    }

  # aws_lightsail_static_ip_attachment.Example-sig-ip-attache will be created
  + resource "aws_lightsail_static_ip_attachment" "Example-sig-ip-attache" {
      + id             = (known after apply)
      + instance_name  = (known after apply)
      + ip_address     = (known after apply)
      + static_ip_name = (known after apply)
    }

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

+ represents the resource to be added, and (know after apply) means the specific value that will be returned after AWS creates the corresponding resource according to the definition after applying it. Next, you can use terraform apply to perform specific operations. After the execution is successful, a .terraform/terraform.state file will be generated to record the resource status after execution. You can also use the command terraform show to view

❯ terraform show
# aws_lightsail_instance.Example-sig:
resource "aws_lightsail_instance" "Example-sig" {
    arn                = "arn:aws:lightsail:ap-southeast-1:090767794770:Instance/21cb0ea5-e814-4307-8606-01348d98be15"
    availability_zone  = "ap-southeast-1c"
    blueprint_id       = "ubuntu_20_04"
    bundle_id          = "nano_2_0"
    cpu_count          = 1
    created_at         = "2021-11-08T05:49:05Z"
    id                 = "Example-Sig"
    ipv6_address       = "2406:da18:8ae:4b02:1f2:4ff1:daa1:6a8c"
    ipv6_addresses     = [
        "2406:da18:8ae:4b02:1f2:4ff1:daa1:6a8c",
    ]
    is_static_ip       = true
    key_pair_name      = "LightsailDefaultKeyPair"
    name               = "Example-Sig"
    private_ip_address = "172.26.45.249"
    public_ip_address  = "54.220.33.133"
    ram_size           = 0.5
    tags               = {
        "Example" = ""
    }
    tags_all           = {
        "Example" = ""
    }
    username           = "ubuntu"
}

# aws_lightsail_instance_public_ports.Example-sig-public-ports:
resource "aws_lightsail_instance_public_ports" "Example-sig-public-ports" {
    id            = "Example-Sig-987241840"
    instance_name = "Example-Sig"

    port_info {
        cidrs     = [
            "0.0.0.0/0",
        ]
        from_port = 0
        protocol  = "tcp"
        to_port   = 65535
    }
    port_info {
        cidrs     = [
            "0.0.0.0/0",
        ]
        from_port = 0
        protocol  = "udp"
        to_port   = 65535
    }
}

# aws_lightsail_static_ip.Example-sig-ip:
resource "aws_lightsail_static_ip" "Example-sig-ip" {
    arn          = "arn:aws:lightsail:ap-southeast-1:090767794770:StaticIp/3f0298e0-efeb-4429-9574-156fef12a48f"
    id           = "Example-EIP"
    ip_address   = "54.220.33.133"
    name         = "Example-EIP"
    support_code = "313963776615/54.220.33.133"
}

# aws_lightsail_static_ip_attachment.Example-sig-ip-attache:
resource "aws_lightsail_static_ip_attachment" "exmaple-sig-ip-attache" {
    id             = "Example-EIP"
    instance_name  = "Example-Sig"
    ip_address     = "54.220.33.133"
    static_ip_name = "Example-EIP"
}

After that, we can update the resource definition file and execute plan & apply to update the resources on the cloud. If the resources are no terraform destroy needed, we can also destroy all resources with a single command of 0619f28df2236f.

Summarize

This article uses simple AWS Lightsail resource management as an example to show how to use Terraform to manage resources on the cloud. A declarative code is used to define the resources we need, and at the same time, the resource definition code can be versioned through version management tools to further realize the working method of IaC.

So we are using Terraform's local execution mode. In addition to local execution, Terraform also provides the function of executing the backend (Backend), which can put the execution on some execution environments on the cloud, and the management of resource status will also It will be maintained on the Backend side to facilitate the implementation of CI/CD Pipeline and GitOps. Among them, Hashicorp's Terraform Cloud is a Backend. The next article will put the example of this project on Terraform Cloud for execution.

[At the same time, published on Terraform Preliminary: Managing AWS Lightsail instance ]


梦哲
74 声望58 粉丝

寻找人生的意义!