Terraform 中可选的 CloudFront Lambda 函数关联

NRa*_*Raf 2 amazon-cloudfront aws-lambda terraform

我们在 CloudFront 和 S3 上托管我们的 Web 应用程序。该基础设施是在 Terraform 模块中配置的。我们使用相同的模块(由 Terragrunt 管理)将我们的 Web 应用程序部署到我们的暂存和生产环境。

显然,我们不希望公众访问我们的暂存环境。因此,我们创建了一个 Lambda 函数来启用基本 HTTP 身份验证,并使用资源lambda_function_association内的aws_cloudfront_distribution来启用它。

问题是我们不希望 Lambda 也在我们的生产环境中运行。我无法有条件地设置资源的关联。

我还尝试创建两个具有相同名称的资源并设置属性,count以便仅存在这些资源。

例如

# Basic Auth Guard
resource "aws_cloudfront_distribution" "default" {
  count = "${var.behind_auth_guard}"
  ...
}

# No Basic Auth Guard
resource "aws_cloudfront_distribution" "default" {
  count = "${var.behind_auth_guard ? 0 : 1}"
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试部署代码时,我得到了aws_cloudfront_distribution.default: resource repeated multiple times.

有什么办法可以实现我想要的吗?

我考虑过的另一个选择是在两个版本上设置 Lambda,但让它在产品中不执行任何操作。然而,这似乎效率低下且成本高昂,因为每次请求都会调用 Lamdba,并且希望尽可能避免这种情况。

小智 5

使用 Terraform v0.12.0 这将非常容易解决,因为它支持动态嵌套块。不幸的是,该版本不会在 2019 年第一季度之前发布。

与此同时,您可以采纳您自己提出的建议,并稍加修改。您只需要进行一些小的更改,因为不支持重复的名称。

# Basic Auth Guard
resource "aws_cloudfront_distribution" "cf_with_guard" {
  count = "${var.behind_auth_guard}"
  ...
}

# No Basic Auth Guard
resource "aws_cloudfront_distribution" "cf_no_guard" {
  count = "${var.behind_auth_guard ? 0 : 1}"
}
Run Code Online (Sandbox Code Playgroud)

如果您现在想使用此资源的任何输出,则必须使用一个小技巧。例如,如果你想输出id分布的:

output "cf_id" {
  value = "${var.behind_auth_guard ? join("", aws_cloudfront_distribution.cf_with_guard.*.id) : join("", aws_cloudfront_distribution.cf_no_guard.*.id)}"
}
Run Code Online (Sandbox Code Playgroud)

之所以需要它join(),是因为您无法引用不存在的资源。即使在 if 语句中也不行。join()通过引用所有资源的列表来解决此问题,如果资源的 为 0,则该列表为空count

供将来参考:如果 v0.12.0 发布,则不再需要上述解决方法。只需参考动态嵌套块即可。