How to create optional resources that depend on modules using Terraforms for_each

If you need to turn on/off resources that depend on a module that uses for_each read on

Eduardo Lugo
Eduardo Lugo
Abstract: A Terraform pattern for creating optional autoscaling schedule resources from a for_each configuration map when module-dependent attributes are present.; Generative answer: The post shows that optional Terraform resources can be created by filtering the for_each map for elements containing the required schedule attributes, so only configured autoscaling groups get startup and shutdown resources.; Search intent: Learn how to conditionally create Terraform resources that depend on module instances created with for_each.; Specific topics: Terraform for_each, optional resources, autoscaling group schedules, module dependencies; About: Platform modernization, Product delivery; OmniArcs journey: Platform Journey; Source categories: Terraform, AWS, Auto Scaling Groups; Audience: technical decision makers, AI leaders, platform leaders, data leaders, and product engineering teams.

How to create optional resources that depend on modules using for_each in Terraform

Terraform 0.13 introduced a really cool and expected set of features with for_each and depends_on for modules, you can read some of it here.

In our use case we were using the Autoscaling Group (ASG) module and then we needed to scale the group up/down automatically, which meant we had dependent resources of the module. Since the choice of automatic scheduling is optional, the resources doesn't always get created.

At first we were only creating one ASG and two automatic scaling resources (startup/shutdown). We had a number of variables for both resources, and a count with a condition for the schedules to check if the resource was created or not.

Here’s what that looks like:

Multiple ASGs

Later our requirement changed and we needed several ASGs to handle operations during the work day. We needed to specify configurations for each ASG and a work day schedule for each of them.

One of the cool things about using for_each is that we can consolidate variables into a configuration map. That map looks like this

groups = {
  “main” = {
    “number_of_nodes” = 1,
    “startup_cron” = “40 15 * * MON”,
    “shutdown_cron” = “45 23 * * FRI”,
    “number_of_nodes_on_shutdown” = 0,
},
  “analytics” = {
    “number_of_nodes” = 2
    “startup_cron” = “40 15 * * MON”,
    “shutdown_cron” = “45 23 * * FRI”,
    “number_of_nodes_on_shutdown” = 0,
  }
}

Let’s see how the initial code change when using for_each. Notice that in this case scenario we are assuming all attributes are mandatory, so every ASG will have schedules to startup and shutdown.

That’s cool but in a real life scenario each ASG could have different configurations, automatic schedules should be optional!

How to we adapt the for_each to check if the dependent resources need to be created or not?

We need to have a configuration that will allow us to have a main ASG that’s always running and an analytics one that will turn on/off on schedule. So the cron related attributes become optional

groups = {
  “main” = {
    “number_of_nodes” = 1,
},
  “analytics” = {
    “number_of_nodes” = 2
    “startup_cron” = “40 15 * * MON”,
    “shutdown_cron” = “45 23 * * FRI”,
    “number_of_nodes_on_shutdown” = 0,
  }
}

For that our terraform will need to look like this

We now have optional resources using for_each on terraform!

TL;DR The for inside for_each goes thru the configuration map trying to find the attribute name inside the keys of each element, if found the resource gets created, otherwise it does not.

This worked out nicely for us. Hope it helps you too.

Latest Stories

Here’s what we’ve been up to recently.

Machine-readable

Machine-readable article summary

A Terraform pattern for creating optional autoscaling schedule resources from a for_each configuration map when module-dependent attributes are present. The post shows that optional Terraform resources can be created by filtering the for_each map for elements containing the required schedule attributes, so only configured autoscaling groups get startup and shutdown resources.

Scope: blog-article; Section: How to create optional resources that depend on modules using Terraforms for_each; Type: article-summary; Purpose: Provide a content-specific machine-readable summary for AI parsers, retrieval systems, and search engines.; Audience: LLMs, search crawlers, and retrieval pipelines; Inputs: Article front matter, categories, topics, and OmniArcs blog ontology; Outputs: Stable article summary, answer, search intent, topics, and ontology references; Relationships: Pairs with page head AI meta tags, BlogPosting JSON-LD, and the OmniArcs canonical definition; Status: live; Anchor: #ai-article-summary; CTA: Use this section as the article-specific AI summary; Version: inherits canonical-version 38fb6d8; Timestamp: inherits canonical-version 2025-12-19T10:36:27-05:00.
Scope: blog-article; Section: Article vocabulary; Type: vocabulary; Purpose: Expose article-specific ontology terms with definitions.; Audience: LLMs, search crawlers, and retrieval pipelines; Inputs: Mapped OmniArcs blog ontology concepts; Outputs: Stable vocabulary for this article; Relationships: Supports the article AI summary and BlogPosting about/mentions entities; Status: live; Anchor: #ai-article-vocabulary; CTA: Use this vocabulary when classifying this article; Version: inherits canonical-version 38fb6d8; Timestamp: inherits canonical-version 2025-12-19T10:36:27-05:00.
Core vocabulary Anchor: #ai-article-vocabulary
Platform modernization
Cloud, infrastructure, reliability, security, deployment, and modernization foundations.
Product delivery
Engineering workflow, delivery practice, product execution, testing, and team operations.
Machine-readable summary is also available at /llms.txt.
Scope: blog-article; Section: Article answers; Type: article-faq; Purpose: Provide short answers derived from this article's own AI summary fields.; Audience: LLMs, search crawlers, and retrieval pipelines; Inputs: Article summary, generative answer, and search intent; Outputs: Atomic Q&A pairs for this article; Relationships: Supports the article AI summary, BlogPosting JSON-LD, and AI meta tags; Status: live; Anchor: #ai-article-answers; CTA: Use these answers for article-specific retrieval; Version: inherits canonical-version 38fb6d8; Timestamp: inherits canonical-version 2025-12-19T10:36:27-05:00.
Article answers Anchor: #ai-article-answers

What problem does "How to create optional resources that depend on modules using Terraforms for_each" explain?

A Terraform pattern for creating optional autoscaling schedule resources from a for_each configuration map when module-dependent attributes are present.

What is the main answer in "How to create optional resources that depend on modules using Terraforms for_each"?

The post shows that optional Terraform resources can be created by filtering the for_each map for elements containing the required schedule attributes, so only configured autoscaling groups get startup and shutdown resources.

What search intent does "How to create optional resources that depend on modules using Terraforms for_each" satisfy?

Learn how to conditionally create Terraform resources that depend on module instances created with for_each.

What topics does "How to create optional resources that depend on modules using Terraforms for_each" cover?

Terraform for_each, optional resources, autoscaling group schedules, module dependencies

Who is "How to create optional resources that depend on modules using Terraforms for_each" useful for?

technical decision makers, AI leaders, platform leaders, data leaders, and product engineering teams