用 Terraform 在华为云上一键创建 VPC + ECS + EIP:从零到一的 IaC 实战

举报
yd_214570068 发表于 2026/10/19 10:11:41 2026/10/19
【摘要】 用 Terraform 在华为云上一键创建 VPC + ECS + EIP:从零到一的 IaC 实战还在控制台点点点建资源?每次环境重建都要手动操作一遍?本文带你用 Terraform 把华为云上最常见的 VPC + ECS + EIP 组合变成一份代码,terraform apply 一条命令搞定,删环境也只需 terraform destroy。 为什么用 Terraform如果你有过...

用 Terraform 在华为云上一键创建 VPC + ECS + EIP:从零到一的 IaC 实战

还在控制台点点点建资源?每次环境重建都要手动操作一遍?本文带你用 Terraform 把华为云上最常见的 VPC + ECS + EIP 组合变成一份代码,terraform apply 一条命令搞定,删环境也只需 terraform destroy。

为什么用 Terraform

如果你有过这样的经历——

  • 测试环境用完想删,结果漏删了一个 EIP,月底账单多出几十块
  • 同一套环境要搭三遍(开发、测试、预发),每次都在控制台重复操作
  • 同事问你"这台 ECS 的安全组规则加了哪些端口",你翻了半天控制台才找到

——那 Terraform 就是为你准备的。

Terraform 是 HashiCorp 出的基础设施即代码(IaC)工具。你用一种声明式语言描述"我想要什么样的云资源",Terraform 负责调用云平台的 API 把它们创建出来,并且记住这些资源的状态(叫 state)。下次改了代码再 apply,它只变更差异部分;想销毁,一条 destroy 全部干净回收。

本文以华为云为例,从零搭建一个最小可用的网络 + 服务器 + 公网 IP。

前置准备

1. 安装 Terraform

华为云提供了官方镜像源,国内下载不走国外网络:

# 下载并安装(以 Linux 为例)
curl -o terraform.zip https://mirrors.huaweicloud.com/terraform/1.8.5/terraform_1.8.5_linux_arm64.zip
unzip terraform.zip
mv terraform /usr/local/bin/
terraform version

Windows / Mac 用户把 linux_arm64 换成 windows_amd64 / darwin_arm64 即可。

2. 获取 AK / SK

登录华为云控制台 → 右上角头像 → “我的凭证” → “访问密钥” → 新建密钥。你会得到一个 AK(Access Key ID)和一个 SK(Secret Access Key),SK 只在创建时显示一次,务必保存好。

⚠️ 安全提醒:AK/SK 是你账号的长期凭证,泄露等于账号沦陷。不要写死在代码里提交到 Git,推荐用环境变量传入。

3. 确认区域和可用区

本文以 cn-north-4(华北-北京四)为例,可用区用 cn-north-4a。你可以根据自己资源所在区域调整。

开始写代码

建一个项目目录:

mkdir huaweicloud-ecs-demo && cd huaweicloud-ecs-demo

文件一:provider.tf —— 告诉 Terraform 用哪个云

terraform {
  required_providers {
    huaweicloud = {
      source  = "huaweicloud/huaweicloud"
      version = ">= 1.60.0"
    }
  }
}

provider "huaweicloud" {
  region     = "cn-north-4"
  # AK/SK 通过环境变量传入,不写死在代码里
  # export HW_ACCESS_KEY="你的AK"
  # export HW_SECRET_KEY="你的SK"
}

这段在做什么:

  • required_providers 声明我们要用华为云的 Terraform Provider(插件),它会去 HashiCorp 的 registry 下载。华为云也提供了 registry 镜像,可以在 terraform 块里加 provider_mirror 配置加速。
  • provider "huaweicloud" 配置认证信息。region 直接写死,AK/SK 通过环境变量 HW_ACCESS_KEY / HW_SECRET_KEY 传入——这是推荐做法,避免凭证泄露到代码仓库。

文件二:variables.tf —— 把可变参数抽出来

variable "ecs_name" {
  description = "ECS 实例名称"
  type        = string
  default     = "demo-ecs"
}

variable "ecs_password" {
  description = "ECS root 用户密码"
  type        = string
  sensitive   = true
  # 密码要求:8-26 位,至少包含大写、小写、数字、特殊字符各一种
}

variable "flavor_id" {
  description = "ECS 规格ID"
  type        = string
  default     = "s6.large.2"  # 2核4G
}

variable "image_id" {
  description = "镜像ID,这里用 Huawei Cloud EulerOS 2.12 公共镜像"
  type        = string
  default     = "your-image-id-here"  # 替换成你区域的实际镜像ID
}

