为 Terraform 插上 CLI 的翅膀

如今的云计算已经不再是那个仅仅只会计算、只会存储、只会连接的机器的集合,互联网业务的敏捷化、智能化、复杂化不断推动着云计算变得更加自动和智能。
从DevOps到IaC,从公有云、私有云到多云管理,Terraform 在基础设施管理领域的地位已经变的越来越举足轻重,用户对Terraform的喜爱也在日益增强。

目前阿里云对 Terraform 的支持已经超过了50个resource,将近20个data source,但这远远无法满足用户复杂多样的业务场景,给用户一种意犹未尽的感觉。

面对 Terraform 暂时还未来得及支持的 resource,用户如何借助 Terraform 继续对资源进行自动化管理呢?这里就要用到一款几乎已经覆盖了所有的阿里云资源的万能管理工具 Aliyun CLI。Terraform 基于阿里云 CLI 的全面覆盖,可帮助用户基于 Terraform 实现对全阿里云资源的自动化管理。

本文是 CLI+Terraform简化资源管理的模板编写 的延伸,有关 Terraform 的使用和介绍可在云栖社区搜索相关文档,如 云生态下的基础架构资源管理利器Terraform,有关 CLI 的使用和安装,可详见 aliyun-cli,本文不再赘述。

Terraform 如何实现对阿里云 CLI 的有效调用呢?

Terraform 如何实现对阿里云 CLI 的自动化调用呢?这里就要用到 Terraform 自身的一个 resource null_resource 和 provisioner local-execlocal-exec 是一个本地命令的执行器,它既可以被应用到已有资源,如 alicloud_instance 中,也可以在独立的 resource null_resource 中实现对其他资源的管理。目前,阿里云 Terraform Provider 尚未实现对阿里云云监控的支持,本文将以云监控的报警规则为例,向大家展示如何基于 terraform 为一台 ECS 实例添加一条云监控报警规则。

创建演示实例 ECS

首先,基于 terraform 创建一台 VPC 类型的 ECS,模板如下:

//
// Create a i CPU 2 G ECS
data "alicloud_instance_types" "main" {
  cpu_core_count = 1
  memory_size = 2
}

// Get a available zone which matchs a specified instance type
data "alicloud_zones" "main" {
  available_resource_creation = "VSwitch"
  available_instance_type = "${data.alicloud_instance_types.main.instance_types.0.id}"
}

// Use Centos
data "alicloud_images" main {
  most_recent = true
  name_regex = "^centos_6\\w{1,5}[64].*"
}

// Create a new VPC
resource "alicloud_vpc" "main" {
  name = "test_for_cloudmonitor"
  cidr_block = "10.1.0.0/21"
}

// Create a new VSwitch in the VPC
resource "alicloud_vswitch" "main" {
  vpc_id = "${alicloud_vpc.main.id}"
  cidr_block = "10.1.1.0/24"
  availability_zone = "${data.alicloud_zones.main.zones.0.id}"
}

// Create a new security group in the VPC
resource "alicloud_security_group" "main" {
  vpc_id = "${alicloud_vpc.main.id}"
}

// Create test instance
resource "alicloud_instance" "main" {
  instance_name = "test_for_add_alarm_rule"
  instance_type = "${data.alicloud_instance_types.main.instance_types.0.id}"
  image_id = "${data.alicloud_images.main.images.0.id}"
  vswitch_id = "${alicloud_vswitch.main.id}"
  security_groups = ["${alicloud_security_group.main.id}"]
}

创建报警规则

由于 Terraform 暂时不支持对报警规则的创建,因此先使用 CLI 代替。

首先,打开创建报警规则的 Open API 页面。接着,根据API参数要求和请求实例,拼接 CLI 创建命令:

