Terraform 数据源 (AWS)
Source: Dev.to
Terraform 数据源是什么?
Terraform 中的数据源是对已有资源的 只读查询。它不是创建新资源,而是向云提供商(此处为 AWS)发起查询,并返回可在配置中使用的信息。
何时使用数据源
- 资源已经存在(例如共享的 VPC、已有的 AMI)。
- 资源由其他团队管理(网络或安全团队)。
- 你的 Terraform 模块不应拥有或重新创建该资源。
- 需要最新或经过过滤的某些资源(例如最新的 AMI)。
- 想避免硬编码 ID、ARN 等标识符。
使用数据源可以让基础设施代码更简洁、更具动态性。
示例 1:使用数据源获取 VPC ID
在许多组织中,网络是集中管理的。VPC 已经存在,你的 Terraform 代码只会在其中部署应用资源。
data "aws_vpc" "vpc_name" {
filter {
name = "tag:Name"
values = ["default-vpc"]
}
}
- 查找标签 Name = default-vpc 的 VPC。
- 返回 VPC 的 ID,可通过
data.aws_vpc.vpc_name.id访问。 - 免去了手动获取或维护 VPC ID 的需求。
示例 2:从特定 VPC 中获取子网 ID
获取到 VPC 后,通常还需要该 VPC 内的子网。
data "aws_subnet" "shared_subnet" {
filter {
name = "tag:Name"
values = ["subnet-a"]
}
vpc_id = data.aws_vpc.vpc_name.id
}
- 获取标签 Name = subnet-a 的子网。
- 确保子网属于前面获取的 VPC。
- 返回单个子网 ID,可通过
data.aws_subnet.shared_subnet.id使用。
这样 Terraform 就能在正确的共享子网中部署 EC2 或 Lambda 资源,而无需硬编码任何内容。
示例 3:获取最新的 Amazon Linux 2 AMI
AMI ID 在各地区经常变化,使用过时或硬编码的 AMI 会导致部署失败。
data "aws_ami" "linux2" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
filter {
name = "architecture"
values = ["x86_64"]
}
}
- 获取 最新 的 Amazon Linux 2 AMI。
- 将结果限制为 Amazon 官方账户拥有的镜像。
- 确保 AMI 符合所需的架构和虚拟化类型。
这是数据源自动保持镜像最新的典型案例。
使用数据源启动 EC2 实例
在获取到 VPC、子网和 AMI 后,可以使用这些动态值来创建 EC2 实例:
resource "aws_instance" "ec2_one" {
ami = data.aws_ami.linux2.id
instance_type = var.instance_type
subnet_id = data.aws_subnet.shared_subnet.id
tags = var.tags
}
- 使用来自数据源的 AMI。
- 将 EC2 实例放置在共享子网中。
- 应用用户提供的实例类型和标签。
最终得到的是一个可复用、与环境无关且面向未来的 Terraform 配置。
为什么数据源很重要
- 避免硬编码 – 无需手动存储 ID、ARN 或 AMI。
- 支持多团队、多账户使用 – 各团队可以引用中心资源,而无需修改权限。
- 提升可复用性 – 模块变得通用,可在 dev、test、prod 环境中无缝使用。
- 支持动态和自动化基础设施 – 获取最新 AMI 可确保安全性和一致性。
- 减少人为错误 – 消除复制粘贴 ID 的错误风险。
结论
Terraform 数据源是构建动态、安全、面向生产的基础设施的关键。它们让你的代码能够与已有的 AWS 资源(如 VPC、子网、AMI 等)交互,而无需重新创建这些资源。上述示例展示了在共享网络环境中,基础设施团队如何广泛使用这些模式。有效利用数据源,能够让你的 Terraform 设置更具可扩展性、可维护性,并与最佳 DevOps 实践保持一致。