【问题标题】:Terraform dynamically generate strings using data sources outputTerraform 使用数据源输出动态生成字符串
【发布时间】:2022-01-04 19:32:00
【问题描述】:

有什么方法可以将 Terraform 数据源输出作为输入提供给另一个 Terraform 文件

场景是,我有一个 terraform 代码来使用数据源获取特定标签(此处为 jenkins)的私有 IP 地址(此处为 3 个 IP 10.1.1.1,10.1.1.2,10.1.1.3)

data "aws_instances" "mytag" {
    filter {
        name = "tag:Application"
        values = ["jenkins"]
    }
}

output "output from aws" {
    value = data.aws_instances.mytag_private_ips
}

每当我应用 terraform 时,在 下面的 metric-filter 代码应该能够从上面的代码中获取结果 IP,并使其在实时状态下可用(aws 控制台)

resource "aws_cloudwatch_log_metric_filter" "test" {
    name = "test-metric-filter"
    pattern = "[w1,w2,w3,w4!=\"*<IP1>*\"&&w4!=\"*<IP2>*\"&&w4!=\"*<IP3>*\",w5=\"*admin*\"]"
    log_group_name = var.test_log_group_name

    metric_transformation {
      name ="test-metric-filter"
      namespace = "General"
    }
}

因此,aws 控制台中 metric 模式的最终结果应该如下所示

[w1,w2,w3,w4!="*10.1.1.1*"&&w4!="*10.1.1.2*"&&w4!="*10.1.1.3*",w5="*admin*"]

最终目标是每当生成新 IP 时,它将被填充为模式(在 aws-console 中),而无需更改指标过滤器代码。

感谢任何帮助,因为我在 terraform 上找不到任何精确的文档,允许我们使用数据源动态生成字符串

【问题讨论】:

  • 这么少的代码为什么要两个文件?

标签: terraform amazon-cloudwatch cloudwatch-alarms


【解决方案1】:

您正在寻找的是 Terraform 中的 string interpolation

我相信你会想要做以下事情:

pattern = "[w1,w2,w3,w4!=\"*${data.aws_instances.mytag.private_ips[0]}*\"&&w4!=\"*${data.aws_instances.mytag.private_ips[1]}*\"&&w4!=\"*${data.aws_instances.mytag.private_ips[2]}*\",w5=\"*admin*\"]"

我建议谨慎使用此语句,因为如果您没有至少 3 个实例,它将失败。你会想要一些动态的东西。

【讨论】:

    【解决方案2】:

    不知道为什么这么简单的事情需要两个文件...
    这是我会做的:

    provider "aws" {
      region = "us-east-1"
    }
    
    data "aws_instances" "test" {
      filter {
        name   = "architecture"
        values = ["x86_64"]
      }
    }
    
    resource "aws_cloudwatch_log_metric_filter" "test" {
      name    = "test-metric-filter"
      pattern = "[w1,w2,w3,w4!=\"*${data.aws_instances.test.private_ips[0]}*\",w5=\"*admin*\"]"
      log_group_name = "test_log_group_name"
    
      metric_transformation {
        name      = "test-metric-filter"
        namespace = "General"
        value     = 1
      }
    }
    

    然后会显示一个 terraform 计划

    Terraform will perform the following actions:
    
      # aws_cloudwatch_log_metric_filter.test will be created
      + resource "aws_cloudwatch_log_metric_filter" "test" {
          + id             = (known after apply)
          + log_group_name = "test_log_group_name"
          + name           = "test-metric-filter"
          + pattern        = "[w1,w2,w3,w4!=\"*172.31.70.170*\",w5=\"*admin*\"]"
    
          + metric_transformation {
              + name      = "test-metric-filter"
              + namespace = "General"
              + unit      = "None"
              + value     = "1"
            }
        }
    
    Plan: 1 to add, 0 to change, 0 to destroy.
    

    连接字符串很简单:"foo ${var.bar} 123"
    在这种情况下,我们的 private_ips 是一个数组,所以我们需要 [x]

    对于更复杂的连接,请查看格式函数:
    https://www.terraform.io/docs/language/functions/format.html

    我确实更改了过滤器以便能够在我的环境中进行测试,并且还使用了比您的更短的模式,但这是您需要的基础,只需添加更多的 make changes 以满足您的需求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-22
      • 2019-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多