aliyun cms CreateAlarm --access-key-id ${var.access_key} --access-key-secret ${var.secret_key} --region ${var.region} --Name tf-alarm --Namespace acs_ecs_dashboard --MetricName vm.MemoryUtilization --Dimensions [{\"instanceId\":\"${alicloud_instance.main.id}\"] --Statistics Average --Period 900  --ComparisonOperator "<=" --Threshold 35 --EvaluationCount 2 --ContactGroups [\"test-group\"] --EndTime 20 --StartTime 6 --NotifyType 1

CLI命令拼接好以后,利用 null_resourcelocal_exec 来执行:

resource "null_resource" "main" {
  provisioner "local-exec" {
    command = <<EOF
        aliyun cms CreateAlarm --access-key-id ${var.access_key} --access-key-secret ${var.secret_key} --region ${var.region} --Name tf-alarm --Namespace acs_ecs_dashboard --MetricName vm.MemoryUtilization --Dimensions [{\"instanceId\":\"${alicloud_instance.main.id}\"] --Statistics Average --Period 900  --ComparisonOperator "<=" --Threshold 35 --EvaluationCount 2 --ContactGroups [\"test-group\"] --EndTime 20 --StartTime 6 --NotifyType 1
    EOF
  }
}

已经创建 ECS 和报警规则

执行命令 terraform apply,创建ECS和报警规则:

$ terraform apply -auto-approve

执行结果如下:

...

alicloud_instance.main: Creation complete after 55s (ID: i-2ze0v7...)
null_resource.main: Creating...
null_resource.main: Provisioning with 'local-exec'...
null_resource.main (local-exec): Executing: ["/bin/sh" "-c" "        aliyun cms CreateAlarm --access-key-id ... --access-key-secret ... --region cn-beijing --Name tf-alarm --Namespace acs_ecs_dashboard --MetricName vm.MemoryUtilization --Dimensions [{\\\"instanceId\\\":\\\"i-2ze0v7...\\\"] --Statistics Average --Period 900  --ComparisonOperator \"<=\" --Threshold 35 --EvaluationCount 2 --ContactGroups [\\\"test-group\\\"] --EndTime 20 --StartTime 6 --NotifyType 1\n    "]
null_resource.main (local-exec): {"Data":"364AD48DC428558BE6.....","RequestId":"186A7B60-D673-414A-8.....","Success":true,"Code":"200"}
null_resource.main: Creation complete after 1s (ID: 1044683700884121057)

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

创建完成后,登录云监控控制台-报警服务-报警规则 即可查看已经创建的报警规则:

为 Terraform 插上 CLI 的翅膀

或者,可以再次使用 null_resource 进行查看:

resource "null_resource" "describe" {
  provisioner "local-exec" {
    command = <<EOF
        aliyun cms ListAlarm --access-key-id ${var.access_key} --access-key-secret ${var.secret_key} --region ${var.region} --Name tf-alarm --Namespace acs_ecs_dashboard --Dimension [{\"instanceId\":\"${alicloud_instance.main.id}\"}]
    EOF
  }
}

如何简化 CLI Command

为了更方便的管理和变更资源属性,可以使用environment 来存放 CLI Command 中的参数值,如下所示:

resource "null_resource" "env" {
  provisioner "local-exec" {
    command = <<EOF
        aliyun cms CreateAlarm --access-key-id ${var.access_key} --access-key-secret ${var.secret_key} --region ${var.region} --Name $Name --Namespace $Namespace --MetricName $MetricName --Dimensions $Dimensions --Statistics $Statistics --Period $Period  --ComparisonOperator $ComparisonOperator --Threshold $Threshold --EvaluationCount $EvaluationCount --ContactGroups $ContactGroups --EndTime $EndTime --StartTime $StartTime --NotifyType $NotifyType
    EOF
    environment {
      Name = "tf-alarm"
      Namespace = "acs_ecs_dashboard"
      MetricName = "vm.MemoryUtilization"
      Dimensions = "[{\"instanceId\":\"${alicloud_instance.main.id}\"]"
      Statistics = "Average"
      Period = 900
      ComparisonOperator = "<="
      Threshold = 35
      EvaluationCount = 2
      ContactGroups = "[\"test-group\"]"
      EndTime = 20
      StartTime = 6
      NotifyType = 1
    }
  }
}

值得注意的是,environment 要求 terraform version >= v0.11.4

更近一步,由于 API 的参数相对固定不变,为了提高 CLI Command 命令的可重用性,可以将 Command 存放在 Shell Script 中,如 “create_cloudmonitor.sh”,然后直接在模板中执行 “create_cloudmonitor.sh” 即可:

resource "null_resource" "script" {
  provisioner "local-exec" {
    command = <<EOF
        sh ./create_cloudmonitor.sh
    EOF
  }
}

写在最后

本文主要讲述了 Terraform 如何 CLI 来管理自身缺失的 resource。通过本文的介绍,我们可以发现,只要阿里云产品提供了 Open API,都可以利用 Terraform 来实现对该资源的有效管理,避免了因 Terraform resource 提供不及时而带来的不便。

目前,面向阿里云的 Terraform Provider 仍在不断的发展和完善中,欢迎大家使用和提供宝贵的意见和建议。以下是相关参考资料,欢迎大家查阅。

Terraform Provider Github 地址https://github.com/terraform-providers/terraform-provider-alicloud
Terraform Provider Documenthttps://www.terraform.io/docs/providers/alicloud/index.html
Terraform Provider Releasehttps://releases.hashicorp.com/terraform-provider-alicloud/

备注:本文所涉及到的模板,可通过附件下载和使用。

上一篇:BT详解


下一篇:Terraform Module 编写指南