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 表达式、指令、模板文件等等,通过这些可以轻松的使我们实现更为复杂的场景。
接下来,以一个实战来演示一下 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"}# 创建vpcresource "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 initInitializing 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.htmlTerraform has made some changes to the provider dependency selections recordedin the .terraform.lock.hcl file. Review those changes and commit them to yourversion 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 seeany changes that are required for your infrastructure. All Terraform commandsshould 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, othercommands will detect it and remind you to do so if necessary.
执行terraform plan
➜ demo $ terraform planTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + createTerraform 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-approveTerraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + createTerraform 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-approvealicloud_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: - destroyTerraform 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 0salicloud_instance.instance: Still destroying... [id=i-uf672vd7e0esv7i4lvjr, 10s elapsed]alicloud_instance.instance: Destruction complete after 11salicloud_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 16salicloud_vswitch.vsw_1: Still destroying... [id=vsw-uf6un6zempw6yvrpb9xmz, 20s elapsed]alicloud_vswitch.vsw_1: Destruction complete after 23salicloud_vpc.vpc: Destroying... [id=vpc-uf6lprsrz6c1cshob79kc]alicloud_vpc.vpc: Destruction complete after 5sDestroy complete! Resources: 5 destroyed.
本文结束。