【问题标题】:Terraform conditional output based on passed-in AWS namespace?基于传入的 AWS 命名空间的 Terraform 条件输出?
【发布时间】:2021-06-25 01:58:00
【问题描述】:
$ terraform -v
Terraform v0.14.6

我有一个创建不同 CloudWatch 警报的计划,像这样

module "rds_high_cpu_alarm" {
  source    = "../modules/cw_alarm"
  namespace = "AWS/RDS"
  statistic = "Average"
  // Other parameters
  ...
}

module "ecs_task_count_alarm" {
  source    = "../modules/cw_alarm"
  namespace = "AWS/ECS"
  statistic = "SampleCount"
  // Other parameters
  ...
}

module "other_aws_alarm" {
  source    = "../modules/cw_alarm"
  namespace = "AWS/OtherNamespace"
  statistic = "OtherStatistic"
}

如您所见,警报共享同一个模块,../modules/cw_alarm,看起来像这样,每个aws_cloudwatch_metric_alarm

# I want to use this for RDS DB instance high CPU alarm
resource "aws_cloudwatch_metric_alarm" "rds_aws_alarm" {
  count      = var.namespace == "AWS/RDS" ? 1 : 0
  alarm_name = var.alarm_name
  namespace  = var.namespace
  statistic  = "Average"
  ...
  dimensions = {
    DBInstanceIdentifier = var.db_instance_id
  }
}

# I want to use this for ECS task count < 1 alarm
resource "aws_cloudwatch_metric_alarm" "ecs_aws_alarm" {
  count      = var.namespace == "AWS/ECS" ? 1 : 0
  alarm_name = var.alarm_name
  namespace  = var.namespace
  statistic  = "SampleCount"
  ...
  dimensions = {
    ServiceName = var.servicename
  }
}

# Other alarm resources
resource "aws_cloudwatch_metric_alarm" "other_aws_alarm" {
  ...
}

如何设置通用输出以使用上述资源之一来输出警报的 ARN?

# In pseudo-code
output "aws_alarm_arn" {
  switch var.namespace {
    case "AWS/RDS":
      value = aws_cloudwatch_metric_alarm.rds_aws_alarm.arm
      break
    case "AWS/ECS":
      value = aws_cloudwatch_metric_alarm.ecs_aws_alarm.arm
      break
    default:
      value = aws_cloudwatch_metric_alarm.other_aws_alarm.arm
  }
}

也就是说,如何根据创建的告警资源输出告警ARN?请记住,我可以添加比我展示的 3 个更多的警报。

我知道我可以为每个警报命名空间创建不同的源模块(这可能是一个很好的解决方案),但请幽默一下。

【问题讨论】:

    标签: amazon-web-services terraform terraform-provider-aws


    【解决方案1】:

    你可以使用conditional expression:

    output "aws_alarm_arn" {
    
      value = (var.namespace == "AWS/RDS" 
              ? aws_cloudwatch_metric_alarm.rds_aws_alarm.arm
              : (var.namespace == "AWS/ECS"
                    ? aws_cloudwatch_metric_alarm.ecs_aws_alarm.arm
                    : aws_cloudwatch_metric_alarm.other_aws_alarm.arm
                )
              )
    }
    

    如果您的闹钟是互斥的,您可以简单地使用try进行上述操作:

    output "aws_alarm_arn" {
    
      value = try(
             aws_cloudwatch_metric_alarm.rds_aws_alarm[0].arn,
             aws_cloudwatch_metric_alarm.ecs_aws_alarm[0].arn,
             aws_cloudwatch_metric_alarm.other_aws_alarm[0].arn)
    }
    

    【讨论】:

    • 谢谢马尔辛。这可能只适用于 3 个警报资源,如果该列表增长,它可能是繁琐的代码。
    • @ChrisF 是的,我同意。但这是你的问题。你必须重新设计你的代码以避免条件增长,最好使用map 来处理你所有可能的警报。或者创建带有警报的模块。
    • @ChrisF 我现在很困惑。你提供了你想要的pseudo-code。那么,如果您不想要与 pseudo-code 等效的 TF,您能否准确说明您的问题?
    • 相互爆炸,我喜欢! :) 我确实会试试这个。
    • 哇,try() 表达式成功了!谢谢!
    猜你喜欢
    • 2021-09-20
    • 2015-01-24
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    相关资源
    最近更新 更多