为什么要抽变量: 同一套代码,改个变量值就能给不同环境用——开发环境用小规格 s6.large.2,生产环境换成 s6.xlarge.4,不用动主体代码。sensitive = true 让密码在 terraform plan 输出中显示为 (sensitive value),不会明文打印。

💡 怎么查镜像 ID:控制台 → ECS → 镜像 → 找到你要的公共镜像,复制 ID。或者用 hcloud CLI:hcloud IMS ShowImages --images.image_type=public。

文件三:network.tf —— 网络基础设施

# VPC
resource "huaweicloud_vpc" "demo" {
  name = "demo-vpc"
  cidr = "192.168.0.0/16"
}

# 子网
resource "huaweicloud_vpc_subnet" "demo" {
  name       = "demo-subnet"
  vpc_id     = huaweicloud_vpc.demo.id
  cidr       = "192.168.0.0/24"
  gateway_ip = "192.168.0.1"
  # 指定可用区
  availability_zone = "cn-north-4a"
}

# 安全组
resource "huaweicloud_networking_secgroup" "demo" {
  name        = "demo-secgroup"
  description = "安全组:仅放行 SSH(22)端口"
}

# 安全组规则:放行 SSH
resource "huaweicloud_networking_secgroup_rule" "ssh" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 22
  port_range_max    = 22
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = huaweicloud_networking_secgroup.demo.id
}

# 安全组规则:放行 HTTP(如果你要跑 Web 服务,按需开放)
resource "huaweicloud_networking_secgroup_rule" "http" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 80
  port_range_max    = 80
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = huaweicloud_networking_secgroup.demo.id
}

逐块解释:

资源 云上对应 关键参数说明
huaweicloud_vpc 虚拟私有云 cidr 是整个 VPC 的网段,用 /16 给子网留足空间
huaweicloud_vpc_subnet 子网 必须在 VPC 的 CIDR 内,gateway_ip 通常是网段第一个地址
huaweicloud_networking_secgroup 安全组 相当于云级别的防火墙,默认全部拒绝,需要逐条放行
..._secgroup_rule 安全组规则 ingress = 入方向,remote_ip_prefix 控制来源 IP

⚠️ 安全提醒:这里 SSH 放行了 0.0.0.0/0(全网可访问),仅适合测试环境。生产环境建议改为你的办公出口 IP,比如 203.0.113.10/32。或者更好的做法:用华为云的 NAT 网关 + 跳板机,不直接对公网开放 22 端口。

文件四:compute.tf —— ECS 和 EIP

# 弹性公网 IP
resource "huaweicloud_vpc_eip" "demo" {
  publicip {
    type = "5_bgp"  # BGP 类型弹性公网IP
  }
  bandwidth {
    name        = "demo-bandwidth"
    size        = 5  # 5 Mbit/s
    share_type  = "PER"
    charge_mode = "traffic"  # 按流量计费
  }
}

# ECS 实例
resource "huaweicloud_compute_instance" "demo" {
  name              = var.ecs_name
  flavor_id         = var.flavor_id
  image_id          = var.image_id
  availability_zone = "cn-north-4a"
  admin_pass        = var.ecs_password

  # 绑定网络
  network {
    uuid = huaweicloud_vpc_subnet.demo.id
  }

  # 绑定安全组
  security_group_ids = [
    huaweicloud_networking_secgroup.demo.id
  ]

  # 绑定 EIP
  eip_id = huaweicloud_vpc_eip.demo.id

  # 系统盘
  system_disk_type = "SAS"   # 高 IO 类型
  system_disk_size = 40      # 40 GB

  tags = {
    Environment = "demo"
    ManagedBy   = "terraform"
  }
}

几个值得注意的点:

  1. eip_id:ECS 创建时直接绑定 EIP,不用事后手动关联。注意 EIP 资源要先于 ECS 创建——Terraform 会根据引用关系自动推断依赖顺序,你不需要手动写 depends_on。
  2. system_disk_type:华为云磁盘类型有 SAS(高 IO)、SSD(超高 IO)、GPSSD(通用型 SSD)、ESSD(极速型 SSD)。测试环境 SAS 够用,生产数据库建议 SSD 或 ESSD。
  3. tags:给资源打标签是好习惯,后续用标签筛选资源、分摊成本都靠它。ManagedBy = terraform 标记这是 IaC 管理的,提醒同事别手动改。

文件五:outputs.tf —— 输出关键信息

output "ecs_public_ip" {
  description = "ECS 公网 IP"
  value       = huaweicloud_vpc_eip.demo.address
}

output "ecs_private_ip" {
  description = "ECS 私网 IP"
  value       = huaweicloud_compute_instance.demo.network[0].fixed_ip_v4
}

