介绍
Terraform 是一种部署技术,任何想要通过基础设施即代码(Infrastructure as Code, IaC)
的方式来管理基础设施的人,都可以使用这种技术。在这里基础设施
主要是指的是基于云的基础设施
,不过从技术上来说,只要是能够通过应用程序接口
进行控制的东西都是可以算基础设施。基础设施即代码
是通过定义配置代码来进行配置及管理基础设施的过程。通过使用 IaC
Terraform 管理基础设施的配置代码,是 HashiCorp 自研的一种配置语言,称之为 HashiCorp Configuration Language,简称为 HCL。因此我们也需要学习这种配置语言,便于我们编写配置代码进行管理基础设施。
同时 HCL 与 JSON 是完全兼容的,这也意味着 HCL 能够直接转换为 JSON 格式,反之亦然。对 JSON 的兼容,也使得与 Terraform 之外的系统进行交互操作或者动态生成配置代码就变的非常简单了。
Terraform 还有一个非常不错的好处就是云无关。云无关指的是能够使用一组相同的工具和工作流,无缝运行在任何云平台上。也就是说,使用 Terraform 把基础设施部署到阿里云
与腾讯云
或者 AWS
云无关,在现在这种云厂商林立的情况下是非常重要的,因为这意味着你不必局限于一种云厂商,也不需要为了每次更换云厂商而去学习新的管理工具或者技术。
Terraform 是通过 provider(提供程序)
与不同的云集成。provider
是 Terraform 的插件机制。通过实现 provider
来与云厂商 API 进行交互。每个云厂商都会维护自己的 provider
,使 provider
provider
是使用 Go 语言编写的,它会以二进制文件的方式,注册到 Terraform 上,当我们需要用到的时候,Terraform 会将其保存到指定的目录中进行调用。同时它也是负责进行厂商的身份验证、发出 API 请求等操作的。当然你也可以自己实现一个 provider
,后续的有机会的话,会介绍下如何实现。
Terraform 的表达能力也是非常强的,它的配置语言也是支持条件语句、for 表达式、指令、模板文件等等,通过这些可以轻松的使我们实现更为复杂的场景。
Hello Terraform
接下来,以一个实战来演示一下 Terraform 的使用。
使用 Terraform 代替我们的手动操作,进行身份验证及 API 调用,在阿里云上创建一个 ECS 的实例。并且演示一下如何使用 Terraform 删除 ECS 实例。
Terraform 创建阿里云 ECS 实例的步骤:
- 编写 Terraform 的配置代码。
- 初始化 Terraform 项目目录,并安装阿里云的
provider
。 - 查看并创建 Terraform 的变更计划。(非必须)
- 执行创建 ECS 实例的计划。
- 清除 ECS 实例。
编写配置代码
下面我们来创建一个名叫 main.tf
阿里云 provider
相关文档地址:https://registry.terraform.io/providers/aliyun/alicloud/latest/docs
.tf 为拓展名的文件,表示它是 Terraform 的配置代码文件。
Terraform 在运行的时候,会读取工作目录下的所有 .tf
terraform {
required_providers {
alicloud = {
source = "aliyun/alicloud"
}
}
}
# 定义云厂商
provider "alicloud" {
region = "cn-shanghai"
access_key = "LTAIxxxxxxxxxxxxxxxxx"
secret_key = "hmbkxxxxxxxxxxxxxxxxxxxxxxxxx"
}
# 创建vpc
resource "alicloud_vpc" "vpc" {
vpc_name = "vpc_1"
cidr_block = "10.0.0.0/16"
}
# 创建vswitch
# alicloud_vswitch是阿里云的资源字段,vsw_1字段是tf文件中的自定义唯一资源名称,vswitch_name字段是在阿里云上的自定义备注名
resource "alicloud_vswitch" "vsw_1" {
vswitch_name = "vsw_aliyun1"
vpc_id = alicloud_vpc.vpc.id
cidr_block = "10.0.0.0/24"
zone_id = "cn-shanghai-b"
}
# 新建安全组
resource "alicloud_security_group" "nsg1" {
name = "lanyulei_aliyun_nsg1"
vpc_id = alicloud_vpc.vpc.id
}
# 将 nsg_rule1 加入安全组 lanyulei_aliyun_nsg1 中
resource "alicloud_security_group_rule" "nsg_rule1" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "1/65535"
priority = 1
security_group_id = alicloud_security_group.nsg1.id
cidr_ip = "0.0.0.0/0"
}
# 创建ECS实例
resource "alicloud_instance" "instance" {
# cn-shanghai
availability_zone = "cn-shanghai-b"
security_groups = ["${alicloud_security_group.nsg1.id}"]
instance_type = "ecs.n1.small"
system_disk_category = "cloud_ssd"
image_id = "centos_7_9_x64_20G_alibase_20220824.vhd"
instance_name = "lanyulei-ecs"
vswitch_id = alicloud_vswitch.vsw_1.id
internet_max_bandwidth_out = 1
password = "4aI5wjyPGUlj"
}
初始化工作目录
执行 terraform init
命令,安装阿里云的 provider
➜ demo $ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of aliyun/alicloud...
- Installing aliyun/alicloud v1.196.0...
- Installed aliyun/alicloud v1.196.0 (signed by a HashiCorp partner, key ID 47422B4AA9FA381B)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.
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.
查看 Terraform 的变更计划
执行 terraform plan
- 绿色的 +:新增。
- 红色的 -:删除。
- 黄色的 ~:变更。
➜ demo $ 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:
# alicloud_instance.instance will be created
+ resource "alicloud_instance" "instance" {
+ availability_zone = "cn-shanghai-b"
+ credit_specification = (known after apply)
+ deletion_protection = false
+ deployment_set_group_no = (known after apply)
+ dry_run = false
+ host_name = (known after apply)
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
+ id = (known after apply)
+ image_id = "centos_7_9_x64_20G_alibase_20220824.vhd"
+ instance_charge_type = "PostPaid"
+ instance_name = "lanyulei-ecs"
+ instance_type = "ecs.n1.small"
+ internet_charge_type = "PayByTraffic"
+ internet_max_bandwidth_in = (known after apply)
+ internet_max_bandwidth_out = 1
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ maintenance_action = (known after apply)
+ password = (sensitive value)
+ private_ip = (known after apply)
+ public_ip = (known after apply)
+ role_name = (known after apply)
+ secondary_private_ip_address_count = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ spot_duration = (known after apply)
+ spot_strategy = "NoSpot"
+ status = (known after apply)
+ stopped_mode = (known after apply)
+ subnet_id = (known after apply)
+ system_disk_category = "cloud_ssd"
+ system_disk_performance_level = (known after apply)
+ system_disk_size = 40
+ volume_tags = (known after apply)
+ vswitch_id = (known after apply)
}
# alicloud_security_group.nsg1 will be created
+ resource "alicloud_security_group" "nsg1" {
+ id = (known after apply)
+ inner_access = (known after apply)
+ inner_access_policy = (known after apply)
+ name = "lanyulei_aliyun_nsg1"
+ security_group_type = "normal"
+ vpc_id = (known after apply)
}
# alicloud_security_group_rule.nsg_rule1 will be created
+ resource "alicloud_security_group_rule" "nsg_rule1" {
+ cidr_ip = "0.0.0.0/0"
+ id = (known after apply)
+ ip_protocol = "tcp"
+ nic_type = "intranet"
+ policy = "accept"
+ port_range = "1/65535"
+ prefix_list_id = (known after apply)
+ priority = 1
+ security_group_id = (known after apply)
+ type = "ingress"
}
# alicloud_vpc.vpc will be created
+ resource "alicloud_vpc" "vpc" {
+ cidr_block = "10.0.0.0/16"
+ id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ name = (known after apply)
+ resource_group_id = (known after apply)
+ route_table_id = (known after apply)
+ router_id = (known after apply)
+ router_table_id = (known after apply)
+ secondary_cidr_blocks = (known after apply)
+ status = (known after apply)
+ vpc_name = "vpc_1"
}
# alicloud_vswitch.vsw_1 will be created
+ resource "alicloud_vswitch" "vsw_1" {
+ availability_zone = (known after apply)
+ cidr_block = "10.0.0.0/24"
+ id = (known after apply)
+ name = (known after apply)
+ status = (known after apply)
+ vpc_id = (known after apply)
+ vswitch_name = "vsw_aliyun1"
+ zone_id = "cn-shanghai-b"
}
Plan: 5 to add, 0 to change, 0 to destroy.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
执行变更计划
执行 terraform apply -auto-approve
,开始创建 ECS 实例。
➜ demo $ terraform apply -auto-approve
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:
# alicloud_instance.instance will be created
+ resource "alicloud_instance" "instance" {
+ availability_zone = "cn-shanghai-b"
+ credit_specification = (known after apply)
+ deletion_protection = false
+ deployment_set_group_no = (known after apply)
+ dry_run = false
+ host_name = (known after apply)
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
+ id = (known after apply)
+ image_id = "centos_7_9_x64_20G_alibase_20220824.vhd"
+ instance_charge_type = "PostPaid"
+ instance_name = "lanyulei-ecs"
+ instance_type = "ecs.n1.small"
+ internet_charge_type = "PayByTraffic"
+ internet_max_bandwidth_in = (known after apply)
+ internet_max_bandwidth_out = 1
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ maintenance_action = (known after apply)
+ password = (sensitive value)
+ private_ip = (known after apply)
+ public_ip = (known after apply)
+ role_name = (known after apply)
+ secondary_private_ip_address_count = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ spot_duration = (known after apply)
+ spot_strategy = "NoSpot"
+ status = (known after apply)
+ stopped_mode = (known after apply)
+ subnet_id = (known after apply)
+ system_disk_category = "cloud_ssd"
+ system_disk_performance_level = (known after apply)
+ system_disk_size = 40
+ volume_tags = (known after apply)
+ vswitch_id = (known after apply)
}
# alicloud_security_group.nsg1 will be created
+ resource "alicloud_security_group" "nsg1" {
+ id = (known after apply)
+ inner_access = (known after apply)
+ inner_access_policy = (known after apply)
+ name = "lanyulei_aliyun_nsg1"
+ security_group_type = "normal"
+ vpc_id = (known after apply)
}
# alicloud_security_group_rule.nsg_rule1 will be created
+ resource "alicloud_security_group_rule" "nsg_rule1" {
+ cidr_ip = "0.0.0.0/0"
+ id = (known after apply)
+ ip_protocol = "tcp"
+ nic_type = "intranet"
+ policy = "accept"
+ port_range = "1/65535"
+ prefix_list_id = (known after apply)
+ priority = 1
+ security_group_id = (known after apply)
+ type = "ingress"
}
# alicloud_vpc.vpc will be created
+ resource "alicloud_vpc" "vpc" {
+ cidr_block = "10.0.0.0/16"
+ id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ name = (known after apply)
+ resource_group_id = (known after apply)
+ route_table_id = (known after apply)
+ router_id = (known after apply)
+ router_table_id = (known after apply)
+ secondary_cidr_blocks = (known after apply)
+ status = (known after apply)
+ vpc_name = "vpc_1"
}
# alicloud_vswitch.vsw_1 will be created
+ resource "alicloud_vswitch" "vsw_1" {
+ availability_zone = (known after apply)
+ cidr_block = "10.0.0.0/24"
+ id = (known after apply)
+ name = (known after apply)
+ status = (known after apply)
+ vpc_id = (known after apply)
+ vswitch_name = "vsw_aliyun1"
+ zone_id = "cn-shanghai-b"
}
Plan: 5 to add, 0 to change, 0 to destroy.
alicloud_vpc.vpc: Creating...
alicloud_vpc.vpc: Creation complete after 6s [id=vpc-uf6lprsrz6c1cshob79kc]
alicloud_security_group.nsg1: Creating...
alicloud_vswitch.vsw_1: Creating...
alicloud_security_group.nsg1: Creation complete after 1s [id=sg-uf642pxnc6msqptaoctg]
alicloud_security_group_rule.nsg_rule1: Creating...
alicloud_security_group_rule.nsg_rule1: Creation complete after 0s [id=sg-uf642pxnc6msqptaoctg:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
alicloud_vswitch.vsw_1: Creation complete after 6s [id=vsw-uf6un6zempw6yvrpb9xmz]
alicloud_instance.instance: Creating...
alicloud_instance.instance: Still creating... [10s elapsed]
alicloud_instance.instance: Creation complete after 12s [id=i-uf672vd7e0esv7i4lvjr]
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
销毁资源实例
执行 terraform destroy -auto-approve
,销毁资源实例。
➜ demo $ terraform destroy -auto-approve
alicloud_vpc.vpc: Refreshing state... [id=vpc-uf6lprsrz6c1cshob79kc]
alicloud_security_group.nsg1: Refreshing state... [id=sg-uf642pxnc6msqptaoctg]
alicloud_vswitch.vsw_1: Refreshing state... [id=vsw-uf6un6zempw6yvrpb9xmz]
alicloud_security_group_rule.nsg_rule1: Refreshing state... [id=sg-uf642pxnc6msqptaoctg:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
alicloud_instance.instance: Refreshing state... [id=i-uf672vd7e0esv7i4lvjr]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# alicloud_instance.instance will be destroyed
- resource "alicloud_instance" "instance" {
- availability_zone = "cn-shanghai-b" -> null
- deletion_protection = false -> null
- dry_run = false -> null
- host_name = "iZuf672vd7e0esv7i4lvjrZ" -> null
- http_put_response_hop_limit = 0 -> null
- id = "i-uf672vd7e0esv7i4lvjr" -> null
- image_id = "centos_7_9_x64_20G_alibase_20220824.vhd" -> null
- instance_charge_type = "PostPaid" -> null
- instance_name = "lanyulei-ecs" -> null
- instance_type = "ecs.n1.small" -> null
- internet_charge_type = "PayByTraffic" -> null
- internet_max_bandwidth_in = -1 -> null
- internet_max_bandwidth_out = 1 -> null
- ipv6_address_count = 0 -> null
- ipv6_addresses = [] -> null
- maintenance_action = "AutoRecover" -> null
- maintenance_notify = false -> null
- password = (sensitive value)
- private_ip = "10.0.0.102" -> null
- public_ip = "139.224.239.237" -> null
- secondary_private_ip_address_count = 0 -> null
- secondary_private_ips = [] -> null
- security_groups = [
- "sg-uf642pxnc6msqptaoctg",
] -> null
- spot_duration = 0 -> null
- spot_price_limit = 0 -> null
- spot_strategy = "NoSpot" -> null
- status = "Running" -> null
- stopped_mode = "Not-applicable" -> null
- subnet_id = "vsw-uf6un6zempw6yvrpb9xmz" -> null
- system_disk_category = "cloud_ssd" -> null
- system_disk_encrypted = false -> null
- system_disk_size = 40 -> null
- tags = {} -> null
- volume_tags = {} -> null
- vswitch_id = "vsw-uf6un6zempw6yvrpb9xmz" -> null
}
# alicloud_security_group.nsg1 will be destroyed
- resource "alicloud_security_group" "nsg1" {
- id = "sg-uf642pxnc6msqptaoctg" -> null
- inner_access = true -> null
- inner_access_policy = "Accept" -> null
- name = "lanyulei_aliyun_nsg1" -> null
- security_group_type = "normal" -> null
- tags = {} -> null
- vpc_id = "vpc-uf6lprsrz6c1cshob79kc" -> null
}
# alicloud_security_group_rule.nsg_rule1 will be destroyed
- resource "alicloud_security_group_rule" "nsg_rule1" {
- cidr_ip = "0.0.0.0/0" -> null
- id = "sg-uf642pxnc6msqptaoctg:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1" -> null
- ip_protocol = "tcp" -> null
- nic_type = "intranet" -> null
- policy = "accept" -> null
- port_range = "1/65535" -> null
- priority = 1 -> null
- security_group_id = "sg-uf642pxnc6msqptaoctg" -> null
- type = "ingress" -> null
}
# alicloud_vpc.vpc will be destroyed
- resource "alicloud_vpc" "vpc" {
- cidr_block = "10.0.0.0/16" -> null
- id = "vpc-uf6lprsrz6c1cshob79kc" -> null
- name = "vpc_1" -> null
- resource_group_id = "rg-acfm2ogvfexgrly" -> null
- route_table_id = "vtb-uf6pyfkc87awmxaa4do32" -> null
- router_id = "vrt-uf69bn1f7xp89m3xfk1f1" -> null
- router_table_id = "vtb-uf6pyfkc87awmxaa4do32" -> null
- secondary_cidr_blocks = [] -> null
- status = "Available" -> null
- user_cidrs = [] -> null
- vpc_name = "vpc_1" -> null
}
# alicloud_vswitch.vsw_1 will be destroyed
- resource "alicloud_vswitch" "vsw_1" {
- availability_zone = "cn-shanghai-b" -> null
- cidr_block = "10.0.0.0/24" -> null
- id = "vsw-uf6un6zempw6yvrpb9xmz" -> null
- name = "vsw_aliyun1" -> null
- status = "Available" -> null
- tags = {} -> null
- vpc_id = "vpc-uf6lprsrz6c1cshob79kc" -> null
- vswitch_name = "vsw_aliyun1" -> null
- zone_id = "cn-shanghai-b" -> null
}
Plan: 0 to add, 0 to change, 5 to destroy.
alicloud_security_group_rule.nsg_rule1: Destroying... [id=sg-uf642pxnc6msqptaoctg:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
alicloud_instance.instance: Destroying... [id=i-uf672vd7e0esv7i4lvjr]
alicloud_security_group_rule.nsg_rule1: Destruction complete after 0s
alicloud_instance.instance: Still destroying... [id=i-uf672vd7e0esv7i4lvjr, 10s elapsed]
alicloud_instance.instance: Destruction complete after 11s
alicloud_security_group.nsg1: Destroying... [id=sg-uf642pxnc6msqptaoctg]
alicloud_vswitch.vsw_1: Destroying... [id=vsw-uf6un6zempw6yvrpb9xmz]
alicloud_vswitch.vsw_1: Still destroying... [id=vsw-uf6un6zempw6yvrpb9xmz, 10s elapsed]
alicloud_security_group.nsg1: Still destroying... [id=sg-uf642pxnc6msqptaoctg, 10s elapsed]
alicloud_security_group.nsg1: Destruction complete after 16s
alicloud_vswitch.vsw_1: Still destroying... [id=vsw-uf6un6zempw6yvrpb9xmz, 20s elapsed]
alicloud_vswitch.vsw_1: Destruction complete after 23s
alicloud_vpc.vpc: Destroying... [id=vpc-uf6lprsrz6c1cshob79kc]
alicloud_vpc.vpc: Destruction complete after 5s
Destroy complete! Resources: 5 destroyed.
本文结束。