安装

https://www.terraform.io/downloads.html

对应系统下载二进制文件

验证

  1. 15:09:59 with lotter in Documents/terraform/aliyun
  2. ./terraform version
  3. Terraform v1.0.5
  4. on darwin_arm64
  5. + provider registry.terraform.io/hashicorp/alicloud v1.140.0
  6. Your version of Terraform is out of date! The latest version
  7. is 1.0.10. You can update by downloading from https://www.terraform.io/downloads.html

一个简单的例子

我们已Aliyun为例写一个简单的例子,创建一个空文件夹,在里面创建一个main.ft文件

  1. variable "access_key" {
  2. default = "xxxx"
  3. }
  4. variable "secret_key" {
  5. default = "xxxx"
  6. }
  7. varibale "region" {
  8. default = "xxxx"
  9. }
  10. provider "alicloud" {
  11. access_key = var.access_key
  12. secret_key = var.secret_key
  13. region = var.region
  14. }
  15. resource "alicloud_vpc" "vpc" {
  16. name = "testvpc"
  17. cidr_block = "172.16.0.0/12"
  18. }
  19. resource "alicloud_vswitch" "vsw" {
  20. vpc_id = "${alicloud_vpc.vpc.id}"
  21. cidr_block = "172.16.0.0/21"
  22. availability_zone = "cn-beijing-b"
  23. }
  24. resource "alicloud_security_group" "default" {
  25. name = "default"
  26. vpc_id = "${alicloud_vpc.vpc.id}"
  27. }
  28. resource "alicloud_instance" "instance" {
  29. # cn-beijing
  30. availability_zone = "cn-beijing-b"
  31. security_groups = ["${alicloud_security_group.default.id}"]
  32. # series III
  33. instance_type = "ecs.n2.small"
  34. system_disk_category = "cloud_efficiency"
  35. image_id = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
  36. instance_name = "test_foo"
  37. vswitch_id = "${alicloud_vswitch.vsw.id}"
  38. internet_max_bandwidth_out = 10
  39. }
  40. resource "alicloud_security_group_rule" "allow_all_tcp" {
  41. type = "ingress"
  42. ip_protocol = "tcp"
  43. nic_type = "intranet"
  44. policy = "accept"
  45. port_range = "1/65535"
  46. priority = 1
  47. security_group_id = "${alicloud_security_group.default.id}"
  48. cidr_ip = "0.0.0.0/0"
  49. }

这里要注意修改代码中的这一段:

  1. variable "access_key" {
  2. default = "xxxx"
  3. }
  4. variable "secret_key" {
  5. default = "xxxx"
  6. }
  7. varibale "region" {
  8. default = "xxxx"
  9. }

这里的 access_key secret_key region 换成自的

这段代码比较简单,头部的terraform这一段声明了这段代码所需要的aliyun插件,后面的varible段则是给出了调用Aliyun API所需要的key和区域等信息。

运行这段代码很简单,让我们在代码所在的路径下进入命令行,执行:

  1. terraform init

这时Terraform会进行初始化操作,通过官方插件仓库下载对应操作系统的aliyun插件。如果一切都正常,读者应该会看到:

  1. Terraform has been successfully initialized!
  2. You may now begin working with Terraform. Try running "terraform plan" to see
  3. any changes that are required for your infrastructure. All Terraform commands
  4. should now work.
  5. If you ever set or change modules or backend configuration for Terraform,
  6. rerun this command to reinitialize your working directory. If you forget, other
  7. commands will detect it and remind you to do so if necessary.

