前言

Terraform是一种开源基础设施及代码(IaC)的工具,可提供统一的CLI(命令行接口)工作流来治理数百个云服务,将云API编码为申明性的配置文件进行治理。
本文创立一个治理AWS Lightsail实例的例子来入门Terraform的应用。

装置Terraform CLI

要应用Terramform,首先要在本地零碎装置Terraform命令行工具。HashiCorp提供了预编译好的二进制散发包,能够通过(https://www.terraform.com/dow...) 间接下载相应平台的二进制包,解压后放到相应的执行门路。也能够通过一些软件包管理工具装置,例如在Linux/OS X上通过LinuxBrew/HomeBrew进行装置,在Windows上通过Chocolatey进行装置。

这里咱们示例在Linux上是应用LinuxBrew进行装置

> brew install terraform

装置实现后,能够查看其版本

❯ terraform -versionTerraform v1.0.11on linux_amd64

应用-help查看其可用命令,装置胜利后,咱们就能够应用Terraform来创立相应的基础设施我的项目了。

AWS账号筹备

本文将通过创立一个治理AWS Lightsial实例的我的项目来尝试Terraform,因而须要一个AWS账号,以及在本地环境装置和配置好AWS CLI工具的拜访凭据。
装置和配置AWS CLI,请参考其文档 (https://docs.aws.amazon.com/c...) 。 配置实现之后,能够在本地命令行终端拜访相应的AWS资源。

创立并初始化Terraform我的项目

Terraform在本地通过文件夹来治理一个基础设施我的项目的申明性代码,例如咱们在本地创立一个文件夹

> mkdir mylightsail> cd mylightsail/

进入文件夹后,创立一个以 .tf 作为后缀的文件,例如 main.tf

> touch main.tf

而后应用编辑器关上文件进行编辑,写入以下代码块

terraform {  required_providers {    aws = {      source  = "hashicorp/aws"      version = "~> 3.65"    }  }}# Configure the AWS Providerprovider "aws" {  region = "ap-southeast-1"}

其中 terraform/required_providers 块定义了该我的项目须要的 Provider,Terraform是通过不同的Provider来治理相应的基础设施资源的,可到 (https://registry.terraform.io) 来查找须要的Providers,例如GCP,Azure以及阿里云等的Providers。这里因为咱们要治理的资源是AWS Lightsail实例,所以应用了Hashicorp官网提供的 hashicorp/aws 。

provider "aws" 局部配置了该Provider的一些可选项,例如这里配置了区域为 ap-southeast-1 ,因而请确保下面配置的AWS拜访凭据可能操作该区域的资源。

也就是这里咱们定义了咱们须要应用的Provider及其相应的选项配置,接下来咱们须要应用 terraform init 命令来初始化我的项目

> terraform initInitializing provider plugins......Terraform has been successfully initialized!

初始化将会从 (https://registry.terraform.io/) 下载相应的Provider插件到 .terramorm/providers/ 目录,供接下來的命令应用。
同时,会生成一个 .terraform.lock.hcl 的文件来记录应用的具体Provider版本,其性能相似于NPM的package-lock文件,可将其提交到代码版本治理仓库,其余合作的成员就能够放弃应用雷同的插件版本。

创立基础设施资源

实现我的项目的初始化之后,咱们就能够编写须要创立的资源申明性配置,能够间接将相应的配置写入 main.tf 文件,也能够另外创立新的以 .tf 作为后缀的文件,这里咱们创立一个新的名为 resources.tf 的文件,并写入咱们须要的资源的定义

## LightSail Resourcesresource "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"    ]  }}

定义资源的格局为 resource "[provider_resource _type]" "resource_name",第一个参数为相应Provider反对的资源类型名称,第二个参数为本人定义的资源名称(可用于其余资源援用)。例如,咱们首先定义了一个Lightsail的动态IP资源,其中参数 name 指定了AWS资源的名称。

下面的定义中,咱们申明了以下资源

  • 一个Lightsail动态IP地址
  • 一个Lightsail计算实例,并绑定名为 LightsailDefaultKeyPair 的SSH密钥
  • 动态IP地址和计算实例的绑定
  • 实例的凋谢的网络端口组(相似于AWS EC2实例的平安组定义)

保留文件之后,咱们能够应用 terraform fmt 命令来格式化文件格式,以及 terraform validate 来查看是否有语法错误。

定义好咱们想要的资源之后,咱们先通过命令 terraform plan 命令来执行打算,查看具体的执行更改(plan不会实际操作相应的资源)

❯ terraform plan                    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:  + createTerraform 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.

+示意将要减少的资源,(know after apply)的意思是要在具体只想(apply)之后,AWS依据定义创立相应资源之后才会返回的具体值。接下来就能够应用 terraform apply 来具体执行操作了,执行胜利之后,会生成 .terraform/terraform.state 文件来记录执行后的资源状态,也能够通过命令 terraform show 命令来查看

❯ 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"}

之后咱们就能够通过更新资源定义文件,而后执行 plan & apply 来更新云上的资源了,如果资源不须要了,咱们也能够通过 terraform destroy 一条命令来销毁所有资源。

总结

本文以治理简略的AWS Lightsail资源为例,展现了如何应用Terraform来治理云上的资源。通过一申明性的代码来定义咱们须要的资源,同时资源定义代码能够通过版本管理工具进行版本化治理,进一步实现IaC的工作形式。

这么咱们应用的是Terraform的本地执行模式,除了在本地执行之外,Terraform还提供了执行后端(Backend)的性能,就能够将执行放到云上的一些执行环境,资源状态的治理也将会保护在Backend端,不便实现CI/CD Pipeline,以及GitOps的形式。其中Hashicorp的Terraform Cloud就是一个Backend。下一篇文章将示例将该我的项目放到Terraform Cloud下来执行。