创建第一个 Terraform 资源 #
准备工作 #
在开始之前,请确保:
text
┌─────────────────────────────────────────────────────────────┐
│ 准备工作 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✅ 已安装 Terraform(运行 terraform version 验证) │
│ ✅ 有一个云服务账号(AWS/Azure/GCP) │
│ ✅ 配置好认证凭证 │
│ ✅ 创建一个工作目录 │
│ │
└─────────────────────────────────────────────────────────────┘
创建项目目录 #
bash
mkdir terraform-demo
cd terraform-demo
示例一:创建本地文件 #
让我们从最简单的例子开始,创建一个本地文件。
创建配置文件 #
创建 main.tf 文件:
hcl
terraform {
required_version = ">= 1.0.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.0"
}
}
}
provider "local" {}
resource "local_file" "hello" {
filename = "hello.txt"
content = "Hello, Terraform!"
}
初始化项目 #
bash
terraform init
输出:
text
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/local versions matching "~> 2.0"...
- Installing hashicorp/local v2.4.1...
- Installed hashicorp/local v2.4.1 (signed by HashiCorp)
Terraform has been successfully initialized!
查看执行计划 #
bash
terraform plan
输出:
text
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.hello will be created
+ resource "local_file" "hello" {
+ content = "Hello, Terraform!"
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "hello.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
应用变更 #
bash
terraform apply
输入 yes 确认:
text
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# local_file.hello will be created
+ resource "local_file" "hello" {
+ content = "Hello, Terraform!"
+ directory_permission = "0777"
+ file_permission = "0777"
+ filename = "hello.txt"
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
local_file.hello: Creating...
local_file.hello: Creation complete after 0s [id=abc123]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
验证结果 #
bash
cat hello.txt
输出:
text
Hello, Terraform!
查看状态 #
bash
terraform show
销毁资源 #
bash
terraform destroy
示例二:创建 AWS EC2 实例 #
让我们创建一个更实际的例子,在 AWS 上创建一个 EC2 实例。
配置 AWS 凭证 #
bash
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_DEFAULT_REGION="us-east-1"
或使用 AWS CLI 配置:
bash
aws configure
创建配置文件 #
创建 main.tf:
hcl
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "terraform-example"
}
}
初始化并应用 #
bash
terraform init
terraform plan
terraform apply
查看输出 #
创建 outputs.tf:
hcl
output "instance_id" {
description = "ID of the EC2 instance"
value = aws_instance.example.id
}
output "instance_public_ip" {
description = "Public IP of the EC2 instance"
value = aws_instance.example.public_ip
}
应用后查看输出:
bash
terraform output
示例三:使用变量 #
创建变量文件 #
创建 variables.tf:
hcl
variable "region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
variable "instance_name" {
description = "Name tag for the instance"
type = string
default = "terraform-example"
}
更新主配置 #
更新 main.tf:
hcl
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = var.instance_type
tags = {
Name = var.instance_name
}
}
使用变量文件 #
创建 terraform.tfvars:
hcl
region = "us-west-2"
instance_type = "t2.small"
instance_name = "my-server"
应用配置 #
bash
terraform apply -var-file="terraform.tfvars"
命令行传递变量 #
bash
terraform apply -var="instance_type=t2.medium" -var="instance_name=production-server"
示例四:创建完整的基础设施 #
让我们创建一个更完整的例子,包括 VPC、子网、安全组和 EC2 实例。
项目结构 #
text
terraform-demo/
├── main.tf
├── variables.tf
├── outputs.tf
└── terraform.tfvars
main.tf #
hcl
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.region
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.project_name}-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr
map_public_ip_on_launch = true
availability_zone = "${var.region}a"
tags = {
Name = "${var.project_name}-public-subnet"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${var.project_name}-igw"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${var.project_name}-public-rt"
}
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
resource "aws_security_group" "web" {
name = "${var.project_name}-web-sg"
description = "Security group for web server"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.project_name}-web-sg"
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
tags = {
Name = "${var.project_name}-web-server"
}
}
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
variables.tf #
hcl
variable "region" {
description = "AWS region"
type = string
default = "us-east-1"
}
variable "project_name" {
description = "Project name for resource naming"
type = string
default = "terraform-demo"
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}
variable "public_subnet_cidr" {
description = "CIDR block for public subnet"
type = string
default = "10.0.1.0/24"
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t2.micro"
}
outputs.tf #
hcl
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.main.id
}
output "public_subnet_id" {
description = "The ID of the public subnet"
value = aws_subnet.public.id
}
output "instance_id" {
description = "The ID of the EC2 instance"
value = aws_instance.web.id
}
output "instance_public_ip" {
description = "The public IP of the EC2 instance"
value = aws_instance.web.public_ip
}
output "security_group_id" {
description = "The ID of the security group"
value = aws_security_group.web.id
}
terraform.tfvars #
hcl
region = "us-east-1"
project_name = "my-project"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.1.0/24"
instance_type = "t2.micro"
执行流程 #
bash
terraform init
terraform validate
terraform fmt
terraform plan
terraform apply
terraform output
terraform destroy
工作流程总结 #
text
┌─────────────────────────────────────────────────────────────┐
│ Terraform 工作流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 编写配置 │
│ └── 创建 .tf 文件 │
│ │
│ 2. 初始化 │
│ $ terraform init │
│ └── 下载 Provider │
│ │
│ 3. 验证 │
│ $ terraform validate │
│ └── 检查语法 │
│ │
│ 4. 格式化 │
│ $ terraform fmt │
│ └── 统一格式 │
│ │
│ 5. 计划 │
│ $ terraform plan │
│ └── 预览变更 │
│ │
│ 6. 应用 │
│ $ terraform apply │
│ └── 执行变更 │
│ │
│ 7. 销毁 │
│ $ terraform destroy │
│ └── 清理资源 │
│ │
└─────────────────────────────────────────────────────────────┘
常见问题 #
状态文件锁定 #
text
Error: Error acquiring the state lock
解决方案:
bash
terraform force-unlock <LOCK_ID>
Provider 认证失败 #
text
Error: error configuring Terraform AWS Provider
解决方案:
bash
aws configure
# 或设置环境变量
export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"
资源已存在 #
text
Error: Resource already exists
解决方案:
bash
terraform import aws_instance.example i-1234567890abcdef0
下一步 #
恭喜你创建了第一个 Terraform 资源!接下来学习 Provider 配置,了解如何配置不同的云服务提供商!
最后更新:2026-03-29