当Terraform遇上ECS(一)——DataSource篇

    xiaoxiao2025-10-11  11

    背景

    越来越多的公司已经熟知并运用“基础设施即代码”来构建和维护自己的云基础设施。目前也有许多的自动化构建工具协助用户通过脚本进行云资源的部署和生命周期的管理,如:Terraform、Ansible、Chef等。但是,在实施过程中,都遇到了如何获取镜像id、可用区、实例类型id,如何跟自己的脚本相结合而备受困扰?

    请首先检查一下您的构建脚本,是否有imageId=centos_6u8_64_40G_cloudinit_20161115.vhd、instanceType=ecs.s2.large、zoneId=cn-beijing-a,类似这样hardcode的代码或者配置?您是否遇到过前几天还顺利运行的脚本, 再次创建的时候却报Image.Invalid错误?另外,您是通过什么方式获取到的这些code值,通过ECS售卖页?本文介绍如何通过Terraform Data Source完美解决这些问题,优雅的创建ECS instance。

    Terraform简介

    Terraform 是管理云基础设施的开源工具,支持阿里云、AWS、Azure、GoogleCloud、DigitalOcean等。他通过模板来定义基础设施,通过指令来实现资源创建/更新/销毁的全生命周期管理。创建ECS实例模板如下:

    resource "alicloud_instance" "web" { # cn-beijing availability_zone = "cn-beijing-b" image_id = "ubuntu_140405_32_40G_cloudinit_20161115.vhd" system_disk_category = "cloud_ssd" instance_type = "ecs.n1.small" internet_charge_type = "PayByBandwidth" security_groups = ["${alicloud_security_group.tf_test_foo.id}"] instance_name = "test_foo" io_optimized = "optimized" }

    Install Terraform, 然后执行terraform apply,稍等片刻一台ECS实例就被创建完成。

    Resource Data简介

    对于常用的查询类资源,可以通过Resource Data实时获取,也能在模板中进行引用。Resource Data是只读类型的资源,支持参数过滤,不会改变基础架构状态。这里以Ecs instance_type为例,做一个介绍:

    之前:根据需要去ECS售卖页上去筛选实例规格,然后把规格code复制、粘贴到模板中。这种方式,不仅操作繁琐,也跟自动化运维的思路不相称。现在:以描述的方式填写过滤条件,Resource Data会进行查询并返回结果,模板片段如下: data "alicloud_instance_types" "1c2g" { cpu_core_count = 1 memory_size = 2 }

    这里,我们定义了一个1核2G的Resource Data。执行terraform apply,您将会得到所有1核2G实例规格的一个Map,如下图:

    { "cpu_core_count": "1", "memory_size": "2", "id": "2404647170", "instance_types.#": "3", "instance_types.0.cpu_core_count": "1", "instance_types.0.family": "ecs.s1", "instance_types.0.id": "ecs.s1.small", "instance_types.0.memory_size": "2", "instance_types.1.cpu_core_count": "1", "instance_types.1.family": "ecs.n1", "instance_types.1.id": "ecs.n1.small", "instance_types.1.memory_size": "2", "instance_types.2.cpu_core_count": "1", "instance_types.2.family": "ecs.n4", "instance_types.2.id": "ecs.n4.small", "instance_types.2.memory_size": "2" }

    其中,

    - `cpu_core_count`和`memory_size`是我们自定义的筛选条件 - `instance_types.#`代表返回结果条目数 - 每个实例类型的结构包含`cpu_core_count`、`family`、`id`、`memory_size`四个属性。其中id是实例规格ID,如`ecs.s1.small`

    创建Ecs实例

    Terraform 已经集成了阿里云地域、可用区、镜像、实例规格类型几种常用Data Resource. 这几个资源组合到一起,可以发挥更大的作用。

    举个例子:在大多数情况下,我们往往并不是非常关心实例具体到哪个可用区,但是API接口又需要我们指明可用区,然而不同可用区支持的实例类型、磁盘类型、网络类型都不同。要选到满意的搭配,需要煞费一番周折。但是,通过组合Data Source,多重过滤参数,可以很轻松的进行选配,即使调整参数,也不需要在页面上点来点去。

    一般的购买行为是这样的:首先,我们都会有个初始需求。比如,操作系统必须是centos的,实例类型是低配的(1c1g ~ 2c2g),磁盘类型需要是固态云盘。然后,根据这个清单去尝试购买资源,这个过程中根据库存情况进行微调。

    用模板描述资源过程是类似的:先定义镜像、实例类型和可用区的筛选条件,然后在Ecs的配置中引用他们,最后尝试去创建资源。如果库存不足,则进行参数调整。

    模板如下:

    data "alicloud_images" "centos" { owners = "system" name_regex = "^centos_6" } data "alicloud_instance_types" "1c2g" { cpu_core_count = 1 memory_size = 2 instance_type_family = "ecs.n1" } data "alicloud_zones" "default" { "available_instance_type"= "${data.alicloud_instance_types.1c2g.instance_types.0.id}" "available_disk_category"= "cloud_ssd" } resource "alicloud_instance" "instance" { image_id = "${data.alicloud_images.centos.0.image_id}" instance_type = "${data.alicloud_instance_types.1c2g.instance_types.0.id}" availability_zone = "${data.alicloud_zones.default.zones.0.id}" security_groups = ["${alicloud_security_group.group.id}"] internet_charge_type = "PayByTraffic" io_optimized = "optimized" instance_charge_type = "PostPaid" system_disk_category = "cloud_ssd" } resource "alicloud_security_group" "group" { name = "tf-sg" description = "New security group" }

    模板详解:

    alicloud_images: 筛选centos类型的系统镜像alicloud_instance_types: 选择1核2G的Ecs实例规格alicloud_zones: 选择支持上述实例类型的可用区alicloud_instance: 描述Ecs 实例配置alicloud_security_group: 定义安全组

    运行terraform apply,结果如下:

    data.alicloud_instance_types.1c2g: Refreshing state... data.alicloud_images.centos: Refreshing state... data.alicloud_zones.default: Refreshing state... alicloud_security_group.group: Creating... description: "" => "New security group" name: "" => "tf-sg" alicloud_security_group.group: Creation complete alicloud_instance.instance: Creating... availability_zone: "" => "cn-beijing-c" instance_type: "" => "ecs.n1.small" image_id: "" => "centos_6u8_64_40G_cloudinit_20161115.vhd"

    从运行结果来看,我们并没有提前指定实例类型、镜像、可用区的具体值,而是根据需求描述Terraform在运行时去查找到了合适的值。至此,一个模板把整个ECS的选配(从实例类型、镜像、可用区)等自动化配置了起来,不仅不需要人工的干预,还能进行后续的扩展、升级和维护。

    反馈

    本文讲述了一种自动化选配、构建ECS资源的方法。大家对自动构建工具Terraform感兴趣,或者有问题也可以在github https://github.com/alibaba/terraform-provider 的Issue中提问。

    相关资源:terraform-ecs:AWS ECS terraform模块-源码
    最新回复(0)