首页 > 解决方案 > 基于传入的 AWS 命名空间的 Terraform 条件输出?

问题描述

$ 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-servicesterraformterraform-provider-aws

解决方案


您可以使用条件表达式

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)
}

推荐阅读