然后我们可以预览一下代码即将产生的变更:

  1. ./terraform plan
  2. Terraform used the selected providers to generate the following execution plan. Resource actions
  3. are indicated with the following symbols:
  4. + create
  5. Terraform will perform the following actions:
  6. # alicloud_instance.instance will be created
  7. + resource "alicloud_instance" "instance" {
  8. + availability_zone = "cn-beijing-b"
  9. + credit_specification = (known after apply)
  10. + deletion_protection = false
  11. + dry_run = false
  12. + host_name = (known after apply)
  13. + id = (known after apply)
  14. + image_id = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
  15. + instance_charge_type = "PostPaid"
  16. + instance_name = "test_foo"
  17. + instance_type = "ecs.n2.small"
  18. + internet_charge_type = "PayByTraffic"
  19. + internet_max_bandwidth_in = (known after apply)
  20. + internet_max_bandwidth_out = 10
  21. + key_name = (known after apply)
  22. + private_ip = (known after apply)
  23. + public_ip = (known after apply)
  24. + role_name = (known after apply)
  25. + security_groups = (known after apply)
  26. + spot_strategy = "NoSpot"
  27. + status = "Running"
  28. + subnet_id = (known after apply)
  29. + system_disk_category = "cloud_efficiency"
  30. + system_disk_performance_level = (known after apply)
  31. + system_disk_size = 40
  32. + volume_tags = (known after apply)
  33. + vswitch_id = (known after apply)
  34. }
  35. # alicloud_security_group.default will be created
  36. + resource "alicloud_security_group" "default" {
  37. + id = (known after apply)
  38. + inner_access = (known after apply)
  39. + inner_access_policy = (known after apply)
  40. + name = "default"
  41. + security_group_type = "normal"
  42. + vpc_id = (known after apply)
  43. }
  44. # alicloud_security_group_rule.allow_all_tcp will be created
  45. + resource "alicloud_security_group_rule" "allow_all_tcp" {
  46. + cidr_ip = "0.0.0.0/0"
  47. + id = (known after apply)
  48. + ip_protocol = "tcp"
  49. + nic_type = "intranet"
  50. + policy = "accept"
  51. + port_range = "1/65535"
  52. + priority = 1
  53. + security_group_id = (known after apply)
  54. + type = "ingress"
  55. }
  56. # alicloud_vpc.vpc will be created
  57. + resource "alicloud_vpc" "vpc" {
  58. + cidr_block = "172.16.0.0/12"
  59. + id = (known after apply)
  60. + ipv6_cidr_block = (known after apply)
  61. + name = "testvpc"
  62. + resource_group_id = (known after apply)
  63. + route_table_id = (known after apply)
  64. + router_id = (known after apply)
  65. + router_table_id = (known after apply)
  66. + status = (known after apply)
  67. + vpc_name = (known after apply)
  68. }
  69. # alicloud_vswitch.vsw will be created
  70. + resource "alicloud_vswitch" "vsw" {
  71. + availability_zone = "cn-beijing-b"
  72. + cidr_block = "172.16.0.0/21"
  73. + id = (known after apply)
  74. + name = (known after apply)
  75. + status = (known after apply)
  76. + vpc_id = (known after apply)
  77. + vswitch_name = (known after apply)
  78. + zone_id = (known after apply)
  79. }
  80. Plan: 5 to add, 0 to change, 0 to destroy.

这段输出告诉我们,代码即将创建5个新资源,修改0个资源,删除0个资源。资源的属性少部分是我们在代码中直接给出的,或是通过data查询的,所以在plan命令的结果中可以看到它们的值;更多的属性只有在资源真正被创建以后我们才能看到,所以会显示“(known after apply)”。

然后我们运行一下:

