momo's Blog.

TerraForm实践

字数统计: 1k阅读时长: 4 min
2021/12/31 Share

阿里云

尝试在阿里云启动一个ECS

这里先理清一下创建一个阿里云的ECS需要哪些步骤

  1. 通过机型,过滤出有该机型的区域(zone)
  2. 拿到zone,创建vpc相关资源,如 switch,NAT
  3. 创建安全组,并且配置对应规则
  4. 创建ECS

配置 provider

  • main.tf
    在入口处,我们配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    terraform {
    required_providers {
    alicloud = {
    source = "aliyun/alicloud"
    version = ">= 1.149.0"
    }
    }
    }

    provider "alicloud" {
    region = "${var.region}"
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    }
  • variables.tf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    variable "region" {
    type = string
    default = "cn-hangzhou"
    description = "aliyun cloud region"
    }

    variable "access_key" {
    type = string
    default = ""
    description = "Your aliyun access_key"
    }

    variable "secret_key" {
    type = string
    default = ""
    description = "Your aliyun secret_key"
    }

创建VPC

创建VPC我们有几种方式,一种是将一个区域内,所有可用区都提前划分出对应的交换机。
另一种,则写死一个或者两个交换机。

我们这里采用提前划分所有的交换机。

  • VPC的cidr地址为: 10.0.0.0/8
  • 下方的交换机为: 10.1-253.0.0/16
  • vpc.tf
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    variable "vpc_cidr" {
    type = string
    default = "10.0.0.0/8"
    description = "description"
    }


    locals {
    switch_cidr = "${[for i in range(1, length(data.alicloud_zones.default.ids) + 1, 1): format("10.%d.0.0/16", i)]}"
    }



    resource "alicloud_vpc" "vpc" {
    vpc_name = "FP-VPC-createByTerraform"
    cidr_block = "${var.vpc_cidr}"
    }

    // 如果只需要创建第一个switch,则修改下方的count
    resource "alicloud_vswitch" "vswitch" {
    count = length(data.alicloud_zones.default.ids)
    vpc_id = alicloud_vpc.vpc.id
    cidr_block = "${element(local.switch_cidr, count.index)}"
    zone_id = "${element(data.alicloud_zones.default.ids, count.index)}"
    vswitch_name = "FP-${element(data.alicloud_zones.default.ids, count.index)}"
    }

上方为完整写法, 执行 terraform plan/apply 部署, 将创建一个地域下所有可用区的交换机,每个可用区有 65532 可用主机位。

但是考虑下来,会不会写死可用区比较好,毕竟其他资源你不可能在所有的可用区全部创建,并且后续人员维护起来,对于全是变量的配置也非常麻烦?

将部署可用区指定的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
variable "vpc_cidr" {
type = string
default = "10.0.0.0/8"
description = "description"
}

resource "alicloud_vpc" "vpc" {
vpc_name = "FP-VPC-createByTerraform"
cidr_block = var.vpc_cidr
}

// 杭州可用区I 交换机 网段 10.1.0.0/16
resource "alicloud_vswitch" "vswitch-cn-hangzhou-i" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "10.1.0.0/16"
zone_id = var.zone
vswitch_name = "FP-${var.zone}"
}

创建NAT

DNAT 可有可无, 一般来说仅仅只有22端口的需求,我们完全可以找一台1c1g的机器当作ssh的proxy 使用 ssh proxy command

我们主要是使用是SNAT,来提供上网功能。

PS:
在DNAT规则中, 如果指定的端口号大于1000的时候,如果不指定port_break则会报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// NAT
resource "alicloud_nat_gateway" "nat-cn-hangzhou-i" {
depends_on = [alicloud_vswitch.vswitch-cn-hangzhou-i]
vpc_id = alicloud_vpc.vpc.id
nat_gateway_name = "FP-NAT-${var.zone}"
payment_type = "PayAsYouGo"
vswitch_id = alicloud_vswitch.vswitch-cn-hangzhou-i.id
nat_type = "Enhanced"
network_type = "internet"
}

// 为 NAT 绑定 EIP
resource "alicloud_eip_address" "nat-eip" {
address_name = "FP-NAT-EIP-${var.zone}"
internet_charge_type = "PayByTraffic"
bandwidth = "5"
}

resource "alicloud_eip_association" "default" {
allocation_id = alicloud_eip_address.nat-eip.id
instance_id = alicloud_nat_gateway.nat-cn-hangzhou-i.id
}

// 这里设置了SNAT, 提供上网的能力
resource "alicloud_snat_entry" "snat-cn-hangzhou-i" {
depends_on = [alicloud_eip_association.default]
snat_table_id = alicloud_nat_gateway.nat-cn-hangzhou-i.snat_table_ids
source_vswitch_id = alicloud_vswitch.vswitch-cn-hangzhou-i.id
snat_ip = join(",", alicloud_eip_address.nat-eip.*.ip_address)
}

// 这里设置DNAT
resource "alicloud_forward_entry" "default" {
count = length(alicloud_instance.instance)
depends_on = [alicloud_instance.instance]
forward_table_id = alicloud_nat_gateway.nat-cn-hangzhou-i.forward_table_ids
external_ip = alicloud_eip_address.nat-eip.ip_address
external_port = "${6000 + count.index}"
ip_protocol = "tcp"
internal_ip = "${alicloud_instance.instance[count.index].private_ip}"
internal_port = "22"
port_break = true
}

创建安全组

注意安全组规则的nic_type 是内网, 不过规则依旧可以影响到公网访问.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
resource "alicloud_security_group" "default-group" {
name = "default-group"
vpc_id = alicloud_vpc.vpc.id
}


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

创建ECS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
resource "alicloud_instance" "instance" {
count = 2
depends_on = [
alicloud_security_group.default-group,
alicloud_vswitch.vswitch-cn-hangzhou-i
]
# cn-beijing
availability_zone = var.zone
security_groups = alicloud_security_group.default-group[*].id

# series III
instance_type = var.instance_type
system_disk_category = "cloud_essd"
system_disk_name = "test"
system_disk_description = "test_foo_system_disk_description"
image_id = data.alicloud_images.images_ds.ids[0]
instance_name = "test_foo-${count.index + 1}"
vswitch_id = alicloud_vswitch.vswitch-cn-hangzhou-i.id
instance_charge_type = "PostPaid"
password = "i4362jDNb6lAOFNy"
data_disks {
name = "disk2"
size = 20
category = "cloud_essd"
description = "disk2"
}
}

DATA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
data "alicloud_zones" "default" {
available_resource_creation = "VSwitch"
}

// 过滤出image id
data "alicloud_images" "images_ds" {
owners = "system"
name_regex = var.image_id
}

// 该机型为4c8g的c7计算型
data "alicloud_zones" "zone_by_4c8g" {
available_instance_type = "ecs.c7.xlarge"
available_disk_category = "cloud_essd"
}
CATALOG
  1. 1. 阿里云
  2. 2. 尝试在阿里云启动一个ECS
    1. 2.1. 配置 provider
    2. 2.2. 创建VPC
      1. 2.2.1. 将部署可用区指定的方式
    3. 2.3. 创建NAT
    4. 2.4. 创建安全组
    5. 2.5. 创建ECS
    6. 2.6. DATA