阿里云Terraform Demo

所有的语言描述不如实际操作 – 很多Terraform的Hello World案例都是基于AWS的(毕竟云计算的No.1),然而,作为国内云厂商No.1,阿里云同样也提供了Terraform支持。

备注

本章节我们来演示如何从0开始在阿里云上运行Hello World Demo。

Provider

Provider是Terraform的基础设施后端驱动,也就是对应每个云计算厂商,包含资源元数据定义,上层请求的处理和后端OpenAPI的调用和响应处理。Terraform调用不同的Provider来完成不同类型资源的同意管理。阿里云的Provider名为 alicloud

Provider不需要手工安装,Terraform会在 init 阶段根据模板地影自动夹在,即关键字 provider 声明:

provider "alicloud" {
    profile = "terraform"
    region = "cn-hangzhou"
}

备注

  • provider 指定需要插件``alicloud``

  • 大括号中配置提供了Provider的配置 - profile 表示可以从阿里云帐号 ~/.aliyun/config.json 中名为 terraform 的配置信息中读取 - region 则定义资源创建在杭州区域

阿里云帐号

阿里云CLI

安装参考 Linux平台MacOS平台aliyun-cli Releases 安装阿里云CLI(以下案例为Linux):

# 假设下载文件在 ~/Download 目录下
cd  $HOME/Download
tar xfz aliyun-cli-linux-3.0.30-amd64.tgz
sudo mv aliyun /usr/local/bin

AK

请参考 配置阿里云CLI > 配置凭证 > 非交互式配置 帮助文档配置阿里云访问凭证(案例是AK):

aliyun configure set \
  --profile terraform \
  --mode AK \
  --region cn-hangzhou \
  --access-key-id AccessKeyId \
  --access-key-secret AccessKeySecret

上述命令将在 ~/.aliyun 目录下创建AK配置文件 config.json

备注

这里传递的参数 --profile terraform 表示在AK配置文件中添加名为 terraform 的profile

部署简单服务器

初始化Terraform

