从手动到自动:用 Terraform 一键部署华为云 VPC + ECS 实战

举报
yd_253349614 发表于 2026/10/31 11:15:40 2026/10/31
【摘要】 # 从手动到自动:用 Terraform 一键部署华为云 VPC + ECS 实战## 前言如果你还在控制台里点点点,手动创建 VPC、子网、安全组、ECS……那你一定经历过这种痛:环境一多就分不清谁是谁,出了问题找不到当初怎么配的,换个账号又得重来一遍。本文分享我用 Terraform 在华为云上从零搭建一套基础网络 + 云服务器环境的实战过程。不讲大道理,只讲实操中真正会遇到的问题和解决...

# 从手动到自动:用 Terraform 一键部署华为云 VPC + ECS 实战

## 前言

如果你还在控制台里点点点,手动创建 VPC、子网、安全组、ECS……那你一定经历过这种痛:环境一多就分不清谁是谁,出了问题找不到当初怎么配的,换个账号又得重来一遍。

本文分享我用 Terraform 在华为云上从零搭建一套基础网络 + 云服务器环境的实战过程。不讲大道理,只讲实操中真正会遇到的问题和解决方式。

## 为什么选 Terraform?

一句话:**基础设施即代码(IaC),让环境变成可版本化、可复现的资产。**

- 声明式写法:你描述"我要什么",Terraform 负责怎么达到
- 状态管理:`terraform.tfstate` 记录当前基础设施的真实状态
- 可复用:同一份代码,改几个变量就能部署到不同区域、不同账号
- 团队协作:代码进 Git,每次变更都有 commit 记录

## 准备工作

### 1. 安装 Terraform

前往 Terraform 官方发布页下载对应平台的安装包(建议 1.7.x 版本),解压后将二进制文件移动到系统 PATH 路径下:

```bash
# Linux/Mac 示例
unzip terraform_1.7.5_linux_amd64.zip
sudo mv terraform /usr/local/bin/

terraform version  # 验证安装
```

### 2. 配置华为云认证

推荐用环境变量,避免 AK/SK 硬编码进代码:

```bash
export HW_ACCESS_KEY="你的AK"
export HW_SECRET_KEY="你的SK"
export HW_REGION_NAME="cn-north-4"   # 华北-北京四
export HW_PROJECT_ID="你的项目ID"
```

> **安全提醒**:千万别把 AK/SK 提交到 Git 仓库里。.gitignore 中务必加上 `*.tfvars` 和 `terraform.tfstate`。

## 实战:一份代码搭起整套环境

### 目录结构

```
huaweicloud-infra/
├── main.tf          # 主配置:provider + 资源定义
├── variables.tf     # 变量声明
├── outputs.tf       # 输出有用的信息
└── terraform.tfvars # 变量赋值(不提交到 Git)
```

### main.tf —— 核心配置

```hcl
terraform {
  required_providers {
    huaweicloud = {
      source  = "huaweicloud/huaweicloud"
      version = ">= 1.50.0"
    }
  }
}

provider "huaweicloud" {
  region = var.region
}

# ========== 网络:VPC ==========
resource "huaweicloud_vpc" "main" {
  name = var.vpc_name
  cidr = "192.168.0.0/16"
}

# 子网
resource "huaweicloud_vpc_subnet" "web" {
  name       = "${var.vpc_name}-subnet-web"
  vpc_id     = huaweicloud_vpc.main.id
  cidr       = "192.168.0.0/24"
  gateway_ip = "192.168.0.1"
}

# ========== 安全组 ==========
resource "huaweicloud_networking_secgroup" "web" {
  name        = "${var.vpc_name}-sg-web"
  description = "Web 服务器安全组"
}

# 放行 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.web.id
}

# 放行 HTTP
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.web.id
}

# ========== 云服务器 ECS ==========
resource "huaweicloud_compute_instance" "web" {
  name              = "web-server-01"
  image_id          = var.image_id
  flavor_id         = "s6.large.2"
  availability_zone = var.az

  network {
    uuid = huaweicloud_vpc_subnet.web.id
  }

  security_group_ids = [huaweicloud_networking_secgroup.web.id]

  tags = {
    Environment = "dev"
    Team        = "platform"
  }
}

# ========== 弹性公网 IP ==========
resource "huaweicloud_vpc_eip" "web" {
  publicip {
    type = "5_bgp"
  }
  bandwidth {
    name        = "web-bandwidth"
    size        = 5
    share_type  = "PER"
    charge_mode = "traffic"
  }
}

# 将 EIP 绑定到 ECS
resource "huaweicloud_compute_eip_associate" "web" {
  public_ip   = huaweicloud_vpc_eip.web.address
  instance_id = huaweicloud_compute_instance.web.id
}
```

