深色模式
Terraform 入门:用 HCL 建一台云主机
摘要:Terraform 用「描述终态」代替一步步敲命令。本文完成安装、写 provider、用 data source 自动选镜像、创建一台云主机并输出公网 IP,最后 destroy 干净回收。
适用环境
- 本地 Linux / macOS / WSL
- 一个云厂商账号与 Access Key(示例用 AWS,其它厂商结构一致)
- 能访问外网下载 provider
操作步骤
1. 安装 CLI
bash
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install -y terraform
terraform version1
2
3
4
2
3
4
2. 准备凭证
bash
export AWS_ACCESS_KEY_ID="你的AK"
export AWS_SECRET_ACCESS_KEY="你的SK"
export AWS_REGION="ap-northeast-1"1
2
3
2
3
危险
不要把 AK/SK 写进 .tf 文件并提交 Git。本地用环境变量,CI 中用平台 Secret 注入。
3. 写 main.tf
bash
mkdir -p ~/tf-demo && cd ~/tf-demo
cat > main.tf <<'EOF'
terraform { required_version = ">= 1.5.0" }
provider "aws" { region = var.region }
variable "region" { type = string, default = "ap-northeast-1" }
variable "instance_type" { type = string, default = "t3.micro" }
data "aws_ami" "al2023" {
most_recent = true
owners = ["amazon"]
filter { name = "name", values = ["al2023-ami-*-x86_64"] }
}
resource "aws_instance" "demo" {
ami = data.aws_ami.al2023.id
instance_type = var.instance_type
tags = { Name = "tf-demo" }
}
output "public_ip" { value = aws_instance.demo.public_ip }
EOF1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
4. 初始化与创建
bash
terraform init && terraform fmt && terraform validate
terraform plan -out=tfplan && terraform apply tfplan1
2
2
5. 用完即毁
bash
ssh ec2-user@$(terraform output -raw public_ip) 'echo login-ok'
terraform destroy1
2
2
验证
bash
terraform state list && terraform output public_ip1
- [ ]
terraform validate通过 - [ ] apply 后 output 能拿到 IP 且可 SSH
- [ ] destroy 后控制台上资源已消失
常见坑
忘了 terraform init
换目录或新增 provider 后未 init 会报 provider not found。
手动改了云上配置
Terraform 只认 state,控制台手改会造成漂移,下次 apply 可能被回滚。
AMI 写死会失效
镜像 ID 按区域不同且会轮转。用 data "aws_ami" 加 filter 动态查询。