output "vpc_id" {
  description = "VPC ID"
  value       = huaweicloud_vpc.demo.id
}

apply 完成后这些值会直接打印在终端,不用再去控制台翻。

跑起来

第一步:设置环境变量

export HW_ACCESS_KEY="你的AK"
export HW_SECRET_KEY="你的SK"
export TF_VAR_ecs_password="你的密码"  # 满足复杂度要求

第二步:初始化

terraform init

这一步会下载华为云 Provider 插件。如果国内网络慢,配置 provider 镜像:

# 在 ~/.terraformrc 或 terraform 配置中
provider_installation {
  dev_overrides {}
  direct {
    exclude = ["huaweicloud/huaweicloud"]
  }
  filesystem_mirror {
    path    = "/usr/local/share/terraform/providers"
    include = ["huaweicloud/huaweicloud"]
  }
}

第三步:预览执行计划

terraform plan

Terraform 会告诉你它将要创建哪些资源,但不会真的创建。仔细看一遍输出,确认无误:

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

  # huaweicloud_vpc.demo will be created
  # huaweicloud_vpc_subnet.demo will be created
  # huaweicloud_networking_secgroup.demo will be created
  # huaweicloud_networking_secgroup_rule.ssh will be created
  # huaweicloud_networking_secgroup_rule.http will be created
  # huaweicloud_vpc_eip.demo will be created
  # huaweicloud_compute_instance.demo will be created

7 个资源,符合预期:1 VPC + 1 子网 + 1 安全组 + 2 安全组规则 + 1 EIP + 1 ECS。

第四步:正式创建

terraform apply

输入 yes 确认。大约 1-2 分钟后,你会看到 outputs 打印出公网 IP:

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

Outputs:

ecs_public_ip  = "121.xxx.xxx.xxx"
ecs_private_ip = "192.168.0.123"
vpc_id         = "vpc-xxxxx"

用 SSH 连上去验证:

ssh root@121.xxx.xxx.xxx

第五步(用完后):销毁

terraform destroy

输入 yes,7 个资源全部干净删除,不会漏删 EIP 产生持续计费。这就是 IaC 最大的好处之一:环境即代码,创建和销毁完全对称。

进阶:把状态存到 OBS

默认 state 文件存在本地 terraform.tfstate,团队协作时不方便。华为云 OBS 可以作为 Terraform 的远程 backend:

terraform {
  backend "s3" {
    endpoint   = "obs.cn-north-4.myhuaweicloud.com"
    bucket     = "my-terraform-state"
    key        = "ecs-demo/terraform.tfstate"
    region     = "cn-north-4"
    # OBS 兼容 S3 协议,Terraform 的 s3 backend 可以直接用
  }
  # ... required_providers 不变
}

这样团队成员共享同一份 state,谁改了资源,其他人 terraform plan 能立刻看到差异。

常见踩坑记录

1. image_id 找不到

镜像 ID 是区域相关的,cn-north-4 的镜像在 cn-east-3 用不了。确认你用的镜像在你配置的 region 下可用。

2. 密码不符合要求

华为云 ECS 密码规则:8-26 位,至少包含大写字母、小写字母、数字、特殊字符(!@$%^-_=+[{}]:,./?)各一种。不符合会报 Invalid password。

3. 可用区没有该规格

不是所有可用区都有所有规格。用 hcloud ECS ListFlavors --availability_zone=cn-north-4a 确认你要的 flavor 在目标可用区有库存。

4. 改了安全组规则没生效

Terraform 管理的安全组规则,如果你在控制台手动加了一条规则,再 terraform apply 时 Terraform 不会动那条手动加的(它只管自己 state 里记录的)。但如果你手动改了 Terraform 管理的规则,terraform plan 会显示 drift,apply 会覆盖回代码定义的状态。建议:一旦用 Terraform 管理资源,就不要再手动在控制台改同一资源。

小结

传统方式 Terraform 方式
控制台逐个创建,容易漏配 一份代码描述全部,plan 预览差异
删除靠记忆,漏删就持续计费 destroy 一键干净回收
环境复制靠重复操作 改变量值,同一套代码复用
变更没有审计记录 代码版本管理 = 基础设施变更审计

本文的完整代码已经能跑通一个最小可用的华为云 ECS 环境。下一步你可以尝试:

  • 加一个 RDS 数据库,用 huaweicloud_rds_instance 资源
  • 加一个 ELB 负载均衡,把流量分发到多台 ECS
  • 用 Terraform Module 把这套封装成可复用模块

IaC 的核心理念就一句话:基础设施是代码,代码可以版本化、可以复用、可以审计。 从今天开始,把你的云资源交给 Terraform 管理吧。


【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。