Terraform – Data Source的使用

Terraform data 资源的作用

在 Terraform 中,data 资源用于读取和查询外部的现有资源,而不创建新的资源。主要作用包括:

  1. 引用现有资源:获取已经存在的基础设施资源,而无需重新定义或创建。
  2. 动态查找信息:在运行时获取某些信息,比如 AWS 的 AMI ID、VPC ID 等。
  3. 跨 Terraform 配置共享资源:在不同的 Terraform 配置之间共享已有资源的信息。

使用案例 1:查询 AWS 最新的 AMI ID

如果要创建一台 EC2 实例,但不想手动指定 AMI ID,而是希望自动获取 AWS Marketplace 上最新的 AMI,可以使用 data 资源:

provider "aws" {
  region = "ap-southeast-5"
}

data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }
  filter {
    name   = "name" //找出最新版本的Amazon Linux 2023 AMI
    values = ["al2023-ami-2023*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest_amazon_linux.id
  instance_type = "t2.micro"
}

output "result"{
  value = data.aws_ami.latest_amazon_linux.name
}

解释:

  • data "aws_ami" 查询 AWS 上最新的 Amazon Linux AMI ID。
  • most_recent = true 确保获取的是最新的 AMI。
  • ami = data.aws_ami.latest_amazon_linux.id 在 EC2 资源中使用查询到的 AMI ID。

使用案例 2:获取现有的 VPC ID

如果 VPC 是手动创建的,或者由另一个 Terraform 配置管理,我们可以使用 data 资源来获取 VPC ID,而不是硬编码:

data "aws_vpc" "default" {
  default = true
}

resource "aws_subnet" "example" {
  vpc_id            = data.aws_vpc.default.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-west-2a"
}

解释:

  • data "aws_vpc" "default" 查找 AWS 账户中的默认 VPC。
  • data.aws_vpc.default.idaws_subnet 资源中使用 VPC ID,而不需要手动指定。

使用案例 3:跨 Terraform 工作空间共享资源

如果你的 Terraform 使用多个工作空间(workspace),你可以使用 data 资源动态获取资源,而不依赖硬编码:

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "my-terraform-state"
    key    = "network/terraform.tfstate"
    region = "us-west-2"
  }
}

resource "aws_instance" "app" {
  ami           = "ami-12345678"
  instance_type = "t2.micro"
  subnet_id     = data.terraform_remote_state.network.outputs.subnet_id
}

解释:

  • data "terraform_remote_state" 允许从另一个 Terraform 配置(例如 network 配置)读取 terraform.tfstate 文件。
  • data.terraform_remote_state.network.outputs.subnet_id 获取 network 配置中输出的 subnet_id,在当前 Terraform 配置中使用。

使用案例 4:在path.module 读取当前文件的数据

下面是一个示例,展示如何使用 Terraform 中的内置变量 path.module 来读取当前模块目录下的本地文件。假设你有一个 JSON 文件,用来配置 EC2 实例的参数,文件名为 config.json,其内容如下:

{
  "instance_type": "t2.micro",
  "ami": "ami-12345678"
}

你可以在 Terraform 配置中通过 data 读取该文件,并使用 jsondecode() 将其解析为对象,示例如下:

# 使用 local provider 提供的 local_file 数据源读取 config.json 文件
data "local_file" "config" {
  filename = "${path.module}/config.json"
}

# 使用 locals 保存解析后的 JSON 对象
locals {
  config = jsondecode(data.local_file.config.content)
}

resource "aws_instance" "example" {
  ami           = local.config.ami
  instance_type = local.config.instance_type
}

解释

  • path.module 变量
    • 这是 Terraform 的内置变量,返回当前模块所在目录的绝对路径。
    • 在本例中,通过 ${path.module}/config.json 构造了指向当前模块下 config.json 文件的完整路径。
  • local_file 数据源
    • 示例中使用了 local provider 提供的 local_file 数据源,而非直接使用 file() 函数。
    • 该数据源读取指定文件的全部文本内容,并将内容保存在 data.local_file.config.content 属性中。
  • jsondecode() 函数
    • 将从 local_file 数据源读取的 JSON 格式字符串转换为 Terraform 内部的数据结构(如 map)。
    • 这样可以在后续的资源定义中通过 local.config.amilocal.config.instance_type 等方式引用配置参数。
  • 应用场景
    • 这种方式允许将外部配置文件(如 JSON)与 Terraform 配置分离。
    • 避免在代码中硬编码参数,提高了配置的灵活性和可维护性。
    • 特别适用于参数配置较多或者需要动态调整资源配置的场景。

Terraform Registry 文档查询

在Terraform registry的文档当中,data sources就是读取数据的文档,有些数据返回是单个数据,有些返回的是list也就是多个数据

Loading

Facebook评论