### variables.tf —— 参数化

```hcl
variable "region" {
  type    = string
  default = "cn-north-4"
}

variable "az" {
  type    = string
  default = "cn-north-4a"
}

variable "vpc_name" {
  type    = string
  default = "tf-demo-vpc"
}

variable "image_id" {
  type        = string
  description = "ECS 镜像 ID,可通过控制台或 API 查询"
}
```

### outputs.tf —— 部署后输出关键信息

```hcl
output "ecs_public_ip" {
  value = huaweicloud_vpc_eip.web.address
}

output "vpc_id" {
  value = huaweicloud_vpc.main.id
}

output "subnet_id" {
  value = huaweicloud_vpc_subnet.web.id
}
```

## 执行:四步搞定

```bash
# 第 1 步:初始化,下载 provider 插件
terraform init

# 第 2 步:检查格式和语法
terraform fmt
terraform validate

# 第 3 步:预览变更计划(重要!先看再执行)
terraform plan

# 第 4 步:正式部署(会要求输入 yes 确认)
terraform apply
```

执行 `terraform plan` 时你会看到类似这样的输出:

```
Plan: 8 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the following actions:
    # huaweicloud_vpc.main will be created
    # huaweicloud_vpc_subnet.web will be created
    # huaweicloud_networking_secgroup.web will be created
    ...
```

**8 个资源,一条命令,几秒钟完成创建。** 这就是 IaC 的魅力。

## 实操中的三个踩坑点

### 坑一:state 文件冲突

多人协作时,如果大家都用本地 state,很容易互相覆盖。

**解法**:用 OBS 远程后端:

```hcl
terraform {
  backend "local" {}  # 改成远程后端
}
```

华为云目前可用 `http` 后端对接 OBS,或者用 S3 兼容接口。小团队本地 state 也够用,但记得加 `.gitignore`。

### 坑二:安全组规则重复创建

直接删除安全组资源时,关联的规则不会自动清理,再次 apply 会报规则已存在。

**解法**:安全组和规则分开定义为独立的 resource(就像上面代码那样),destroy 时会按依赖顺序自动清理。

### 坑三:ECS 创建失败 —— 镜像 ID 无效

不同区域的镜像 ID 不同,从 cn-north-4 拿的镜像 ID 拿到 cn-east-3 就用不了。

**解法**:用 `data` 数据源动态查询,而不是硬编码:

```hcl
data "huaweicloud_images_image" "ubuntu" {
  name        = "Ubuntu 22.04 server 64bit"
  most_recent = true
}

resource "huaweicloud_compute_instance" "web" {
  image_id = data.huaweicloud_images_image.ubuntu.id
  # ...
}
```

## 销毁环境

测试完了,一条命令全部清理,不留垃圾:

```bash
terraform destroy
```

```
Plan: 0 to add, 0 to change, 8 to destroy.
```

**这比手动到控制台一个一个删快太多了,而且不会漏删导致持续计费。**

## 总结

| 对比项 | 手动控制台 | Terraform |
|--------|-----------|-----------|
| 部署速度 | 10-30 分钟 | 1-2 分钟 |
| 可复现性 | 靠记忆和文档 | 代码即文档 |
| 销毁清理 | 容易漏删 | 一条命令 |
| 变更追溯 | 无 | Git commit |
| 多环境部署 | 重复劳动 | 改变量即可 |

从手动到自动,不是一步到位的事。建议从一个小资源开始(比如先只管一个 ECS),熟悉了再逐步把 VPC、安全组、EIP 都纳入管理。

**基础设施不该是手动操作的产物,它应该是代码的产物。**

---

> 以上内容为原创实战经验分享,基于个人在华为云上的真实使用过程整理。如有问题欢迎评论区交流。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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