Terraform Lambda heredoc 未解析内联函数变量

Terraform Lambda heredoc not resolving inline function variables

我的内插变量,无论是否带有 ${} 字符,都不会解析为 Terraform 引用值。我的代码如下所示:

data "archive_file" "lambda_zip_file_int" {
  type        = "zip"
  output_path = "/tmp/lambda_zip_file_int.zip"
  source {
    content  =  <<EOF
    'use strict';
    var AWS = require('aws-sdk');
    exports.handler = (event, context, callback) => {
      ...
      var params = {
        foo: ${aws_cognito_user_pool.my_pool.id}
      }
      ...
        callback(null, event);
      });
    };
EOF
    filename = "foo.js"
  }
}

lambda 函数创建正确,但是

      var params = {
        foo: ${aws_cognito_user_pool.my_pool.id}
      }

作为文字保存在我的函数中,没有替换实际值。

提前致谢

您在此处共享的 template expression 似乎会创建无效的 JavaScript 语法,因为将 Cognito 池 ID 直接替换到该位置会产生如下内容:

  var params = {
    foo: us-west-2:11111111-1111-1111-1111-111111111111
  }

获得此结果的更可靠方法是使用 Lambda environment variables,这样 Lambda 函数中的 JavaScript 代码可以完全静态,但可以从后面声明函数时传入的环境变量:

  source {
    content  =  <<EOF
    'use strict';
    var AWS = require('aws-sdk');
    exports.handler = (event, context, callback) => {
      ...
      var params = {
        foo: process.environment.COGNITO_POOL_ID
      }
      ...
        callback(null, event);
      });
    };
EOF
    filename = "foo.js"
  }

请注意,以上只是从 NodeJS 程序访问环境变量的正常方式,并不是 Terraform 的特殊方式。

当您使用 aws_lambda_function 声明 Lambda 函数时,您可以传入该环境变量的最终具体值,这允许您稍后更改它而无需重建代码包:

resource "aws_lambda_function" "example" {
  # ...

  environment {
    variables = {
      COGNITO_POOL_ID = aws_cognito_user_pool.my_pool.id
    }
  }
}

虽然我建议尽可能避免动态代码生成,但您也可以通过字符串的 JSON 编码也是有效的事实来使您的原始示例有效 JavaScript 语法JavaScript 字符串编码:

      var params = {
        foo: ${jsonencode(aws_cognito_user_pool.my_pool.id)}
      }

这也应该产生一个有效的结果,但这意味着 Cognito 池 ID 嵌入在您的函数的源代码中,以后对其进行更改将需要重建源代码包。

  var params = {
    foo: "us-west-2:11111111-1111-1111-1111-111111111111"
  }