通过Terraform创建并使用ECS实例

Terraform是一款IaC工具(Infrastructure as Code),旨在帮助开发人员和运维团队自动化基础设施的创建、部署和管理。您可以通过编写简洁的代码来定义和配置云端基础设施,而不必手动操作和配置。本文为您介绍如何通过Terraform创建ECS实例。

安装Terraform

本文以在Linux或Windows系统中使用程序包安装Terraform为例,更多安装方式,请参见Provider 安装

  1. 进入Terraform官网下载适用于您的操作系统的程序包。

  2. 配置Terraform运行环境。

    Linux

    执行以下命令将程序包解压到/usr/local/bin

    # 将{your_zip_path}替换为程序包所在路径,若系统不支持unzip命令,请先安装。
    sudo unzip {your_zip_path} -d /usr/local/bin

    Windows

    1. 解压程序包,例如解压后的目录为D:\tool\terraform

    2. 在桌面右键单击此电脑,选择属性 > 高级系统设置 > 环境变量 > 系统变量/用户变量

    3. 在系统变量/用户变量中单击Path,选择编辑 > 新建,输入Terraform的解压目录(如D:\tool\terraform),单击确定完成配置。

  3. 运行terraform验证路径配置。

    terraform

    命令运行后将显示可用的Terraform选项的列表,如下所示,表示安装完成。

    image.png

配置Terraform身份认证

Terraform身份认证是指在通过Terraform操作阿里云基础设施之前,对阿里云Terraform Provider进行身份验证。只有在身份认证成功后,才能与阿里云API进行通信,并创建和管理阿里云的基础设施资源。阿里云Terraform Provider提供多种身份认证方式,有关更多身份认证信息,请参见相关文档Terraform 身份认证

本文以在环境变量中使用RAM用户AccessKey配置身份认证为例:

  1. 由于阿里云账号(主账号)拥有资源的所有权限,其AccessKey一旦泄露风险巨大,所以建议您使用RAM用户的AccessKey。如何创建RAM用户的AccessKey,请参见创建AccessKey

  2. 在为RAM用户授予操作云服务器ECS及专有网络VPC相关资源的权限时,建议所授予的权限应遵循最小权限原则。有关如何为RAM用户进行授权的详细信息,请参见为RAM用户授权。本文提供的示例代码需要创建ECS、VPC、交换机等资源,为便于执行本文中的示例,您可以为授予RAM用户以下权限:

    云产品

    授予权限

    专有网络VPC

    本示例选择系统策略:AliyunVPCFullAccess

    云服务器ECS

    本示例选择系统策略:AliyunECSFullAccess

  3. 创建环境变量,存放身份认证信息。

    Linux

    重要

    使用export命令配置的临时环境变量仅对当前会话有效,当会话退出之后所设置的环境变量将会丢失。若需长期保留环境变量,可将export命令配置到对应操作系统的启动配置文件中。

    # AccessKey Id
    export ALICLOUD_ACCESS_KEY="LTAIUrZCw3********"
    # AccessKey Secret
    export ALICLOUD_SECRET_KEY="zfwwWAMWIAiooj14GQ2*************"
    # 资源将要部署的地域
    export ALICLOUD_REGION="cn-beijing"

    Windows

    1. 在桌面右键单击此电脑,选择属性 > 高级系统设置 > 环境变量 > 系统变量/用户变量

    2. 系统变量/用户变量中,单击新建,创建以下环境变量。

      变量名

      变量描述

      变量值

      ALICLOUD_ACCESS_KEY

      AccessKey Id

      示例:LTAIUrZCw3********

      ALICLOUD_SECRET_KEY

      AccessKey Secret

      示例:zfwwWAMWIAiooj14GQ2*************

      ALICLOUD_REGION

      资源将要部署的地域

      示例:cn-beijing

涉及的Terraform资源

本文所提供的示例代码中,所涉及到的Terraform资源信息。

说明

本教程示例包含的部分资源会产生一定费用,请在不需要时及时进行释放或退订。

Resource

Data Source

alicloud_zones:动态查询可以创建特定实例规格的可用区。

编写Terraform配置文件

