如何从Terraform中的文件加载输入数据?

如何从Terraform中的文件加载输入数据?,terraform,Terraform,我在terraform中定义了一个aws\u cloudwatch\u event\u target,从cloudwatch向lambda发射一个事件。输入字段是事件参数,例如: resource "aws_cloudwatch_event_target" "data" { rule = "${aws_cloudwatch_event_rule.scheduler.name}" target_id = "finance_producer_cloudwatch" arn

我在terraform中定义了一个
aws\u cloudwatch\u event\u target
,从
cloudwatch
向lambda发射一个事件。
输入
字段是事件参数,例如:

resource "aws_cloudwatch_event_target" "data" {
  rule      = "${aws_cloudwatch_event_rule.scheduler.name}"
  target_id = "finance_producer_cloudwatch"
  arn       = "${aws_lambda_function.finance_data_producer.arn}"
  input     = "{\"test\": [\"111\"]}"
}
我想知道如何从外部文件加载
输入
json数据。

您可以使用从外部文件提取数据:

input = "${file("myjson.json")}"

只需确保磁盘上的
myjson.json
与其他Terraform文件位于同一目录中。

我将使用数据模板文件资源。就像这样

data "template_file" "my_file" {
  template = "${file("${path.module}/my_file.json")}"
  vars = {
    var_to_use_in_file = "${var.my_value}"
  }
}
然后在您的资源块中

resource "aws_cloudwatch_event_target" "data" {
  rule      = "${aws_cloudwatch_event_rule.scheduler.name}"
  target_id = "finance_producer_cloudwatch"
  arn       = "${aws_lambda_function.finance_data_producer.arn}"
  input     = "${data.template_file.my_file.rendered}"
}

这里的答案取决于几个不同的问题:

  • 此文件是配置的静态部分,与
    .tf
    文件一起签入到版本控制中,还是作为应用过程的一部分动态生成
  • 您是想按字面意思使用文件内容,还是需要从Terraform配置的其他地方将值替换到文件中
这两个问题构成了四个不同答案的矩阵:

             |  Literal Content            Include Values from Elsewhere
-------------|----------------------------------------------------------
Static File  |  file(...) function         templatefile(...) function
Dynamic File |  local_file data source     template_file data source
我将在下面更详细地描述这四个选项中的每一个

所有这些示例中的一个共同主题都是对
path.module
的引用,该主题的计算结果为当前模块加载的路径。另一种考虑方法是,它是包含当前
.tf
文件的目录。允许访问其他目录中的文件,但在大多数情况下,通过将数据文件和配置文件放在一起,使模块中的内容保持独立是合适的

Terraform字符串是unicode字符序列,因此Terraform只能读取包含有效UTF-8编码文本的文件。对于JSON来说,这没有问题,但对于其他可能不是常规UTF-8编码的文件格式,值得记住

文件
功能 作为配置初始评估的一部分,从磁盘读取文件的文本内容。出于验证目的,文件内容被视为文本字符串值,因此文件必须作为配置的静态部分存在于磁盘上(通常在版本控制中),而不是在
terraform apply
期间动态生成

resource "aws_cloudwatch_event_target" "data" {
  rule      = aws_cloudwatch_event_rule.scheduler.name
  target_id = "finance_producer_cloudwatch"
  arn       = aws_lambda_function.finance_data_producer.arn
  input     = file("${path.module}/input.json")
}
这是最常见和最简单的选择。如果
文件
功能足以满足您的需要,那么它是作为默认选项使用的最佳选项

模板文件
功能 类似于
file
函数,但它不是直接返回文件内容,而是将文件内容解析为,然后使用第二个参数中给出的一组局部变量对其求值。如果您需要从地形配置中的其他位置传递一些数据,这非常有用,如本例所示:

resource "aws_cloudwatch_event_target" "data" {
  rule      = aws_cloudwatch_event_rule.scheduler.name
  target_id = "finance_producer_cloudwatch"
  arn       = aws_lambda_function.finance_data_producer.arn
  input     = templatefile("${path.module}/input.json.tmpl", {
    instance_id = aws_instance.example.id
  })
}
input.json.tmpl
中,可以使用Terraform模板语法替换该变量值:

{"instance_id":${jsonencode(instance_id)}}
在这种情况下,如果整个结果是JSON,我建议只使用
jsonecode
生成整个结果,因为这样您就可以让Terraform担心JSON转义等问题,只需使用Terraform的对象语法编写数据结构:

${jsonencode({
  instance_id = instance_id
})}
文件
一样,由于
templatefile
是一个函数,因此在配置的初始解码期间对其进行评估,并将其结果验证为文本值。因此,模板文件也必须是作为配置的一部分分发的静态文件,而不是动态生成的文件

local\u文件
数据源 是读取现有对象或计算结果的特殊资源类型,而不是创建和管理新对象。因为它们是资源,所以它们可以参与依赖关系图,因此可以使用在
Terraform apply
期间由相同Terraform配置中的其他资源创建的对象(包括本地文件)

resource "aws_cloudwatch_event_target" "data" {
  rule      = aws_cloudwatch_event_rule.scheduler.name
  target_id = "finance_producer_cloudwatch"
  arn       = aws_lambda_function.finance_data_producer.arn
  input     = file("${path.module}/input.json")
}
属于并且本质上是
文件
函数的数据源等价物

在下面的示例中,我使用
var.input\u file
作为占位符来引用由相同配置中的其他资源创建的文件路径。在实际示例中,这很可能是对资源属性的直接引用

data "local_file" "input" {
  filename = var.input_file
}

resource "aws_cloudwatch_event_target" "data" {
  rule      = aws_cloudwatch_event_rule.scheduler.name
  target_id = "finance_producer_cloudwatch"
  arn       = aws_lambda_function.finance_data_producer.arn
  input     = data.local_file.input.content
}
模板文件
数据源 是与
模板文件
函数等效的数据源。它的用法类似于
local_file
,不过在本例中,我们通过将模板作为静态文件读取来填充模板本身,使用
file
函数或
local_file
,具体取决于模板是在静态文件还是动态生成的文件中,虽然如果它是静态文件,我们更喜欢使用
templatefile
函数,因此我们将在此处使用
local_文件
数据源:

data "local_file" "input_template" {
  filename = var.input_template_file
}

data "template_file" "input" {
  template = data.local_file.input_template.content
  vars = {
    instance_id = aws_instance.example.id
  }
}

resource "aws_cloudwatch_event_target" "data" {
  rule      = aws_cloudwatch_event_rule.scheduler.name
  target_id = "finance_producer_cloudwatch"
  arn       = aws_lambda_function.finance_data_producer.arn
  input     = data.template_file.input.rendered
}
templatefile
功能是在Terraform 0.12.0中添加的,因此您可以在其他地方看到使用
template\u文件
数据源渲染静态模板文件的示例。这是一种旧模式,现在在Terraform 0.12中已被弃用,因为
templatefile
函数在大多数情况下都可以提供更直接、更可读的配置

templatefile
功能不同的是,
templatefile\u文件
数据源的一个怪癖是,数据源属于Terraform Core,而不是Terraform Core,因此其中可用的模板功能将取决于安装了哪个版本的提供程序,而不是安装了哪个版本的Terraform CLI。
template
提供程序在哪些模板语言功能可用方面可能落后于Terraform Core,这是在可能的情况下首选
templatefile
功能的另一个原因

其他可能性 这个问题是关于从文件中读取数据的,但是