Terraform代码使用了 HashiCorp Configuration Language(HCL),代码文件扩展名为 .tf ,在一个空目录(假设我创建了一个目录 terraform-demo 下创建一个 main.tf 文件作为主程序:

provider "alicloud" {
    profile = "terraform"
    region = "cn-hangzhou"
}

备注

这里 profile 引用了前面使用 aliyun 命令创建的访问凭证。如果没有使用上述访问凭证,你也可以在 provider "aliclou" 中直接添加AK,但是这样公布的``.tf``配置缺乏安全性:

provider “alicloud” {

access_key = “${var.access_key}” secret_key = “${var.secret_key}” region = “${var.region}”

}

然后执行以下命令初始化:

terraform init

此时会看到Terraform开始下载名为 aliclouod 的provider插件

定义资源

resource是Terraform中特定基础设置资源,通过 create, update, read, delete 方法的实现来管理特定资源的生命周期。

在上述 main.tf 中添加:

resource "alicloud_instance" "default" {
   image_id = "centos_7_7_64_20G_alibase_20191008.vhd"
   instance_type = "ecs.t6-c4m1.large"
   instance_name = "terraform-demo"
}

备注

阿里云ECS的规格价格差异很大,作为学习和验证,请在ECS的控制台先交互选择合适规格再使用Terraform对应创建,以节约使用费用。这里选择价格低廉的入门级(共享)实例 ecs.t6-c4m1.large

计划Plan

在完成基础配置之后,通过 terraform plan 命令可以预览代码执行效果,调试是否存在问题。

例如,上述 resource 配置,对应执行 terraform plan 会提示还缺少必要参数:

Error: Missing required argument

   on main.tf line 6, in resource "alicloud_instance" "default":
    6: resource "alicloud_instance" "default" {

The argument "security_groups" is required, but no definition was found.

所以,我从交互方式创建的ECS实例获取安全组名称,假设名字是 sg-bp1ceir9l2mgph4bp5kx ,所以修改上述配置,添加内容:

security_groups = ["sg-bp1ceir9l2mgph4bp5kx"]

备注

安全组可以通过Terraform来创建,后续补充。初始时,你可以通过ECS的WEB管控台先构建一个安全组,然后把该安全组作为实验使用。

安全组是一个字符串集,所以需要使用 [] 括起一个或多个安全组字符串。

现在我们再次执行 terraform plan 命令,不再报错,表明已经就绪,可以执行了:

terraform will perform the following actions:

  # alicloud_instance.default will be created
  + resource "alicloud_instance" "default" {
      + availability_zone          = (known after apply)
      + credit_specification       = (known after apply)
      + deletion_protection        = false
      + dry_run                    = false
      + host_name                  = (known after apply)
      + id                         = (known after apply)
      + image_id                   = "centos_7_7_64_20G_alibase_20191008.vhd"
      + instance_charge_type       = "PostPaid"
      + instance_name              = "terraform-demo"
      + instance_type              = "ecs.t6-c4m1.large"
      + internet_max_bandwidth_in  = (known after apply)
      + internet_max_bandwidth_out = 0
      + key_name                   = (known after apply)
      + private_ip                 = (known after apply)
      + public_ip                  = (known after apply)
      + role_name                  = (known after apply)
      + security_groups            = [
          + "sg-bp1ceir9l2mgph4bp5kx",
        ]
      + spot_strategy              = "NoSpot"
      + status                     = (known after apply)
      + subnet_id                  = (known after apply)
      + system_disk_category       = "cloud_efficiency"
      + system_disk_size           = 40
      + volume_tags                = (known after apply)
    }

apply执行

执行一下命令运行Terraform计划:

terraform apply

好吧,实际上云计算资源还要再复杂一点,此时提示创建失败:

alicloud_instance.default: Creating...

Error: [ERROR] terraform-provider-alicloud/alicloud/resource_alicloud_instance.go:373:
[ERROR] terraform-provider-alicloud/alicloud/resource_alicloud_instance.go:844:
The specified security_group_id sg-bp1ceir9l2mgph4bp5kx is in a VPC vpc-bp1kvl6pjf6wzwpifhcig, and `vswitch_id` is required when creating a new instance resource in a VPC.

  on main.tf line 6, in resource "alicloud_instance" "default":
   6: resource "alicloud_instance" "default" {

原因是VPC创建缺少相关信息 vswitch_id ,我这里再次使用通过WEB管理界面创建一个实例,然后检查样例所使用的vswitch信息,这样得到配置,在资源配置中添加:

vswitch_id = "vsw-bp15z1k91emrdg2pqqkuo"

这样综上所述,较为完整的配置 main.cf 内容如下:

provider "alicloud" {
    profile = "terraform"
    region = "cn-hangzhou"
}

resource "alicloud_instance" "default" {
   image_id = "centos_7_7_64_20G_alibase_20191008.vhd"
   instance_type = "ecs.t6-c4m1.large"
   instance_name = "terraform-demo"
   security_groups = ["sg-bp1ceir9l2mgph4bp5kx"]
   vswitch_id = "vsw-bp15z1k91emrdg2pqqkuo"
}

现在我们执行 terraform apply 则提示创建实例:

alicloud_instance.default: Creating...
alicloud_instance.default: Still creating... [10s elapsed]
alicloud_instance.default: Creation complete after 17s [id=i-bp1f6ny09icnetnvui0n]

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

现在登陆ECS console检查可以看到刚刚创建的实例 i-bp1f6ny09icnetnvui0n ,注意,这个实例只是简单默认配置:

  • 单网卡,无公网IP地址

  • 没有必要的配置,例如帐号

但我们至少已经创建了一个实例,可以开始进一步探索了。

resource变更

资源变更只需要修改模板定义的属性值,Terraform资源变更有两种情况:

  • 原地变更(update in-place)

即不改变资源生命周期情况下(不销毁,不重启)实现对资源属性修改,例如修改资源名称,描述,标签等。

  • 重建变更(destroy and then create replacement)

参考