如何将 .env 文件中的环境变量读取到 terraform 脚本中?

Mag*_*nus 3 terraform

我正在使用 terraform 在 aws 上构建一个 lambda 函数。用于上传环境变量的 terraform 脚本中的语法是:

resource "aws_lambda_function" "name_of_function" {

  ...

  environment {
    variables = {
      foo     = "bar"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在.env我的 repo 中有一个文件,里面有一堆变量,例如email='admin@example.com',我希望 terraform 从该文件中读取(一些)它们并将它们注入到空间中,以便 env vars 上传并可供 lambda 函数使用. 如何才能做到这一点?

小智 35

这是一个纯 TerraForm 解决方案,可将.env文件解析为本机 TerraForm 地图。

output "foo" {
  value = { for tuple in regexall("(.*?)=(.*)", file("/path/to/.env")) : tuple[0] => tuple[1] }
}
Run Code Online (Sandbox Code Playgroud)

我已将其定义为通过 CLI 进行快速测试的输出,但您始终可以将其定义为本地或直接在参数上。

编辑以允许环境变量包含=

  • 如果像我们一样,您的 `.env` 值有时包含 `=` 字符(例如,base64 编码值),您可能希望第一个匹配是非贪婪的,如: `...regexall("(.*? )=(.*)", ...` (13认同)

Fáb*_*lho 16

根据 @Uizz Underweasel 的回复,出于安全目的,我只是添加了敏感函数:

在variables.tf中定义——安全

locals {
  envs = { for tuple in regexall("(.*)=(.*)", file(".env")) : tuple[0] => sensitive(tuple[1]) }
}
Run Code Online (Sandbox Code Playgroud)

Variables.tf 中的定义-不太安全

locals {
  envs = { for tuple in regexall("(.*)=(.*)", file(".env")) : tuple[0] => tuple[1] }
}
Run Code Online (Sandbox Code Playgroud)

.env的示例

HOST=127.0.0.1
USER=my_user
PASSWORD=pass123
Run Code Online (Sandbox Code Playgroud)

用途

output "envs" {
  value = local.envs["HOST"]
  sensitive = true # this is required if the sensitive function was used when loading .env file (more secure way)
}
Run Code Online (Sandbox Code Playgroud)


Mag*_*nus 6

我现在的解决方案涉及 3 个点/步骤。

  1. 将变量放在 .env 文件中,如下所示:
export TF_VAR_FOO=bar
Run Code Online (Sandbox Code Playgroud)

是的,您必须在 varsTF_VAR_前面加上前缀有点烦人,但我已经学会忍受它(至少它在您的 .env 中明确了 terraform 将使用哪些 vars,哪些不会。)

  1. 在您的 TF 脚本中,您必须声明任何不带TF_VAR_前缀的此类变量。例如
variable "FOO" {
  description = "Optionally say something about this variable"
}
Run Code Online (Sandbox Code Playgroud)
  1. 在运行 terraform 之前,您需要获取 .env 文件 ( . .env),以便任何此类变量都可用于要在当前 shell 环境中启动的进程(即此处的 terraform)。添加这一步并不困扰我,因为无论如何我总是使用 bash 脚本操作我的 repo。

注:我把一个更好的方式来处理.ENV文件的请求,在这里,虽然我其实是现在的事情很高兴,因为是(这只是糟糕的官方文档中描述的TF如何与IMO .ENV文件)。

  • 只是注意到“export TF_FOO”对我不起作用,但“export TF_VAR_FOO”对我有用。 (2认同)

Jim*_*mbo 0

我最终编写了一个简单的 PHP 脚本来读取 env 文件,按照我想要的方式解析它(explode()删除带有“#”的行,然后再次删除其他变量等implode()),然后首先在我的 makefile 中对其进行评估。看起来像这样:

provision:
    @eval $(php ./scripts/terraform-env-vars.php); \
    terraform init ./deployment/terraform; \
    terraform apply -auto-approve ./deployment/terraform/
Run Code Online (Sandbox Code Playgroud)

不幸的是 terraform 有一个荒谬的想法,即所有环境变量都必须以TF_VAR_.

grep我通过和的组合解决了这个问题sed,我的想法是用正则表达式用所需的前缀替换所有环境变量。

首先,您需要在 .tf 文件中声明一个与环境变量同名的输入变量:

variable "MY_ENV_VAR" {
  type = string
}
Run Code Online (Sandbox Code Playgroud)

然后,在 terraform 命令之前使用以下命令:

export $(shell sed -E 's/(.*)/TF_VAR_\1/' my.env | grep -v "#" | grep -v "TF_VAR_$"); terraform apply

这是做什么的:

  • 用于使用sed抓取捕获组中的每一行,然后使用第一个捕获组 ( )(.*)来替换前缀TF_VAR\1
  • 使用 grep 删除所有有注释的行(任何带#)。
  • 使用 grep 删除所有仅包含TF_VAR.

不幸的是,这还有一堆使用前缀创建的其他环境变量TF_VAR,我不确定为什么,但这至少是使用.envterraform 文件的开始。