把服务器当宠物养、靠手动在控制台点选来部署,是很多团队早期的通病:环境不一致、变更不可追溯、一次手滑就回不到昨天。本文用 Terraform 管理阿里云 ECS,把 VPC、安全组、实例这些资源写成可版本化、可复用的代码——也就是基础设施即代码(IaC),让环境一致、变更可回滚、扩容只需改一个数字。
一、为什么要用 Terraform 管阿里云
手动在控制台创建一台 ECS,要填十几个选项;等你要再建一套测试环境,又得重复一遍,还容易和线上对不上。Terraform 用声明式 HCL 描述“最终想要什么状态”,由它负责计算差异并执行变更。它的核心优势有三点:
- 声明式:你写的是目标状态,而不是一步一步的操作脚本;
- 状态管理:Terraform 记录资源当前状态,下次只改“变化的部分”;
- 可回滚与可审查:配置进 Git,谁改了什么一目了然,出问题 git revert 即可。
对于已经跑在阿里云 ECS 上的业务,把基础设施代码化,是迈向自动化运维的第一步。
二、环境准备与 Provider 配置
先在本地装好 Terraform(macOS 可用 brew install terraform,其他平台下载官方二进制并加入 PATH)。然后新建 versions.tf 声明阿里云 Provider:
terraform {
required_version = ">= 1.5.0"
required_providers {
alicloud = {
source = "aliyun/alicloud"
version = ">= 1.220.0"
}
}
}
provider "alicloud" {
region = "cn-hangzhou"
}
鉴权不要写死在代码里。把 AccessKey 放进环境变量,Terraform 会自动读取,避免在仓库里泄露密钥:
export ALICLOUD_ACCESS_KEY="你的AccessKeyId"
export ALICLOUD_SECRET_KEY="你的AccessKeySecret"
export ALICLOUD_REGION="cn-hangzhou"
三、用代码创建 VPC 与安全组
代码化的第一步是网络。下面一次性把 VPC、交换机(VSwitch)和 Web 安全组(放行 22/80 端口)都声明出来:
resource "alicloud_vpc" "main" {
vpc_name = "tf-demo-vpc"
cidr_block = "10.0.0.0/16"
}
resource "alicloud_vswitch" "main" {
vswitch_name = "tf-demo-vsw"
vpc_id = alicloud_vpc.main.id
cidr_block = "10.0.1.0/24"
zone_id = "cn-hangzhou-h"
}
resource "alicloud_security_group" "web" {
security_group_name = "tf-web-sg"
vpc_id = alicloud_vpc.main.id
}
resource "alicloud_security_group_rule" "ssh" {
type = "ingress"
ip_protocol = "tcp"
port_range = "22/22"
security_group_id = alicloud_security_group.web.id
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_security_group_rule" "http" {
type = "ingress"
ip_protocol = "tcp"
port_range = "80/80"
security_group_id = alicloud_security_group.web.id
cidr_ip = "0.0.0.0/0"
}
各资源的职责如下:
| 资源 | 作用 |
|---|---|
| alicloud_vpc | 私有网络边界,隔离你的云上资源 |
| alicloud_vswitch | 子网,决定实例落在哪个可用区 |
| alicloud_security_group | 虚拟防火墙,控制入站/出站流量 |
| alicloud_security_group_rule | 具体放行规则(端口、协议、来源) |
四、定义 ECS 实例并初始化运行环境
有了网络,就可以声明 ECS 实例。下面这台机器在创建时通过 user_data 自动装上 Docker 和 Nginx,开机即可用:
resource "alicloud_instance" "web" {
instance_name = "tf-web-ecs"
instance_type = "ecs.g7.large"
image_id = "ubuntu_22_04_x64"
security_groups = [alicloud_security_group.web.id]
vswitch_id = alicloud_vswitch.main.id
system_disk_category = "cloud_essd"
system_disk_size = 40
internet_max_bandwidth_out = 10
user_data = <<-EOT
#!/bin/bash
apt-get update
apt-get install -y docker.io nginx
systemctl enable docker nginx
EOT
}
实例起来后,你可以用 Docker 容器编排实战 里的方法把业务打包成镜像,再用 Nginx 反向代理 把 80 端口流量转发到容器,一套标准化的 Web 运行环境就成型了。
五、变量化与多环境
把硬编码抽成变量,才能在测试、预发、生产之间复用同一套代码。新建 variables.tf:
variable "env" {
description = "环境标识"
default = "prod"
}
variable "instance_type" {
default = "ecs.g7.large"
}
resource "alicloud_vpc" "main" {
vpc_name = "tf-${var.env}-vpc"
cidr_block = "10.0.0.0/16"
}
再用 terraform apply -var-file=prod.tfvars 切换不同环境的参数,就能用一份代码管理多套基础设施,告别“复制粘贴改 IP”的野路子。
六、把 Terraform 纳入 CI/CD
配置进 Git 后,下一步是把变更接入流水线。借助 GitHub Actions 实战:从零搭建 CI/CD,可以在提交时自动做 terraform plan、合并后自动 apply,让基础设施变更也走代码评审:
name: terraform
on: [push, pull_request]
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- run: terraform init
- run: terraform plan
env:
ALICLOUD_ACCESS_KEY: ${{ secrets.ALICLOUD_ACCESS_KEY }}
ALICLOUD_SECRET_KEY: ${{ secrets.ALICLOUD_SECRET_KEY }}
七、常见坑与最佳实践
- State 别放本地:多人协作要用阿里云 OSS 做远程后端,避免 state 文件丢失和并发冲突;
- 密钥别进仓库:敏感变量用
*.tfvars并加入.gitignore,或接入阿里云 KMS / 密钥管理; - 警惕资源漂移:有人在控制台手动改了配置,要用
terraform plan比对,必要时terraform import收回管理; - 先 plan 再 apply:每次变更先看 plan 输出,确认只动了你想要的资源;
- 开启状态锁:远程后端自带锁,防止两个人同时 apply 互相覆盖。
八、小结
用 Terraform 管理阿里云 ECS,本质是把“运维经验”沉淀成可执行的代码。从 Provider 配置、VPC/安全组,到 ECS 实例与 user_data 初始化,再到变量化多环境与 CI/CD 接入,你已经拥有了一条可复用、可追溯的基础设施流水线。下一步,可以把数据库、负载均衡、CDN 也逐步纳入这套代码,让整个云上架构都变得“可版本化”。