在main.tf中定义创建ECS所需的基础设施资源,例如ECS、VPC等。您可以直接复制下方完整示例中的代码到配置文件中

  1. 创建配置文件。

    Terraform的基础设施资源是在配置文件中进行定义的,因此必须首先创建一个配置文件。

    Linux

    # 创建工作目录
    mkdir terraform-projects && cd terraform-projects
    mkdir ecs-quickstart && cd ecs-quickstart
    # 创建配置文件并编辑
    touch main.tf && vim main.tf

    Windows

    创建一个新的文件夹,例如命名为ecs-quickstart,并在该文件夹内创建一个Terraform配置文件,例如配置文件名称为main.tf

  2. 定义Provider配置。

    配置阿里云资源部署的地域。

    # 资源所在的地域
    variable "region" {
      default = "cn-chengdu"
    }
    
    provider "alicloud" {
      region = var.region
    }
  3. 定义专有网络VPC及其子网。

    VPC是一种专有的云上私有网络,允许用户在公共云上配置和管理一个逻辑隔离的网络区域。

    variable "instance_name" {
      default = "tf-sample"
    }
    
    # ecs实例规格
    variable "instance_type" {
      default = "ecs.e-c1m2.large"
    }
    
    # 查询满足条件的可用区
    data "alicloud_zones" "default" {
      available_disk_category     = "cloud_essd"
      available_resource_creation = "VSwitch"
      available_instance_type     = var.instance_type
    }
    
    # 创建VPC
    resource "alicloud_vpc" "vpc" {
      vpc_name   = var.instance_name
      cidr_block = "172.16.0.0/12"
    }
    
    # 创建交换机
    resource "alicloud_vswitch" "vsw" {
      vpc_id     = alicloud_vpc.vpc.id
      cidr_block = "172.16.0.0/21"
      zone_id    = data.alicloud_zones.default.zones.0.id
    }
  4. 定义安全组。

    安全组是一种虚拟防火墙,能够控制ECS实例的出入方向流量。

    # 创建安全组
    resource "alicloud_security_group" "default" {
      name   = var.instance_name
      vpc_id = alicloud_vpc.vpc.id
    }
    
    # 为安全组入方向添加规则
    resource "alicloud_security_group_rule" "allow_tcp_22" {
      type              = "ingress"
      ip_protocol       = "tcp"
      nic_type          = "intranet"
      policy            = "accept"
      port_range        = "22/22"
      priority          = 1
      security_group_id = alicloud_security_group.default.id
      cidr_ip           = "0.0.0.0/0"
    }
  5. 定义ECS实例。

    使用ECS,您可以快速部署和运行应用程序,灵活调整资源以应对业务变化,同时享受高性能、高安全性和低成本的计算能力,适用于网站托管、应用开发、数据处理等多种场景。

    # ecs实例镜像ID
    variable "image_id" {
      default = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
    }
    
    # ecs实例公网带宽
    variable "internet_bandwidth" {
      default = "10"
    }
    
    # ecs实例登录密码
    variable "password" {
      default = "Test@12345"
    }
    
    # 指定创建ECS的数量,默认值是 1
    variable "ecs_count" {
      default = 1
    }
    
    # 创建ECS实例
    resource "alicloud_instance" "instance" {
      count                      = var.ecs_count
      availability_zone          = data.alicloud_zones.default.zones.0.id
      security_groups            = alicloud_security_group.default.*.id
      password                   = var.password
      instance_type              = var.instance_type
      system_disk_category       = "cloud_essd"
      image_id                   = var.image_id
      instance_name              = var.instance_name
      vswitch_id                 = alicloud_vswitch.vsw.id
      internet_max_bandwidth_out = var.internet_bandwidth
    }
    
    output "public_ip" {
      value = alicloud_instance.instance.*.public_ip
    }
    

完整示例

variable "region" {
  default = "cn-chengdu"
}

provider "alicloud" {
  region = var.region
}

variable "instance_name" {
  default = "tf-sample"
}

variable "instance_type" {
  default = "ecs.e-c1m2.large"
}

data "alicloud_zones" "default" {
  available_disk_category     = "cloud_essd"
  available_resource_creation = "VSwitch"
  available_instance_type     = var.instance_type
}