➜ ./terraform apply

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-beijing-b"
      + credit_specification          = (known after apply)
      + deletion_protection           = false
      + dry_run                       = false
      + host_name                     = (known after apply)
      + id                            = (known after apply)
      + image_id                      = "ubuntu_140405_64_40G_cloudinit_20161115.vhd"
      + instance_charge_type          = "PostPaid"
      + instance_name                 = "test_foo"
      + instance_type                 = "ecs.n2.small"
      + internet_charge_type          = "PayByTraffic"
      + internet_max_bandwidth_in     = (known after apply)
      + internet_max_bandwidth_out    = 10
      + key_name                      = (known after apply)
      + private_ip                    = (known after apply)
      + public_ip                     = (known after apply)
      + role_name                     = (known after apply)
      + security_groups               = (known after apply)
      + spot_strategy                 = "NoSpot"
      + status                        = "Running"
      + subnet_id                     = (known after apply)
      + system_disk_category          = "cloud_efficiency"
      + system_disk_performance_level = (known after apply)
      + system_disk_size              = 40
      + volume_tags                   = (known after apply)
      + vswitch_id                    = (known after apply)
    }

  # alicloud_security_group.default will be created
  + resource "alicloud_security_group" "default" {
      + id                  = (known after apply)
      + inner_access        = (known after apply)
      + inner_access_policy = (known after apply)
      + name                = "default"
      + security_group_type = "normal"
      + vpc_id              = (known after apply)
    }

  # alicloud_security_group_rule.allow_all_tcp will be created
  + resource "alicloud_security_group_rule" "allow_all_tcp" {
      + cidr_ip           = "0.0.0.0/0"
      + id                = (known after apply)
      + ip_protocol       = "tcp"
      + nic_type          = "intranet"
      + policy            = "accept"
      + port_range        = "1/65535"
      + priority          = 1
      + security_group_id = (known after apply)
      + type              = "ingress"
    }

  # alicloud_vpc.vpc will be created
  + resource "alicloud_vpc" "vpc" {
      + cidr_block        = "172.16.0.0/12"
      + id                = (known after apply)
      + ipv6_cidr_block   = (known after apply)
      + name              = "testvpc"
      + resource_group_id = (known after apply)
      + route_table_id    = (known after apply)
      + router_id         = (known after apply)
      + router_table_id   = (known after apply)
      + status            = (known after apply)
      + vpc_name          = (known after apply)
    }

  # alicloud_vswitch.vsw will be created
  + resource "alicloud_vswitch" "vsw" {
      + availability_zone = "cn-beijing-b"
      + cidr_block        = "172.16.0.0/21"
      + id                = (known after apply)
      + name              = (known after apply)
      + status            = (known after apply)
      + vpc_id            = (known after apply)
      + vswitch_name      = (known after apply)
      + zone_id           = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

当我们运行terraform apply时,Terraform会首先重新计算一下变更计划,并且像刚才执行plan命令那样把变更计划打印给我们,要求我们人工确认。让我们输入yes,然后回车:

alicloud_vpc.vpc: Creating...
alicloud_vpc.vpc: Still creating... [10s elapsed]
alicloud_vpc.vpc: Creation complete after 10s [id=vpc-2ze35sbnt00zzzpe0rtq5]
alicloud_vswitch.vsw: Creating...
alicloud_security_group.default: Creating...
alicloud_security_group.default: Creation complete after 1s [id=sg-2ze5e25nj5svwan0wfw3]
alicloud_security_group_rule.allow_all_tcp: Creating...
alicloud_security_group_rule.allow_all_tcp: Creation complete after 1s [id=sg-2ze5e25nj5svwan0wfw3:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]
alicloud_vswitch.vsw: Creation complete after 6s [id=vsw-2zeeyjfvne3x4nfy9aaqh]
alicloud_instance.instance: Creating...
alicloud_instance.instance: Still creating... [10s elapsed]
alicloud_instance.instance: Still creating... [20s elapsed]
alicloud_instance.instance: Creation complete after 22s [id=i-2zeae73xjmeps06h1jlc]

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

可以看到,Terraform成功地创建了我们定义的资源,并且把我们定义的输出给打印了出来。

清理

完成这个体验后,不要忘记清理我们的云端资源。我们可以通过调用destroy命令来轻松完成清理:

➜ ./terraform destroyalicloud_vpc.vpc: Refreshing state... [id=vpc-2ze35sbnt00zzzpe0rtq5]alicloud_security_group.default: Refreshing state... [id=sg-2ze5e25nj5svwan0wfw3]alicloud_vswitch.vsw: Refreshing state... [id=vsw-2zeeyjfvne3x4nfy9aaqh]alicloud_security_group_rule.allow_all_tcp: Refreshing state... [id=sg-2ze5e25nj5svwan0wfw3:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]alicloud_instance.instance: Refreshing state... [id=i-2zeae73xjmeps06h1jlc]Note: Objects have changed outside of TerraformTerraform detected the following changes made outside of Terraform since the last "terraformapply":  # alicloud_security_group.default has been changed  ~ resource "alicloud_security_group" "default" {        id                  = "sg-2ze5e25nj5svwan0wfw3"        name                = "default"      + tags                = {}        # (4 unchanged attributes hidden)    }  # alicloud_vpc.vpc has been changed  ~ resource "alicloud_vpc" "vpc" {        id                    = "vpc-2ze35sbnt00zzzpe0rtq5"        name                  = "testvpc"      + secondary_cidr_blocks = []      + user_cidrs            = []        # (6 unchanged attributes hidden)    }  # alicloud_vswitch.vsw has been changed  ~ resource "alicloud_vswitch" "vsw" {        id                = "vsw-2zeeyjfvne3x4nfy9aaqh"      + tags              = {}        # (5 unchanged attributes hidden)    }  # alicloud_instance.instance has been changed  ~ resource "alicloud_instance" "instance" {        id                         = "i-2zeae73xjmeps06h1jlc"      + tags                       = {}        # (22 unchanged attributes hidden)    }Unless you have made equivalent changes to your configuration, or ignored the relevantattributes using ignore_changes, the following plan may include actions to undo or respond tothese changes.────────────────────────────────────────────────────────────────────────────────────────────────Terraform used the selected providers to generate the following execution plan. Resource actionsare indicated with the following symbols:  - destroyTerraform will perform the following actions:  # alicloud_instance.instance will be destroyed  - resource "alicloud_instance" "instance" {      - availability_zone          = "cn-beijing-b" -> null      - deletion_protection        = false -> null      - dry_run                    = false -> null      - host_name                  = "iZ2zeae73xjmeps06h1jlcZ" -> null      - id                         = "i-2zeae73xjmeps06h1jlc" -> null      - image_id                   = "ubuntu_140405_64_40G_cloudinit_20161115.vhd" -> null      - instance_charge_type       = "PostPaid" -> null      - instance_name              = "test_foo" -> null      - instance_type              = "ecs.n2.small" -> null      - internet_charge_type       = "PayByTraffic" -> null      - internet_max_bandwidth_in  = -1 -> null      - internet_max_bandwidth_out = 10 -> null      - private_ip                 = "172.16.1.28" -> null      - public_ip                  = "123.57.53.71" -> null      - security_groups            = [          - "sg-2ze5e25nj5svwan0wfw3",        ] -> null      - spot_price_limit           = 0 -> null      - spot_strategy              = "NoSpot" -> null      - status                     = "Running" -> null      - subnet_id                  = "vsw-2zeeyjfvne3x4nfy9aaqh" -> null      - system_disk_category       = "cloud_efficiency" -> null      - system_disk_size           = 40 -> null      - tags                       = {} -> null      - volume_tags                = {} -> null      - vswitch_id                 = "vsw-2zeeyjfvne3x4nfy9aaqh" -> null    }  # alicloud_security_group.default will be destroyed  - resource "alicloud_security_group" "default" {      - id                  = "sg-2ze5e25nj5svwan0wfw3" -> null      - inner_access        = true -> null      - inner_access_policy = "Accept" -> null      - name                = "default" -> null      - security_group_type = "normal" -> null      - tags                = {} -> null      - vpc_id              = "vpc-2ze35sbnt00zzzpe0rtq5" -> null    }  # alicloud_security_group_rule.allow_all_tcp will be destroyed  - resource "alicloud_security_group_rule" "allow_all_tcp" {      - cidr_ip           = "0.0.0.0/0" -> null      - id                = "sg-2ze5e25nj5svwan0wfw3: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-2ze5e25nj5svwan0wfw3" -> null      - type              = "ingress" -> null    }  # alicloud_vpc.vpc will be destroyed  - resource "alicloud_vpc" "vpc" {      - cidr_block            = "172.16.0.0/12" -> null      - id                    = "vpc-2ze35sbnt00zzzpe0rtq5" -> null      - name                  = "testvpc" -> null      - route_table_id        = "vtb-2zetq5inr8gjwpasz1s1r" -> null      - router_id             = "vrt-2zemc0u9346x2sbzc0lz2" -> null      - router_table_id       = "vtb-2zetq5inr8gjwpasz1s1r" -> null      - secondary_cidr_blocks = [] -> null      - status                = "Available" -> null      - user_cidrs            = [] -> null      - vpc_name              = "testvpc" -> null    }  # alicloud_vswitch.vsw will be destroyed  - resource "alicloud_vswitch" "vsw" {      - availability_zone = "cn-beijing-b" -> null      - cidr_block        = "172.16.0.0/21" -> null      - id                = "vsw-2zeeyjfvne3x4nfy9aaqh" -> null      - status            = "Available" -> null      - tags              = {} -> null      - vpc_id            = "vpc-2ze35sbnt00zzzpe0rtq5" -> null      - zone_id           = "cn-beijing-b" -> null    }Plan: 0 to add, 0 to change, 5 to destroy.Do you really want to destroy all resources?  Terraform will destroy all your managed infrastructure, as shown above.  There is no undo. Only 'yes' will be accepted to confirm.  Enter a value:  yes

可以看到,Terraform列出了它即将清理的资源信息,并且要求我们人工确认同意继续执行清理操作。我们输入yes,然后回车:

alicloud_security_group_rule.allow_all_tcp: Destroying... [id=sg-2ze5e25nj5svwan0wfw3:ingress:tcp:1/65535:intranet:0.0.0.0/0:accept:1]alicloud_instance.instance: Destroying... [id=i-2zeae73xjmeps06h1jlc]alicloud_security_group_rule.allow_all_tcp: Destruction complete after 0salicloud_instance.instance: Still destroying... [id=i-2zeae73xjmeps06h1jlc, 10s elapsed]alicloud_instance.instance: Destruction complete after 11salicloud_vswitch.vsw: Destroying... [id=vsw-2zeeyjfvne3x4nfy9aaqh]alicloud_security_group.default: Destroying... [id=sg-2ze5e25nj5svwan0wfw3]alicloud_security_group.default: Still destroying... [id=sg-2ze5e25nj5svwan0wfw3, 10s elapsed]alicloud_vswitch.vsw: Still destroying... [id=vsw-2zeeyjfvne3x4nfy9aaqh, 10s elapsed]alicloud_security_group.default: Destruction complete after 17salicloud_vswitch.vsw: Still destroying... [id=vsw-2zeeyjfvne3x4nfy9aaqh, 20s elapsed]alicloud_vswitch.vsw: Still destroying... [id=vsw-2zeeyjfvne3x4nfy9aaqh, 30s elapsed]alicloud_vswitch.vsw: Destruction complete after 32salicloud_vpc.vpc: Destroying... [id=vpc-2ze35sbnt00zzzpe0rtq5]alicloud_vpc.vpc: Destruction complete after 5sDestroy complete! Resources: 5 destroyed.

Terraform与以往诸如Ansible等配置管理工具比较大的不同在于,它是根据代码计算出的目标状态与当前状态的差异来计算变更计划的,有兴趣的读者可以在执行terraform apply以后,直接再执行一次terraform apply,看看会发生什么,就能明白他们之间的差异。

实际上这段代码在apply以后,直接再次apply,得到的计划会是什么也不做,因为当前云端的资源状态已经完全符合代码所描述的期望状态了,所以Terraform什么也不会做。好了,这就是我们对Terraform的一个初步体验。