🏉

Terraformのtry関数をdynamicブロックの作成条件に使う

2023/03/11に公開

Terraformで、特定の条件下でのみブロックを指定したい場面があります。たとえば、AWS Budgetsの予算を示すaws_budgets_budgetでは、予算タイプによってcost_filterブロックの要否が異なります。

条件ごとにリソースを定義してもよいのですが、テンプレートが冗長になりがちです。

下記の例では、try関数を使って、必要なときのみcost_filterブロックを指定してみました。すっきりしていて読みやすく感じます。

locals {
  budgets = {
    # RDSリザーブドインスタンスのカバレッジ予算。cost_filtersが必要
    reservation_coverage_rds = {
      name        = "Daily reservation coverage budget - RDS"
      budget_type = "RI_COVERAGE"

      cost_filters = [
        {
          name   = "Service"
          values = ["Amazon Relational Database Service"]
        }
      ]
    }

    # Savings Plansのカバレッジ予算。cost_filtersは不要
    savings_plans_coverage = {
      name        = "Daily Savings Plans coverage budget"
      budget_type = "SAVINGS_PLANS_COVERAGE"
    }
  }
}

resource "aws_budgets_budget" "this" {
  for_each = local.budgets

  account_id   = data.aws_caller_identity.current.account_id
  name         = each.value.name
  budget_type  = each.value.budget_type
  limit_amount = "100.0"
  limit_unit   = "PERCENTAGE"
  time_unit    = "DAILY"

  dynamic "cost_filter" {
    # cost_filtersが指定されていなければ、空のリストが返るので無視される
    for_each = try(each.value.cost_filters, [])

    content {
      name   = cost_filter.value.name
      values = cost_filter.value.values
    }
  }

  cost_types {
    include_credit             = false
    include_discount           = false
    include_other_subscription = false
    include_recurring          = false
    include_refund             = false
    include_subscription       = true
    include_support            = false
    include_tax                = false
    include_upfront            = false
    use_amortized              = false
    use_blended                = false
  }

  notification {
    comparison_operator        = "LESS_THAN"
    threshold                  = 80
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = ["admin@example.com"]
    subscriber_sns_topic_arns  = [data.aws_sns_topic.selected.arn]
  }
}

Discussion