resource "alicloud_vpc" "vpc" {
  vpc_name   = var.instance_name
  cidr_block = "172.16.0.0/12"
}

resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "172.16.0.0/21"
  zone_id    = data.alicloud_zones.default.zones.0.id
}

resource "alicloud_security_group" "default" {
  name   = var.instance_name
  vpc_id = alicloud_vpc.vpc.id
}

resource "alicloud_security_group_rule" "allow_tcp_22" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "22/22"
  priority          = 1
  security_group_id = alicloud_security_group.default.id
  cidr_ip           = "0.0.0.0/0"
}

variable "image_id" {
  default = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
}

variable "internet_bandwidth" {
  default = "10"
}

variable "password" {
  default = "Test@12345"
}

variable "ecs_count" {
  default = 1
}

resource "alicloud_instance" "instance" {
  count                      = var.ecs_count
  availability_zone          = data.alicloud_zones.default.zones.0.id
  security_groups            = alicloud_security_group.default.*.id
  password                   = var.password
  instance_type              = var.instance_type
  system_disk_category       = "cloud_essd"
  image_id                   = var.image_id
  instance_name              = var.instance_name
  vswitch_id                 = alicloud_vswitch.vsw.id
  internet_max_bandwidth_out = var.internet_bandwidth
}

output "public_ip" {
  value = [for i in range(var.ecs_count) : alicloud_instance.instance[i].public_ip]
}

运行Terraform命令创建资源

在完成Terraform配置文件编写后,运行Terraform命令来完成ECS实例的自动创建。

1. 初始化Terraform

terraform init命令用于下载并安装阿里云提供商的插件到当前文件夹中,同时还会生成各类记录文件。

Linux

terraform init

Windows

打开命令提示符cmd,在cmd中切换到Terraform配置文件所在文件夹,然后执行terraform init命令进行初始化。

# 例如配置文件路径 D:/ecs-quickstart
# 切换到 D盘
d:
# 切换到配置文件所在文件夹路径的命令,ecs-quickstart是配置文件所在文件夹路径,您可根据实际路径替换。
cd ecs-quickstart
# 执行初始化命令
terraform init
说明

当您因网络延迟等原因导致terraform init超时,无法正常下载Provider等情况时,可通过配置阿里云镜像站解决,具体操作步骤,请参见Terraform Init 加速方案配置

如下所示的信息表示初始化成功。

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should 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, other
commands will detect it and remind you to do so if necessary.

2. 预览Terraform代码

运行terraform plan实现如下功能:

  • 验证main.tf中Terraform代码的语法是否正确。

  • 显示当前Terraform代码将要创建的资源的预览结果。

terraform plan

如果显示如下所示的信息表示Terraform文件无语法错误,可以执行terraform apply命令创建资源。若出现其他报错提示,请根据提示修改Terraform配置文件。

...

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

3. 执行Terraform代码

运行terraform apply以完成ECS实例及其依赖资源的自动创建和Python的自动安装。在创建过程中,需要按照提示输入yes,以允许Terraform创建所有定义的资源。

terraform apply

如下所示的信息表示ECS及所依赖资源均已创建成功。

...

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

alicloud_vpc.vpc: Creating...
alicloud_vpc.vpc: Creation complete after 6s [id=vpc-2vcsghlpznz74XXXXXXXX]
alicloud_security_group.default: Creating...
alicloud_vswitch.vsw: Creating...
alicloud_security_group.default: Creation complete after 1s [id=sg-2vcdz6b8h9c3XXXXXXXX]
alicloud_security_group_rule.allow_tcp_22: Creating...
alicloud_security_group_rule.allow_tcp_22: Creation complete after 0s [id=sg-2vcdz6b8h9c3XXXXXXXX:ingress:tcp:22/22:intranet:0.0.0.0/0:accept:1]
alicloud_vswitch.vsw: Creation complete after 4s [id=vsw-2vc50dknug30bXXXXXXXX]
alicloud_instance.instance: Creating...
alicloud_instance.instance: Still creating... [10s elapsed]
alicloud_instance.instance: Creation complete after 15s [id=i-2vc3rf151bwcXXXXXXXX]

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

Outputs:

public_ip = [
  "4XX.XXX.XXX.XX7",
]

连接ECS实例

当ECS实例成功创建后,您可以通过SSH协议远程登录到指定公网IP的ECS。更多远程连接方式,请参见连接方式概述

ssh <用户名>@<公网IP>

查看结果

使用Terraform命令

您可以通过以下命令查看已创建的ECS实例信息。

# 命令格式:terraform state show <资源类型>.<资源别名>
terraform state show alicloud_instance.instance

登录控制台查看

您可以登录ECS管理控制台查看已创建的ECS实例。image

资源变更

当您需要调整配置时,可以通过直接修改配置文件中的资源定义来实现,例如添加新的安全组入方向的放行规则。

  1. 若您希望在安全组入方向规则中添加443端口的放行规则,您可以在配置文件中添加以下代码。

    resource "alicloud_security_group_rule" "allow_tcp_443" {
      type              = "ingress"
      ip_protocol       = "tcp"
      nic_type          = "intranet"
      policy            = "accept"
      port_range        = "443/443"
      priority          = 1
      security_group_id = alicloud_security_group.default.id
      cidr_ip           = "0.0.0.0/0"
    }
  2. 执行terraform plan命令预览所做的变更。如下所示的信息表示将要为安全组ID是sg-2vcdz6b8h9c3XXXXXXXX的安全组增加一条安全组规则。

    ...
    
    Terraform will perform the following actions:
    
      # alicloud_security_group_rule.allow_tcp_443 will be created
      + resource "alicloud_security_group_rule" "allow_tcp_443" {
          + cidr_ip           = "0.0.0.0/0"
          + id                = (known after apply)
          + ip_protocol       = "tcp"
          + nic_type          = "intranet"
          + policy            = "accept"
          + port_range        = "443/443"
          + prefix_list_id    = (known after apply)
          + priority          = 1
          + security_group_id = "sg-2vcdz6b8h9c3XXXXXXXX"
          + type              = "ingress"
        }
    
    Plan: 1 to add, 0 to change, 0 to destroy.
  3. 如果变更符合预期,执行terraform apply命令将变更应用到您的基础设施。在执行该命令时,Terraform将要求您确认是否进行变更,请键入yes并按回车键确认。如下所示的信息表示已为安全组ID是sg-2vcdz6b8h9c3XXXXXXXX的安全组新增规则成功。

    ...
    
    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
    
    alicloud_security_group_rule.allow_tcp_443: Creating...
    alicloud_security_group_rule.allow_tcp_443: Creation complete after 0s [id=sg-2vcdz6b8h9c3XXXXXXXX:ingress:tcp:443/443:intranet:0.0.0.0/0:accept:1]
    
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

释放资源

当您不再需要上述通过terraform创建或管理的资源时,运行下面的命令释放资源。

terraform 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

alicloud_security_group_rule.allow_tcp_443: Destroying... [id=sg-2vcdz6b8h9c3XXXXXXXX:ingress:tcp:443/443:intranet:0.0.0.0/0:accept:1]
alicloud_security_group_rule.allow_tcp_22: Destroying... [id=sg-2vcdz6b8h9c3XXXXXXXX:ingress:tcp:22/22:intranet:0.0.0.0/0:accept:1]
alicloud_instance.instance: Destroying... [id=i-2vc3rf151bwcXXXXXXXX]
alicloud_security_group_rule.allow_tcp_22: Destruction complete after 0s
alicloud_security_group_rule.allow_tcp_443: Destruction complete after 0s
alicloud_instance.instance: Still destroying... [id=i-2vc3rf151bwcXXXXXXXX, 10s elapsed]
alicloud_instance.instance: Destruction complete after 10s
alicloud_security_group.default: Destroying... [id=sg-2vcdz6b8h9c3XXXXXXXX]
alicloud_vswitch.vsw: Destroying... [id=vsw-2vc50dknug30bXXXXXXXX]
alicloud_security_group.default: Destruction complete after 1s
alicloud_vswitch.vsw: Destruction complete after 8s
alicloud_vpc.vpc: Destroying... [id=vpc-2vcsghlpznz74XXXXXXXX]
alicloud_vpc.vpc: Destruction complete after 6s

Destroy complete! Resources: 6 destroyed.

相关文档