<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Terramate Blog - Medium]]></title>
        <description><![CDATA[Terramate adds code generation, stacks, orchestration, change detection and more to your Terraform environments. - Medium]]></description>
        <link>https://medium.com/terramate?source=rss----467b6143fa7---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Terramate Blog - Medium</title>
            <link>https://medium.com/terramate?source=rss----467b6143fa7---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 15 Apr 2026 01:37:31 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/terramate" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Terramate Bundles vs Terragrunt Stacks]]></title>
            <link>https://medium.com/terramate/terramate-bundles-vs-terragrunt-stacks-a6e4d213ac31?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/a6e4d213ac31</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[terragrunt]]></category>
            <category><![CDATA[terramate]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Tue, 03 Mar 2026 10:47:00 GMT</pubDate>
            <atom:updated>2026-03-03T10:47:00.329Z</atom:updated>
            <content:encoded><![CDATA[<p>What’s the difference between Terramate Bundles and Terragrunt Stacks? While Terragrunt Stacks focus on reusable expert workflows, Terramate Bundles introduce a contract layer designed for both platform engineers and non-experts. This deep comparison explores code generation, environment promotion, AI integration, governance, and developer self-service to help you choose the right Terraform orchestration model at scale.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C0Ha3Pkfbqj2Jmuo0LNgyA.png" /></figure><p>A common question: how do Terragrunt Stacks compare with Terramate Stacks? The naming is misleading — a more accurate comparison is between Terramate Bundles and Terragrunt Stacks.</p><p>This article cuts through the terminology confusion by building from foundational concepts, then directly comparing Terramate Bundles with Terragrunt Stacks.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#terraform-opentofu-tf">Terraform / OpenTofu (TF)</a></h3><p>Let’s do a bit of basics, which might mainly feel like repetition, but it helps to build the hierarchy that we try to simplify with Terramate Bundles.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#tf-resources-and-tf-data-sources">TF Resources and TF Data Sources</a></h3><p>In Terraform, resources and data sources are the smallest units. They define how Terraform communicates with APIs, synchronizes data, and applies actions to</p><p>API-managed resources — primarily cloud APIs, though not exclusively.</p><p>Resources and data sources are implemented in Terraform Providers, which abstract away the complex CRUD operations on underlying APIs.</p><p>Terraform configuration is declarative (HCL). Every resource and data source exposed by a provider can be combined freely in your configuration.</p><p>A typical Terraform configuration spans multiple resources and data sources to define complete cloud services: VPCs, subnets, databases, Kubernetes clusters, workloads, and more.</p><p>These configurations live in a single directory but can be split across multiple files.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#tf-state-and-versions">TF State and Versions</a></h3><p>Every directory containing Terraform configurations needs three things: resource definitions, a backend configuration, and pinned TF and provider versions.</p><p>Terraform tracks infrastructure through state — a record of every resource it has deployed. Before making changes, Terraform refreshes this state against the live cloud API, then calculates what to create, update, or delete. State is stored in a remote backend (typically a cloud object storage bucket), which enables multiple engineers to work on the same infrastructure safely.</p><p>A single git repository can hold multiple such directories, each containing:</p><ul><li>TF configurations (resources, data sources, modules)</li><li>Backend configuration</li><li>TF and provider version pins</li></ul><p>Different tools name these directories differently: Terramate calls them Stacks, Terraform and OpenTofu call them Root Modules, and Terragrunt calls them Units.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#tf-modules">TF Modules</a></h3><p>Modules group related resources for deployment. Like resources in standard Terraform configurations, modules can be called directly. A module consists of four parts:</p><ul><li>TF configuration — resources, data sources, and nested modules</li><li>Input variables — the interface callers use to configure underlying resources</li><li>Output variables — metadata passed from one resource or module to another as inputs</li><li>Required providers — minimum and maximum provider version constraints</li></ul><p>Modules promote reuse and keep configurations DRY. When a module also defines backend and provider configurations, Terraform calls it a Root Module — a naming convention that creates confusion.</p><p>Terramate resolved this by introducing a clearer term: any directory that defines a TF backend and owns a state file is called a stack. Stacks are also not limited to Terraform Root Modules — they support Kubernetes configurations and other tooling.</p><p>When we adopted the term “Terramate Stacks,” no other tool in the space used it. That held true for some time, until Terragrunt Stacks and Terraform Stacks both appeared roughly a year ago.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#terramate-components">Terramate Components</a></h3><p>Terramate Components define templates for generating any type of code or file — YAML , JSON , Markdown , TXT , or HCL . We&#39;ll focus on HCL here.</p><p>Each Component has four parts:</p><ul><li>Metadata — name, description, version, and capabilities.</li><li>Inputs — typed values set when instantiating the Component.</li><li>Code generation templates — output code based on those inputs, using generate_hcl or .tmgen.</li><li>Exports — transformed or additional configuration passed downstream.</li></ul><p>In most cases today, the generated code is Terraform: referencing TF modules, or extending them with additional resources, data sources, or nested modules. This keeps TF modules generic while letting Components handle the specifics — so teams with existing modules can adopt Terramate without rewriting them.</p><p>Components can be instantiated into existing stacks, but they’re designed to work alongside Terramate Bundles, not as standalone units.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#comparing-terramate-components-with-terragrunt-units">Comparing Terramate Components with Terragrunt Units</a></h3><p>With the addition of Terragrunt Stacks, Terragrunt Units are easily reusable. Those Terragrunt Units can be considered to share the same high-level intent as Terramate Components: Reuse TF Configuration. While they are not 1:1 comparable lets focus on some important parts in the following table.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/867/1*MRoBNnSt5HUyB1yKacFqxw.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#terramate-bundles">Terramate Bundles</a></h3><p>The purpose of Terramate Bundles is provide re-usable units that serve as a contract layer between infrastructure producers (experts) and infrastructure consumers (non-experts).</p><p>When enabling non-experts, it is important to hide as much complexity as possible. By pre-configuring the bulk of the configuration and exposing only a limited set of choices to the infrastructure consumers, producers can prevent any non-compliant, non-secure, and non-reliable configuration at all times.</p><p>When focusing on experts, it is important to remain un-opinionated and allow for flexibility without limiting them to specific patterns. There is no single silver bullet, and different teams have different requirements.</p><p>How can Terramate Bundles bring both worlds together: prevent specific actions but allow full flexibility?</p><p>Experts define, create, curate, and maintain repeatable, reusable patterns following best practices while ensuring compliance. Experts set and control the limits that they want to expose to non-expert users.</p><ul><li>TF modules can be fully flexible, exposing all possible options to their callers and taking care of grouping underlying TF configurations.</li><li>Terramate Components can still be flexible and extend existing TF modules with additional safeguards. But they can also only expose a subset of configuration options and hard-code other settings. E.g., always enable encryption at rest and in transit when possible, and do not allow disabling it when using the component; e.g., always enable HA by default when deploying to production &amp; always disable HA for cost control when in pre-prod environments.</li><li>Terramate Bundles define the interface for non-experts in two levels: What values are required to get new infrastructure up and running? And what values shall be adjustable over time or when promoting infrastructure through the environment stages to production.</li></ul><p>Terramate Bundles consist of the following parts:</p><ul><li>Bundle Metadata — defining details about the component, such as a name, description, class, version, and further capabilities.</li><li>Bundle Inputs — A set of inputs of any possible type that can be set when instantiating the component.</li><li>Bundle Exports — that allow the export of transformed and additional configuration details.</li><li>Bundle Stacks — define what Terramate Stacks shall be created or extended and what components shall be called within those stacks.</li></ul><p>So let’s go a bit deeper and see what experts can control and what non-experts can forget about:</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#the-developer-friendly-experience-devx">The Developer Friendly Experience DevX</a></h3><p>When a non-expert user (or an expert ofc) wants to deploy a new type of infrastructure, they call terramate scaffold and can choose an environment to deploy to and a bundle to be deployed into that environment. In an upcoming version, this can even be done by natural language, e.g., “I would like to deploy my new service to staging and connect it to the main database”.</p><p>The following will then be triggered via the Terramate Terminal User Interface (TUI):</p><ul><li>an environment will or can be selected</li><li>the user gets a pre-filled form to deploy a “service” bundle.</li><li>a name for the service will be set or asked for,</li><li>a database matching the criteria will be pre-selected or can be created too in the same step.</li><li>other backing services could be attached or configured if needed.</li></ul><p>Once this form is completed, one or more Bundle Instance YAML files are created in directories that are pre-defined by the expert users who created the Bundle. The non-expert can safely ignore such artifacts.</p><p>Deterministic code generation can automatically be triggered, which will take care of creating a bunch of stacks as defined by the Bundle Stacks definition (by expert users). Multiple directories will be created &amp; initialized, and then code generation will fill each stack with life.</p><p>A commit can also be created if desired, followed by a draft PR that can optionally be synchronized to Terramate Cloud and reviewed in detail. Or the review can be skipped altogether, as all code is guaranteed to be curated in advance and generated from templates that have already been reviewed by the experts. If the preview was generated without failure, the pull request can automatically be marked ready for review and merged.</p><p>If you do not want to use the terminal user interface, all of this can be done with modern tooling, leveraging the AI agent of your choice and running the Terramate MCP server, leveraging the agent skills you use on a daily basis. The AI creates the configuration, and Terramate generates the code, ensuring full compliance by deterministically following what was defined before.</p><p>Expect all of this in by the end of Q1 2026 — we are very close to releasing this full experience, adding the missing AI parts. The manual process is available and ready to be used as of today.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#environment-promotion">Environment promotion</a></h3><p>Terramate Bundles introduce native Environment support. Environments are, for example, pre-production and production, maybe with multiple stages going from development to staging to production. They do not match every company’s view of the world — if you have a different worldview on environment promotion, please reach out and let us know.</p><p>Each Bundle Instance YAML file can be extended to deploy the exact same configuration to any next environment. This can again be done in multiple ways, using the upcoming promote feature of the Terramate Terminal UI, using the AI tool of your choice, or manually editing the YAML file.</p><p>Yes, one YAML configuration controls multiple stacks, multiple Components in each stack, and multiple environments in which those Components can be deployed in.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#comparing-terramate-bundles-with-terragrunt-stacks">Comparing Terramate Bundles with Terragrunt Stacks</a></h3><p>They are not the same. Terragrunt Stacks are meant to be copied and not created from templates by filling in forms. But they do have similarities. Terragrunt Stacks also create new directories and initialize them with Terragrunt Units. The user needs to copy and paste the configuration when promoting it to new environments. This is mainly a feature from Platform Experts for Platform Experts to be used by Platform Experts.</p><p>But let’s try to compare some highlights, which we believe are game changers, when using Terramate Bundles:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/1*VN5YKPwbfspD5eCh7nkOpg.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks/#bundle-roadmap-whats-next">Bundle Roadmap: What’s next?</a></h3><p>Below is a laundry list of capabilities. We are aiming to deliver this list by mid Q2 2026.</p><ul><li>✅ Terramate Bundles, Components and Environments are fully available</li><li>✅ AI-based scaffolding or reconfiguration using your tools and the terramate agent skills</li><li>✅ terramate scaffold allows to scaffold new infra with bundles for non-experts</li><li>✅ manual reconfiguration of existing bundles (edit the YAML → generate → apply → done)</li><li>✅ manual environment promotion (edit the YAML → generate → apply → done)</li><li>✅ advanced types system for better documentation, improved auto-completion in IDEs</li><li>🚧 fully support all new types and auto-completion in the language server</li><li>🚧 improved AI workflows to generate Components and Bundles on scale</li><li>🚧 full AI support in the Terminal User Interface or on Terramate Cloud to prompt your infrastructure together</li><li>🚧 improved Terminal User Interface to scaffold new infrastructure, reconfigure existing and promote everything through environments</li><li>🚧 full support for Bundles, Components on Terramate Cloud</li><li>track versions instantiated and detect required updates for Bundles, Components, TF Modules, and TF Providers</li><li>track environment promotion of all parts of your infrastructure</li><li>Bundles, Components Registry to</li><li>🚧 more features for Bundle and Component authors to access internal data structures and simplify code generation</li><li>🚧 your custom feature that will make your life easier → talk to us, share your pain, be part of the journey to make your team even more successful ;)</li></ul><p>Terramate Bundles and Terragrunt Stacks are not the same abstraction. Terragrunt improves how experts structure and reuse Terraform modules. Terramate Bundles introduce a contract layer on top — separating configuration from implementation, enabling environment promotion, and making self-service viable without giving up control.</p><p>If you want the broader picture beyond this specific comparison, read our article <a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/"><em>“Terramate vs Terragrunt: A 2026 Comparison”</em></a>. It dives deeper into architectural trade-offs, performance, change detection, environment promotion, AI workflows, and long-term maintainability at scale.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a6e4d213ac31" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/terramate-bundles-vs-terragrunt-stacks-a6e4d213ac31">Terramate Bundles vs Terragrunt Stacks</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Terramate vs Terragrunt: A 2026 Comparison]]></title>
            <link>https://medium.com/terramate/terramate-vs-terragrunt-a-2026-comparison-88ec043d79a7?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/88ec043d79a7</guid>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[terragrunt]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Tue, 03 Mar 2026 10:40:23 GMT</pubDate>
            <atom:updated>2026-03-03T10:40:23.219Z</atom:updated>
            <content:encoded><![CDATA[<p>How does Terramate compare to Terragrunt in 2026? While Terragrunt pioneered DRY Terraform orchestration, modern Infrastructure-as-Code demands more: scalable change detection, built-in environment promotion, AI readiness, and developer self-service. This in-depth comparison explores architecture, performance, output sharing, observability, and long-term maintainability — so you can choose the right orchestration tool for Terraform and OpenTofu at scale.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-M6TIsBl4hxHc0HQiUCQaQ.png" /></figure><p>The number one question we get asked from prospects is how Terramate compares to Terragrunt. This is our opinionated take.</p><p>While Terragrunt was and is a great tool and was the go-to tool for the better part of the last decade, the challenges of 2026 look different from those of five years ago. Infrastructure systems are larger, teams are more distributed, AI-generated code is on the rise, and platform engineering has become a discipline in its own right. The question is no longer just how to keep stacks DRY — it’s how to maintain clarity, performance, auditability, and evolvability at scale. This is where the design philosophies of Terragrunt and Terramate begin to diverge, and why we believe Terramate is the more future-proof approach.</p><p>So if you use Terragrunt today or consider starting with it, please check out how we see the comparison here at Terramate and why we believe we often are a better choice. Also, please feel free to disagree or point out what we missed.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#quick-primer-on-terramate">Quick Primer on Terramate</a></h3><p>If you have never heard of Terramate, let us share a quick list of capabilities before going deeper into the actual user experience.</p><p>Terramate offers an Open Source CLI and a Cloud Platform, which, in combination, provide you with the best IaC experience you can get:</p><p>The Open Source CLI gives every engineer:</p><ul><li>Environment management with built-in promotion across stages</li><li>Stack orchestration with intelligent change detection</li><li>Code generation to eliminate boilerplate and enforce consistency</li><li>Developer self-service so teams ship without bottlenecks</li><li>AI-readiness via agent skills and an MCP server</li></ul><p>Terramate Cloud layers enterprise-grade capabilities on top — with close to zero additional setup:</p><ul><li>Pull Request Change Previews and Collaboration</li><li>Deployment Management and Audibility of Changes</li><li>Drift Detection and Drift Reconciliation</li><li>Resource Browser and Resource Policy Checks</li><li>Notifications and alerting on failures, violations, and successes</li><li>Dashboards, Analytics, and Reporting</li><li>AI to support understanding the complexity of failures and changes</li></ul><p>Now, let us take a look at the actual user experience here. If you like to dive deeper, feel free to <a href="https://terramate.io/demo">schedule a call</a>.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#onboarding-experience-close-to-zero-migration-effort">Onboarding experience: close to zero migration effort</a></h3><p>Onboarding existing OpenTofu, Terraform, or Terragrunt configurations into Terramate takes a single command. Running terramate create --all-terraform (or --all-terragrunt for Terragrunt projects) scans every relevant directory and creates a stack.tm.hcl file with a stack {} block and a unique UUID-based ID.</p><p>Once stacks are initialized, most Terramate features are available immediately, including full orchestration with Git-based change detection, triggered via terramate run --changed -- {any-command} . No code changes required.</p><p>Terragrunt takes a similar approach: each directory needs a terragrunt.hcl file, which can be empty. Terramate&#39;s equivalent requires at minimum an empty stack {} block and, by default, assigns an ID that unlocks additional benefits covered later.</p><p>The practical difference is small. Terramate’s auto-detection gives it a slight onboarding edge, but at scale, the gap narrows.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/966/1*W63d4oTfVVBnz3wwC5zwaA.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#keeping-stacks-dry-configuration-complexity-and-long-term-maintainability">Keeping stacks DRY — configuration complexity and long-term maintainability</a></h3><p>Keeping configuration DRY (don’t repeat yourself) is one of the goals in both tools. The design decisions are fundamentally different here:</p><p>Terragrunt keeps configuration DRY by leveraging Terraform Modules that can be invoked across multiple stacks, making root modules reusable. Those modules are then initialized in temporary directories, and commands are executed in the temporary directories, wrapping OpenTofu or Terraform, passing different input values defined in the terragrunt.hcl via TF_var_* environment variables. This prevents running native tofu or terraform commands in the stack and always requires running terragrunt as a wrapper.</p><p>Once a Terragrunt stack uses a reusable module, no further Terraform or OpenTofu configuration files can be dropped into the stack, but always need to be added to the shared module.</p><p>Configuration values can be loaded by searching additional configuration files up the hierarchy. Maintaining the list of files to read makes the configuration less DRY as a side effect. Introducing more dryness by including a file that holds the configuration of what configuration files to load will lead to decreasing the readability of each stack’s configuration, as it gets harder to maintain a mental overview of where values are coming from, where to change values and what the impact of such a change will be.</p><p>This complexity has not only mental overhead but also performance impact, which also Terramate suffers from when running the Terragrunt Change Detection Integration.</p><p>Terramate keeps configuration DRY by allowing to define templates that deterministically generate actual code. This code generation can either be inherited in the hierarchy or packaged into Terramate Components.</p><p>Terramate always has generated artefacts living in the stacks, which are not meant to be manually edited. Any additional files inside of stacks are not touched by terramate , so adding native configuration and running native terraform or tofu commands is possible at any point in time. Each stack always contains readable, reviewable HCL configuration.</p><p>Configuration values are inherited in the hierarchy, and there is no need to maintain a list of files that need to be loaded to access shared configuration. In addition, changing values of global variables will lead to changes in generated files, which can easily be identified using normal git operations. It is easier to maintain the mental model of the overall configuration and overwrite specific values. Terramate also offers changing values in complex objects without the need to clone the full object, thanks to a feature called <a href="https://terramate.io/docs/cli/reference/variables/globals#labeled-globals">Labeled Globals</a>: Setting globals &quot;terraform&quot; &quot;provider&quot; &quot;aws&quot; { version = &quot;6.33.0&quot; } will only change the version of the AWS provider while keeping other provider configurations untouched.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/862/1*Q-d6ic5-zWT12f4H4Nql8Q.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#performance">Performance</a></h3><p>Terragrunt had some performance regressions for quite some version numbers, improved a bit in latest releases, but overall can also be used with bigger setups.</p><p>Terramate’s Terragrunt integration uses Terragrunt as a library under the hood, so any Terragrunt performance issue flows through to Terramate, most notably in change detection and dependency resolution. The core problem: change detection must repeatedly scan every stack for chained includes, regardless of what actually changed. This is the equivalent of a full table scan on every run. The result is slower change detection compared to using Terraform or native Terramate alone.</p><p>Terramate’s file-generation approach adds some build-time overhead, plus optional runtime overhead if safeguards are enabled to verify generated files are current. However, change detection in this mode is highly optimized. It relies only on changes surfaced by the Git integration, with no need to scan the full file tree.</p><p>One option for speeding up Terragrunt workflows is to generate the final Terragrunt files via Terramate. But at that point, removing Terragrunt entirely may require similar effort and yield a more maintainable result long-term.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#output-vs-information-sharing">Output vs Information sharing</a></h3><p>Terragrunt pioneered output sharing to solve a core problem when splitting monolithic Terraform code: how do you access cloud resource IDs that are only known after an apply? In a monolith, Terraform resolves these dependencies at apply time. In a multi-stack setup, that option disappears. Terragrunt’s solution is stack dependencies: one stack’s outputs become another stack’s inputs.</p><p>This creates a real orchestration burden. The stack providing outputs must be fully applied before dependent stacks can even be planned, forcing multiple pull requests to be merged in strict order.</p><p>Terramate supports this workflow but goes further: it can read shared data from multiple sources beyond Terraform or OpenTofu outputs. The one-time setup of a sharing backend adds minimal overhead while unlocking flexibility in how and where data is sourced.</p><p>Both Terramate and Terragrunt support mocked output values for data not yet available. Mocks appear in plan previews as placeholders; once real data exists, the plan must be regenerated.</p><p>An alternative and even better Terraform -native approach is to use remote state lookups leveraging the <a href="https://developer.hashicorp.com/terraform/language/state/remote-state-data">terraform_remote_state</a> data source. This also requires the first stack to be applied to access the data but both stacks can actually be planned at the same time, when actually reading the remote state data source is postponed to the apply time using depends_on . Multiple depending stacks can now be managed in a single initial pull request but changing outputs over time can lead to the initial problems.</p><p>Terraform also supports data sources for specific resources, those again can be postponed to be read at apply time for initial deployments and do not cause issues when adding additional resources to the game. The problem here is how to know what filters to use in such data sources: Terramate information sharing to the rescue.</p><p>Terramate information sharing is mainly supported within bundles as of today. Bundles allow to control what stacks shall be generated, and what Components shall be used to generate code into such stacks. More on Bundles further down.</p><p>Every Terramate Bundle gets a UUID when instantiated in a repository. You can use this UUID to tag cloud resources, filter data sources, and directly target specific resources without guessing at filter logic. The UUID is also accessible from other bundles or outside a bundle entirely. Each Bundle additionally exposes a class and a human-friendly alias as alternative ways to reference the same UUID.</p><p>This shared context eliminates the need for complex tagging strategies and brittle filter configurations. See <a href="https://github.com/terramate-io/terramate-catalyst-examples">https://github.com/terramate-io/terramate-catalyst-examples</a> for working examples.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/865/1*sY0ph33GaMP8boP6FZcCQQ.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#end-to-end-experience-observability-and-auditability-with-terramate-cloud">End-to-end Experience, Observability and Auditability with Terramate Cloud</a></h3><p>Terramate offers an end-to-end experience to automate the IaC experience and run workflows anywhere.</p><p>To run IaC on scale and to enable self-service, it is important to understand the state of your infrastructure at any point in time.</p><p>Terramate CLIs orchestration features and the available automation blueprints for the main CI/CD providers like GitLab Actions, GitLab CI, or Bitbucket Pipelines allow for an easy start into full end-to-end automation.</p><p>Once automation kicks in, all cloud resources are created and maintained by Service Accounts or assume IAM roles and cloud audit logs do reflect only changes but not the correct actor. Terramate Cloud keeps track of collaborators requesting or deploying changes and thus creates a full auditability of changes over time, and can assign the correct actor to each and every change.</p><p>Terramate Clouds’ advanced preview process allows for faster reviews and highlights failures and risky operations.</p><p>Since Terramate Cloud is our commercial offering let’s not get into too many details here as we want to concentrate on comparing the different approaches: There is not much difference here when comparing the CLIs, as we fully support Terragrunt also on Terramate Cloud in addition to Terraform and OpenTofu.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#ai-readiness-of-terramate">AI-Readiness of Terramate</a></h3><p><a href="https://github.com/terramate-io/terramate-mcp-server">Terramates MCP Server</a> allows to combine local development with globals state in Terramate Cloud.</p><p>When Terramate Cloud detected a drift, the MCP server can help to accept the cloud state and adjust the code to reflect the new desired state. It can also trigger drifted stacks to auto-reconcile the drift by redeploying the desired state in code.</p><p><a href="https://github.com/terramate-io/agent-skills">Terramate Agent Skills</a> allow to maintain a Terraform, OpenTofu, and Terramate code base in modern AI environments.</p><p>We think AI with different audiences by design. Experts can leverage AI to create a contract layer on top of Terraform with reusable Bundles and Components that follow best practices, are compliant and enforce specific settings on scale. Non-expert users can leverage AI to configure existing, curated Terramate Bundles to deploy cloud services, like databases, Kubernetes workloads, etc, on scale fully safeguarded by the bundle interfaces the experts provided in the first place.</p><p>Full control for experts and full power for non-experts on a day-2-day use. Curated and configured new infrastructure can be set up to run a review-less workflow, leading to faster deployments of infrastructure and applications.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#environment-promotion">Environment Promotion</a></h3><p>Terragrunt supports template reuse across environments via Stacks or Units, but the process is largely manual, copying files and configurations between environments.</p><p>Terramate Bundles enforce a strict separation between code and configuration. A Bundle’s YAML configuration only needs three things: a reference to the Bundle source, a version, and the desired configuration values. All implementation details, such as directory structure, stack layout, Component wiring are encapsulated inside the Bundle itself.</p><p>Deploying the same Bundle to multiple environments is straightforward. All environment configurations live in a single file. New environments can be added by duplicating a configuration block or using the Terramate CLI’s TUI, a form-based interface that eliminates manual YAML editing.</p><p>With Terramate Bundles, environment promotion is a solved problem.</p><p>We will publish a follow-up article going into details about <a href="https://terramate.io/rethinking-iac/terramate-bundles-vs-terragrunt-stacks">how Terragrunt Stacks and Terramate Bundles differ.</a></p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#going-beyond-terraform-and-opentofu">Going beyond Terraform and OpenTofu</a></h3><p>Terramate is not limited to Terraform or OpenTofu. Terragrunt, being a wrapper for either, can only work in such environments.</p><p>Terramate can orchestrate any commands, including but not limited to terraform , tofu , helm , kubectl , kustomize .</p><p>Terramate can generate files of any type: HCL , JSON , YAML , etc. Allowing to also template CloudFormation templates, values YAML files and others.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#ease-of-use-also-for-non-experts">Ease of use (also for non-experts)</a></h3><p>Terragrunt helped paper over Terraform’s early shortcomings, but many of those fixes are now built into Terraform and OpenTofu natively. Terramate addresses what remains: the problems that still slow teams down every day, across both the Terramate CLI and Terramate Cloud.</p><ul><li>Terraform state and backend configuration — State management is no longer a blocker. Both Terraform and OpenTofu support state migrations in code. Terramate lets you template backend configuration at scale and uses a Stack ID (not the stack’s path) as the state storage key, so renaming or restructuring directories never breaks state. Large state files can be split into stacks to reduce blast radius and speed up deployments with Change Detection.</li><li>Provider configuration — Dynamic provider configuration is already supported via templates. Terramate Bundles and Components will extend this further in upcoming releases. Rolling out provider updates scoped to a single environment or subsystem is fully solved today.</li><li>Keeping code DRY — Code generation and Terramate Components eliminate duplication without sacrificing clarity.</li><li>Environment promotion — With Terramate Bundles, promoting across environments is a single configuration file change.</li><li>Separation of configuration and code — Terramate is built by platform engineers for platform engineers. Experts define and templatize the infrastructure; non-experts consume it safely. One tool, two audiences.</li><li>AI readiness — Build reusable building blocks now and let AI configure them, rather than generate unbounded infrastructure code. Maintainability and speed are not a trade-off.</li></ul><h3><a href="https://terramate.io/rethinking-iac/terramate-vs-terragrunt-a-2026-comparison/#developer-self-service-layer-for-agentic-infrastructure">Developer self-service &amp; layer for agentic infrastructure</a></h3><p>Terragrunt was the go-to solution for years and remains a great tool. But the landscape has shifted. Terramate addresses the gaps that Terragrunt leaves open. Most importantly, self-service capabilities to enable non-expert developers and a built-in observability layer that tracks infrastructure changes at scale, keeping you audit-ready and giving you the data to move KPIs in the right direction.</p><p>We’re also building for what’s next: AI-generated infrastructure code is already producing massive volumes of HCL. Our answer is to let experts leverage AI to generate reusable patterns once, package those as Bundles, and then let every engineer use AI to configure them — preventing slop at the source and turning AI-generated Terraform from a maintenance problem into a force multiplier.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=88ec043d79a7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/terramate-vs-terragrunt-a-2026-comparison-88ec043d79a7">Terramate vs Terragrunt: A 2026 Comparison</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Terramate Bundles: The Contract Layer Terraform Never Shipped]]></title>
            <link>https://medium.com/terramate/terramate-bundles-the-contract-layer-terraform-never-shipped-a49c2607861a?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/a49c2607861a</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[terraform]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Fri, 27 Feb 2026 10:45:14 GMT</pubDate>
            <atom:updated>2026-02-27T10:45:14.312Z</atom:updated>
            <content:encoded><![CDATA[<p>Terraform modules were designed for code reuse, not for governing infrastructure at scale across teams, environments, and repositories. Terramate Bundles introduce the missing contract layer between platform teams who define standards/patterns and developers who provision infrastructure in self-service, with built-in governance, directory structure, environment promotion, and lifecycle management out of the box.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wzLCNWYxnh69lhxQ9dRxXg.png" /></figure><p>You have 14 teams, 80 repositories, and a Confluence page titled “How to create an S3 bucket” that nobody reads. Your shared Terraform modules started clean. Then one team starts copying the module to adjust it to their needs, another adds a bunch of missing resources, and so on. Now you need to roll out a tagging strategy across every S3 bucket in every environment, and you’re looking at pull requests in 40 repositories, each with slightly different directory layouts, variable names, and module versions.</p><p>This is not a tooling problem. It’s a missing abstraction.</p><p>Terraform modules solve code reuse. They were never designed to be a contract between a platform team and the rest of engineering. They don’t enforce directory conventions, don’t manage environment promotion, don’t track where they’re used, and don’t constrain what developers can configure. Modules give you building blocks. What you actually need is an interface boundary. A layer that lets platform teams ship vetted, governed infrastructure patterns that developers consume without needing to understand or modify the underlying Terraform. That’s what Terramate Bundles are. Not a replacement for modules, but the contract layer that sits above them: platform-team-owned, self-service-ready, and opinionated by design.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-governance">Built-in Governance</a></h3><p>A Bundle is a platform-team-owned definition of how a piece of infrastructure should be provisioned. It encodes best-practice patterns such as resource naming, security configuration, cost controls, compliance requirements and exposes only a limited, vetted set of configuration options to the end user.</p><p>This is a deliberate constraint. When a developer creates an S3 bucket through a bundle, they don’t choose the encryption algorithm, the lifecycle policy, or the logging configuration. The platform team already made those decisions. The developer picks a name, an environment, and maybe a retention period. Everything else is locked.</p><p>The result is that every resource provisioned through Bundles meets your organization’s reliability, security, budget, and compliance goals by default. Not because developers read the wiki. Because the interface doesn’t let them do it wrong.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-directory-structure">Built-in Directory Structure</a></h3><p>If you’ve operated IaC across multiple repositories and teams, you know the entropy. One team nests everything under terraform/ . Another uses infra/production/ . A third uses yet another structure. When someone new joins, they spend a day just figuring out where things live.</p><p>With Terramate Bundles, the directory structure is part of the contract. The platform team defines the layout pattern, and every Bundle scaffolds into it automatically. For example, a Bundle can enforce the convention:</p><pre>define bundle stack &quot;s3&quot; {<br>  metadata {<br>    path = &quot;/infra/${bundle.environment.id}/{bundle.input.account.value}/s3/${tm_slug(bundle.input.name.value)}&quot;<br>    ... <br>  }<br>}</pre><p>When a developer provisions a new S3 bucket called my-bucket in the dev environment, the infrastructure code is scaffolded into infra/dev/web-account/s3/my-bucket . Every time. In every repository. For every team.</p><p>This means you can look at any repository in your organization and immediately know where to find the Terraform for a specific resource. No guessing. No Confluence page. The structure is the documentation.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-environment-promotion">Built-in Environment Promotion</a></h3><p>Promoting infrastructure changes between environments is one of those problems that sounds simple and never is. With vanilla Terraform, teams end up copying entire directory trees, duplicating .tfvars files, or wrestling with workspaces that were never designed for multi-environment promotion. The result is drift between environments that&#39;s invisible until something breaks in production.</p><p>Terramate Bundles treat environment promotion as a first-class operation. Developers use terramate ui , a terminal interface that lets you promote changes from one environment to another, adjust environment-specific settings, and preview the diff before applying. Under the hood, it updates the relevant variables and regenerates the Terraform code. No manual file copying. No editing raw HCL in three directories.</p><pre>apiVersion: terramate.io/cli/v1<br>kind: BundleInstance<br>metadata:<br>  name: my-bucket<br>  uuid: 6586fa6a-d25a-4d16-9950-d79c226add76<br>spec:<br>  source: /bundles/acme.com/s3/v1<br>  inputs:<br>    <br>    name: my-bucket<br>    versioning_enabled: true<br>    retention_days: 30<br>    <br>    terraform_modules:<br>      terraform-aws-modules/s3-bucket/aws:<br>        source: terraform-aws-modules/s3-bucket/aws<br>        version: 5.9.1</pre><pre># environment-specific overrides<br>environments:<br>  dev:<br>    inputs:<br>      versioning_enabled: false<br>  staging:<br>    inputs:<br>      versioning_enabled: true<br>      retention_days: 90<br>  production:<br>    inputs:<br>      versioning_enabled: true<br>      retention_days: 365</pre><p>The same overrides can be managed directly in YAML or HCL files, making it machine-friendly for CI pipelines and automation. The key shift: environment configuration lives in a structured format that tools can read and modify, not scattered across .tfvars files that only humans can parse.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-maintainability">Built-in Maintainability</a></h3><p>Here’s the scenario that breaks most IaC setups at scale: you need to roll out a change to existing infrastructure. Not provide something new, but update something that’s already deployed everywhere.</p><p>Say your security team mandates a new tagging strategy. Every resource needs a cost-center and data-classification tag. With vanilla Terraform, this means updating hundreds of resource configurations across dozens of repositories. You&#39;re writing migration scripts, opening mass pull requests, and hoping each team&#39;s module version is compatible with the change.</p><p>With Terramate Bundles, you update the bundle definition once. Then you can see exactly which repositories, teams, and environments are running which bundle versions — and upgrade them in a targeted manner. Update all s3-bucket bundles in dev environments first. Verify. Promote to staging. Then production. The bundle version graph gives you the visibility and control that raw module references never provided.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-ai-safety-layer">Built-in AI Safety Layer</a></h3><p>Generative AI is accelerating infrastructure code production. That’s the good news. The bad news: every LLM-generated Terraform file looks slightly different: different resource names, different variable conventions, different provider configurations. Often, it is also a function of the expertise level of the LLM-user. The code might be syntactically correct, but it doesn’t match your organization’s patterns. At scale, this creates a maintenance nightmare that compounds faster than any team can review.</p><p>While this can be partially mitigated by using agent-skills such as the <a href="https://github.com/terramate-io/agent-skills">Terramate agent-skills</a> for Terraform and OpenTofu, Bundles solve this by constraining the generation surface. When an AI agent provisions infrastructure through a bundle, it doesn’t write raw Terraform. It fills in bundle inputs. The underlying code is deterministically generated, i.e., exactly the same way every time, matching your organization’s standards. You can integrate bundles directly with coding agents like Cursor, Codex, or Claude Code, giving your agentic workflows the same guardrails your human developers get.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-standardization">Built-in Standardization</a></h3><p>Without bundles, developers have to decide how and where to use modules, structure repositories, how to name cloud resources, etc. Eventually, there’s a gap between the standardization that modules provide and everything else.</p><p>Bundles enforce standardization at the generation layer. The platform team controls which dependency versions are used, which configuration options are exposed, and how the code is structured. Every bundle-generated stack looks the same. Not because developers are disciplined, but because the system doesn’t produce anything else.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-review">Built-in Review</a></h3><p>If developers write raw Terraform, every pull request needs a review. Someone has to verify the resource configuration, check naming conventions, validate that the right provider version is pinned, and confirm the directory structure and state configuration are correct. That review burden scales linearly with your team count.</p><p>With Bundles, the code and its possible configurations are reviewed once — when the platform team publishes the bundle in the first place. After that, PRs that contain only bundle-generated configuration can be auto-merged. The review happened upstream, at the contract definition. Not downstream, at every consumption point.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-lifecycle-management">Built-in Lifecycle Management</a></h3><p>Day-2 operations in Terraform are often manual and fragile. Upgrading a provider version means touching every configuration that uses it. Rotating a pattern means coordinating across teams. There’s no built-in concept of “upgrade all instances of this pattern to the next version.”</p><p>Bundles make lifecycle management a version upgrade workflow. Because the bundle owns the definition of dependency versions, upgrading the provider, the module, or the underlying resource configuration is a single bundle version bump. Roll it out to dev first. Then staging. Then production. Target by environment, by team, by repository. Day-2 operations become as straightforward as day-1 provisioning.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#built-in-visibility">Built-in Visibility</a></h3><p>If you use Terraform modules today, answering “where is this module used?” requires grep, tribal knowledge, or both. Answering “which version of this module is running in production across all teams?” is harder. Answering “which teams haven’t upgraded to the version with the security fix?” is nearly impossible without custom tooling.</p><p><a href="https://terramate.io/">Terramate Cloud</a> provides a single control plane that tracks bundle usage across all environments, teams, and repositories. You can see which bundle versions are deployed where, which components and providers are in use, and which teams are running outdated versions — all from one dashboard. The visibility that any module registry is lacking.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#the-layer-youve-been-building-by-hand">The Layer You’ve Been Building by Hand</a></h3><p>Every mature platform team ends up building some version of this. Internal CLIs that scaffold directories. Wrapper scripts that manage environment promotion. Dashboards that track module usage. Review policies that try to enforce standards through process.</p><p>Terramate Bundles are that layer — productized. A contract between the platform team that defines how infrastructure should be provisioned and the developers who provision it. If you’re scaling IaC beyond a single team and you’re still relying on modules, READMEs, and good intentions, you’re missing the abstraction that actually matters: not code reuse, but organizational control.</p><p>Modules are building blocks. Bundles are the interface.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-bundles-the-contract-layer-terraform-never-shipped/#give-it-a-go">Give it a go</a></h3><p>Terramate Bundles are available now as part of the open-source <a href="https://github.com/terramate-io/terramate">Terramate CLI</a>. Check out our <a href="https://github.com/terramate-io/terramate-catalyst-examples">example repo</a> to see Bundles live in action. And learn how Bundles technically work.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a49c2607861a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/terramate-bundles-the-contract-layer-terraform-never-shipped-a49c2607861a">Terramate Bundles: The Contract Layer Terraform Never Shipped</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing Terramate Agent Skills]]></title>
            <link>https://medium.com/terramate/introducing-terramate-agent-skills-750dab55400d?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/750dab55400d</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[terraform]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Fri, 20 Feb 2026 11:24:09 GMT</pubDate>
            <atom:updated>2026-02-20T11:24:09.439Z</atom:updated>
            <content:encoded><![CDATA[<p>We’ve released an open library of Agent Skills to help teams build and manage infrastructure with Terramate, Terraform and OpenTofu faster with AI.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VrUINScayLJBrO5ipwnihw.png" /></figure><h3>Agent Skills</h3><p>Today, we’re happy to announce the <a href="https://github.com/terramate-io/agent-skills">Terramate Agent Skills</a> for Terraform, OpenTofu and Terramate, a collection of best practices when managing IaC at scale.</p><p>These skills are opinionated best practices we collected since we started Terramate and help writing, maintaining, automating and testing your IaC faster with agents such as Opencode, Cursor, Codex and Claude Code. They also provide another layer of integration with Terramate Cloud via Terramate CLI and Catalyst, in addition to the <a href="https://github.com/terramate-io/terramate-mcp-server">Terramate MCP Server</a>.</p><h3>What Skills are available?</h3><p>The library provides two packages: Terraform and OpenTofu best practices as well as Terramate best practices that can be used in tandem or individually.</p><h3>Terramate Best Practices</h3><p>Terraform and OpenTofu best practices and guidelines. Contains 37 rules across 10 categories, prioritized by impact.</p><p><strong>Use when:</strong></p><ul><li>Writing new Terraform modules or configurations</li><li>Implementing infrastructure patterns (AWS, GCP, Azure)</li><li>Reviewing code for security and reliability issues</li><li>Optimizing state management and performance</li><li>Refactoring existing Terraform code</li></ul><p><strong>Categories covered:</strong></p><ul><li>Organization &amp; Workflow (Critical)</li><li>State Management (Critical)</li><li>Security Best Practices (Critical)</li><li>Module Design (High)</li><li>Resource Organization (Medium-High)</li><li>Variable &amp; Output Patterns (Medium)</li><li>Language Best Practices (Medium)</li><li>Provider Configuration (Medium)</li><li>Performance Optimization (Low-Medium)</li><li>Testing &amp; Validation (Low)</li></ul><h3>Terraform and OpenTofu Best Practices</h3><p>Terramate CLI, Cloud, and Catalyst best practices and usage guides. Contains 15+ rules across 8 categories for stack management, orchestration, code generation, and Cloud integration.</p><p><strong>Use when:</strong></p><ul><li>Creating and organizing Terramate stacks</li><li>Orchestrating commands across multiple stacks</li><li>Create Catalyst bundles and components from existing Terraform modules</li><li>Scaffold complex multi-state architectures using Catalyst</li><li>Using code generation to keep configurations DRY</li><li>Integrating with Terramate Cloud for observability</li><li>Creating Catalyst components and bundles</li><li>Setting up CI/CD workflows with Terramate</li></ul><p><strong>Categories covered:</strong></p><ul><li>CLI Fundamentals (Critical)</li><li>CLI Orchestration (High)</li><li>CLI Code Generation (High)</li><li>CLI Configuration (Medium-High)</li><li>Terramate Cloud (Medium-High)</li><li>Terramate Catalyst (Medium)</li><li>CI/CD Integration (Medium)</li><li>Advanced Patterns (Low-Medium)</li></ul><h3>Installation</h3><pre>npx skills add terramate-io/agent-skills</pre><h3>Usage</h3><p>Skills are automatically available once installed. The agent will use them when relevant tasks are detected.</p><p><strong>Examples:</strong></p><pre>Create a S3 Bucket from the available Terramate Bundles</pre><pre>Fix the drifted stacks in this repository</pre><pre>Refactor this Terraform configuration to use modules</pre><p>Check out the <a href="https://github.com/terramate-io/agent-skills">agent-skill</a> repository. Also, please don’t hesitate to reach out for questions or suggestions. The best place to reach us is the <a href="http://terramate.io/discord">Terramate community on Discord</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=750dab55400d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/introducing-terramate-agent-skills-750dab55400d">Introducing Terramate Agent Skills</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Separating Configuration from Code with Terramate Catalyst]]></title>
            <link>https://medium.com/terramate/separating-configuration-from-code-with-terramate-catalyst-5566d0dfddce?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/5566d0dfddce</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Wed, 18 Feb 2026 11:41:44 GMT</pubDate>
            <atom:updated>2026-02-18T11:41:44.443Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-WMaeFRX_zRy69wf-w0tJA.png" /></figure><p>If you’ve ever tried to “make Terraform easy for developers,” you already know how this story goes.</p><p>You start with good intent: self-serve infrastructure, paved roads, and less ticket-driven ops. Then reality sets in. Every new team needs a slightly different variation. Every environment needs a slightly different exception. And suddenly, the IaC repositories — mission-critical codebases in the company — are slowly but surely spinning out of control.</p><p>This post is part of a short series on what makes <strong>Terramate Catalyst</strong> unique — and why we think it’s the new efficient frontier in Infrastructure as Code development.</p><p>If you are new to Terramate Catalyst, we recommend you read our post “A technical introduction to Terramate Catalyst.”</p><h3>The core thesis for Terramate Catalyst</h3><p>In most engineering organizations, only a few experts, such as platform and infrastructure teams, truly know how to deploy and manage production-grade infrastructure with IaC tools such as Terraform and OpenTofu in the right way.</p><p>This is because IaC is not accessible to most developers. You have to learn both HCL and the particulars of the cloud, which many developers simply don’t want to do — and they probably shouldn’t.</p><p>Instead of forcing Terraform upon the developers, the idea is to create a clear interface between <em>what developers configure</em> and <em>what platform teams implement and control.</em> So that the whole organization benefits from the experts’ capabilities.</p><h3>IaC not accessible — what does that mean?</h3><p>To use infrastructure, application developers need to know two things:</p><ol><li>Terraform / HCL</li><li>How cloud infrastructure actually works</li></ol><p>Terraform has a steep learning curve: HCL is yet another language to learn, and concepts like state, providers, and the plan/apply lifecycle introduce significant cognitive overhead.</p><p>The domain itself is just as complex, because the hardest part is understanding <em>how clouds actually work</em>:</p><ul><li>Choosing the right services and configuring them correctly</li><li>Ensuring secure-by-default setups (networking, IAM, encryption)</li><li>Staying within cost and quota constraints</li><li>Implementing reliable backups and recovery strategies</li><li>Putting the right monitoring and alerting in place</li></ul><h3>The downstream symptoms are painfully predictable</h3><p>If you’ve spent time in the Terraform ecosystem, you’ve seen the same complaints over and over:</p><p>Teams start with a clean setup. Then it grows. Then it turns into a mess of modules, wrappers, copy/paste sprawl, and siloed knowledge.</p><p>Fast forward a couple of years, and the situation probably looks like this:</p><ul><li>Creating new infrastructure takes days or weeks because standards are hard to follow or barely exist</li><li>Simple configuration changes require code changes in many places, becoming ever harder to maintain</li><li>Version management: Provider, Terraform Module, or Terraform/OpenTofu upgrades that ought to be simple are becoming ever more challenging to roll out.</li><li>“Self-service,” while often requested and promised, still creates a lot of friction between teams</li><li>Engineers get frustrated, burn out, and leave because the work stops being fun</li></ul><h3>Contemporary solutions — and why they still hurt</h3><p>Platform teams have tried to solve this for years. The patterns are familiar. The failure modes are too.</p><h3>Terraform modules: an abstraction that still requires in-depth Terraform expertise</h3><p>Terraform modules are the default solution. And they work, until they don’t.</p><p>To use a module well, you need to know both the module and the underlying Terraform: the dreaded 200% problem. Experts don’t mind, but what about your developers?</p><p>The tradeoff shows up fast:</p><ul><li>If the module is <strong>opinionated</strong>, teams fight it and fork it.</li><li>If the module is <strong>flexible</strong>, it becomes a kitchen sink of variables.</li><li>If the module is shared across teams, every change becomes political.</li></ul><p>And the worst part: consumers often don’t really know what’s inside. They call the module, get outputs, and hope the module author didn’t bake in a surprise.</p><p>Modules are a great way to reuse code. But they are not a great way to build an interface contract between teams.</p><h3>Terragrunt: more power, more surface area</h3><p>Terragrunt tries to fix the “module composition” problem. It helps with DRY, environment wiring, orchestration, and one-off scaffolding.</p><p>But it inherits all the modules’ tension — and adds its own layer of complexity.</p><p>You still end up with:</p><ul><li>inconsistencies across multiple repos</li><li>implicit behavior that only the expert truly understands</li><li>configuration logic that turns into a second programming language</li><li>brittle coupling between “what teams want” and “what the platform allows”</li></ul><p>It’s not separation. It’s more glue. And the application developers have to learn yet another new technology that still isn’t easily accessible.</p><h3>Scaffolding Engines and IDPs: great on day 1, painful on day 200</h3><p>Scaffolding template engines such as Cookiecutter or Backstage’s Software Templates look great in demos.</p><p>You generate a repo. You get a working baseline. Everyone’s happy.</p><p>Then day 2 happens:</p><ol><li>teams modify the generated code</li><li>the template evolves</li><li>drift becomes permanent</li><li>upgrades and day 2 are tedious</li></ol><p>Blueprints optimize for creation. Real platforms need to <strong>create</strong> and <strong>maintain</strong>.</p><p>Ultimately, this approach makes the platform team’s job easier. But this only solves half of the problem. Developers are still exposed to generated Terraform that they need to master. And we are back to the challenges of a steep learning curve for developers.</p><h3>A new approach: Bundles that separate configuration from code</h3><p>Catalyst takes a different approach: <a href="https://terramate.io/docs/catalyst/concepts/bundles">**Bundles</a>,** the unit of reuse for application developers.</p><p>The goal is to separate *configuration (*what developers select and provide) from *code (*what platform teams implement and own).</p><p>This isn’t “Terraform modules, but nicer.” It’s the missing layer: an interface contract between platform teams and developers. One that scales across teams, promotes changes safely through environments, and abstracts away technical complexity.</p><h3>What “separation” looks like in practice</h3><p>In a typical “Terraform module-based platform” (often called “Terraform Service Catalog”), the interface still leaks cloud and tooling complexity, pushing developers to reason about low-level resources instead of outcomes.</p><pre>module &quot;service&quot; {<br>  source = &quot;git::ssh://git@github.com/acme/platform-modules.git//service?ref=v3.8.1&quot;<br><br>  name        = &quot;payments-api&quot;<br>  environment = &quot;prod&quot;<br><br>  # Leaky abstraction: app teams now need platform knowledge<br>  vpc_id              = data.terraform_remote_state.network.outputs.vpc_id<br>  private_subnet_ids  = data.terraform_remote_state.network.outputs.private_subnet_ids<br>  kms_key_arn         = data.terraform_remote_state.security.outputs.kms_key_arn<br>  log_retention_days  = 30<br><br>  # Every team asks for &quot;just one more option&quot;<br>  enable_waf          = true<br>  waf_rule_set        = &quot;strict&quot;<br>  enable_private_link = true<br><br>  tags = {<br>    owner = &quot;payments&quot;<br>    tier  = &quot;critical&quot;<br>  }<br>}</pre><p>This <em>looks</em> reusable. But it’s not a stable interface. It pushes platform decisions into every application repo:</p><ul><li>Which VPC are we allowed to use?</li><li>What’s the right subnet strategy?</li><li>What KMS key is compliant?</li><li>What’s the correct log retention?</li><li>Which options are mandatory vs optional?</li><li>What happens when the platform changes the “right” answer?</li></ul><p>Now multiply this across:</p><ul><li>20 teams</li><li>4 environments</li><li>3 regions</li><li>varying seniority levels</li><li>multiple IaC repositories</li></ul><p>You don’t get self-service. You get distributed platform engineering.</p><p>Compare this with the same module configured as a Catalyst Bundle.</p><pre>apiVersion: terramate.io/cli/v1<br>kind: BundleInstance<br>metadata:<br>  name: payments-api<br>  uuid: d92dce73-dfdc-4b26-961c-470359b37f46<br><br>spec:<br>  source: /bundles/acme.com/service/aws/v3.8.1<br>  inputs: # App-facing inputs shared between environments<br>    name: payments-api<br>    # ...<br>    # defaults are set by platform teams and <br>    # immutable configuration is not exposed user facing<br><br>specs: # environment specific configurations<br>  dev:<br>    inputs: # Development inputs inheriting and overwriting base configuration <br>      # ..<br>  prd: # Production inputs inherting lower environments and base <br>    inputs:<br>      # ...</pre><p>Instead of complex HCL and configuration, developers get an intuitive, simple-to-use YAML that exposes only the configuration relevant to them. The rest was already pre-configured by the platform team.</p><p>Notice developers no longer need to think about <em>where</em> infrastructure code lives in the repo, <em>how</em> Terraform is bootstrapped, or <em>which</em> state backend and providers are configured. That’s all built in: platform teams define and enforce where stacks are scaffolded in the filesystem, how remote state is set up, and which safe defaults apply — like Terraform, provider, state backend, and module versions.</p><p>Bundles can also include an upgrade path. When a new bundle version introduces additional infrastructure or configuration, Catalyst can automatically reconcile those changes. The result: developers don’t get pulled into complex day-2 operations — or forced to manually wrangle major module upgrades the way they often do with Terraform alone.</p><h3>Benefits to both Developers &amp; Platform Teams</h3><p>This creates a true win-win: platform teams get the control and consistency they need, while developers get a workflow that’s easy to use — so they can ship faster without compromise.</p><h3>For developers: the way of least resistance becomes the right way</h3><p>When configuration is decoupled from code, the developer experience improves immediately:</p><ul><li>Fewer decisions to make — less complexity, faster provisioning</li><li>No need to learn cloud internals just to ship infrastructure</li><li>Guardrails by default, so teams can’t accidentally cause vulnerability via misconfigurations</li><li>Faster onboarding for non-experts</li><li>A clearer golden path that still feels flexible, not restrictive</li></ul><p>Developers become productive by following the path of least resistance. And taking this path is equivalent to doing infrastructure “the right way”.</p><h3>For platform teams: control without becoming the bottleneck</h3><p>For platform teams, the biggest win is that both <strong>Day 1 &amp; Day 2 improve</strong>.</p><p><strong>Day 1:</strong> You can offer standardized, stable interfaces that encapsulate all your expertise in security, governance, &amp; compliance.</p><p><strong>Day 2:</strong> You can change what is underneath without affecting the developers. The interface stays the same, while you can do critical upgrades and maintenance in a decoupled fashion.</p><p>Bundles unlock “fleet management” for infrastructure:</p><ul><li>upgrades are centralized</li><li>refactors don’t require rewriting every consumer repo</li><li>policy changes can be enforced without waiting on every team</li><li>reuse becomes real, not aspirational</li><li>drift becomes manageable because the implementation stays owned</li></ul><p>And because Bundles integrate cleanly into diverse toolchains — including IDPs — you don’t need to rebuild your platform stack around them.</p><p>Catalyst doesn’t try to replace your toolchain. It complements it.</p><h3>The outcome</h3><p>Effortless infrastructure that is governed, compliant, &amp; secure by default.</p><p>And a stable contract between teams that thrive together.</p><p><a href="https://github.com/terramate-io/terramate-catalyst">So do give it a try</a>. We’d love to hear what you think.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5566d0dfddce" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/separating-configuration-from-code-with-terramate-catalyst-5566d0dfddce">Separating Configuration from Code with Terramate Catalyst</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Terramate Catalyst: The New Efficient Frontier for Infrastructure-as-Code]]></title>
            <link>https://medium.com/terramate/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code-a85ce2fd5db7?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/a85ce2fd5db7</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[iac]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Wed, 18 Feb 2026 11:37:08 GMT</pubDate>
            <atom:updated>2026-02-18T11:37:08.712Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6L0OUJmSrQs1RRnYLIlIKw.png" /></figure><p>Infrastructure-as-Code, such as Terraform or OpenTofu, has always had an arduous challenge at scale: getting different parts of your infrastructure to talk to each other shouldn’t be this hard.</p><p>Before Catalyst, teams faced a frustrating reality. Want to reference a resource from one stack in another? You had three bad options, each with its own set of headaches.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code/#the-output-sharing-problem">The Output Sharing Problem</a></h3><p>Traditional Terraform workflows (e.g., as introduced with Terragrunt Dependencies) forced you into a chicken-and-egg scenario⁠⁠. You need state to read from state. This meant chaining deployments⁠⁠ — turning what should be a single PR into multiple deployments⁠⁠. Your team needs permissions to access state files scattered across your infrastructure. And if you’re dealing with large outputs? You’ll hit system limits on environment variables⁠⁠.</p><p>The pain with this approach is that it requires the upstream stack to already be applied before you can even start to do a plan for the dependent stack. Which in turn requires multiple PRs and/or multiple applies. And every team member needs to be aware of this sequencing, which, in aggregate, can become really taxing and a frustrating challenge, especially for non-expert users.</p><p>Features like Terragrunt Dependencies and Terramate Output Sharing tried to make configuring those relationships more simple, but the core problems and complexity of two applies remain.</p><p>As Output Sharing requires terraform output to be parsed in the dependent stack and transformed into Terraform inputs in the dependent stack, additional problems occur:</p><ul><li>Environment variables are used to populate the inputs to Terraform; an environment is limited in size in general, so very large outputs are potentially not possible to be shared.</li><li>Terraform can not run in the dependent stacks directly, as the inputs need to be populated. This can lead to additional effort when debugging or getting things running in the first place, as additional tooling is always required to plan or apply the dependent stacks.</li><li>This is not a one-time thing. Every time new outputs are introduced, the dependency challenge rears its ugly face, quickly compounding to the detriment of the platform team’s ability to execute.</li><li>Mocking outputs (as supported by Terragrunt and Terramate) fixes the symptoms and allows for planning of dependent stacks without existing outputs, but plans do only reflect mocked inputs in plans and require plans to be regenerated during apply with the real values.</li></ul><p>In short, the complexity is shifted from Terraform to tooling, unfortunately, with a mental load and complexity tax.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code/#alternatives-remote-state-and-data-sources">Alternatives: Remote State and Data Sources</a></h3><p>Different approaches have been proposed to mitigate this problem.</p><p><a href="https://developer.hashicorp.com/terraform/language/state/remote-state-data">Remote state</a> sources work by looking at an existing state and looking up the values that are required. This essentially removes the need for additional tooling, as we now stay in native Terraform. We also only need one PR if we postpone the remote state lookup, so the need for mocking goes away.</p><p>Also, the downside is that it needs to be configured, which requires the location of the state and the right bucket. This information isn’t readily available in Terraform and needs to be looked up by the users to be set up once. Another con is that practically you can only postpone once.</p><p>In short, the complexity is partially mitigated, but unfortunately also partly shifted back to the user. So it also doesn’t really solve the problem.</p><p><a href="https://developer.hashicorp.com/terraform/language/data-sources">Data sources</a> get closer⁠⁠. They use the cloud provider API to query a specific resource. They handle new resources better and can be postponed, meaning you can do with only one PR. This, so far, has been our recommended way, as it is the “cleanest”.</p><p>Yet, the downside is that you now have to find the right resource. As IDs are often random, and a specific resource can be a needle in the haystack, you need to know about the infrastructure or invest time in finding the right resource. This, in turn, can make it difficult, especially if the person who did the initial work is not the same person who is required to read the data. Documentation thus becomes really critical (and is in practice often missing when needed the most).</p><p>So in a nutshell, the alternatives are all compromises, with different demands on cognitive load, manual work, and knowledge. But what if there was a way simpler way?</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code/#information-sharing-the-catalyst-way">Information Sharing: The Catalyst Way</a></h3><p>Catalyst introduces information sharing⁠⁠ — combining all the advantages with none of the drawbacks. One PR. One deployment. No permission juggling. No state file archaeology. No work finding resources.</p><p>Here’s how it works: Bundles share two types of information⁠⁠.</p><ul><li>Configuration gets shared at code generation time, so your code automatically adjusts to config from different stacks⁠⁠.</li><li>Data source information gets shared at deployment time, giving you exactly what you need to read the resources you want⁠⁠.</li></ul><p>This information is then used as follows:</p><ul><li>Bundles own creating infrastructure in stacks (create new stacks or extend configuration in existing stacks)</li><li>Bundles also provide a UUID that can be used to tag and identify resources created by Components. Components take care of generating the actual code in stacks (Terraform, OpenTofu, Kubernetes Manifests, etc.)</li><li>Each Bundle implements a Bundle class that can support creating a contract of the exported data</li><li>Bundles can access configuration data of other Bundles by referencing them via UUID or via human-friendly aliases.</li><li>A repository has global knowledge about all Bundles instantiated and all the configurations. In future releases, Terramate Catalyst will allow cross-repository access to information, too.</li></ul><p>As a high-level example: A database Bundle can access a VPC Bundle of class example.com/vpc/v1 with the alias of main and access its uuid and exported configuration as well as the actual Bundle inputs.</p><p>This helps to easily share information about resources created by a Bundle, in contrast to sharing the actual resource, allowing us to generate a complete static configuration before planning or applying the actual resources.</p><p>The end-user does not need to know the details of the actual tagging strategies used, but the platform engineers can rely on the Bundle contracts to ensure tags are in place to populate the filters used in data sources.</p><p>The simplest tagging strategy can be that a Bundle always tags cloud resources with {class} = {uuid} e.g. example.com/vpc/v1 = {uuid} , and other Bundles can use that same tag by referencing class and alias to get the uuid : tm_bundle(&quot;example.com/vpc/v1&quot;, &quot;main&quot;).uuid . This can be set up and extended in flexible ways to meet any team&#39;s needs.</p><p>The result is generated code that shares information and not data. Data is just read when needed. The user does not even need to know which exact stack requires the data, nor any state file configuration.</p><p>Each stack has native Terraform code that can be executed without any additional tooling. Nor does it require you to use any 3rd-party orchestration, so you can use Terramate Catalyst with Terraform Cloud or any other Terraform automation provider as well. Needless to say, it is seamlessly integrating with Terramate Cloud as well.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code/#from-output-sharing-to-information-sharing">From Output Sharing to Information Sharing</a></h3><p>Output sharing was created to mitigate the pain from configuring data sources. But ultimately introduced several new pains in the process.</p><p>With Terramate Catalyst information sharing, we have solved the original root problem. Instead of shifting complexity around, we have completely removed it from the user experience.</p><p>We believe information sharing will be the new standard, as it allows to dramatically reduce the level of expertise required to spin up complex infrastructure.</p><p>So long output-sharing, you won’t be missed.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code/#other-benefits-from-terramate-catalyst">Other Benefits from Terramate Catalyst</a></h3><p>Information sharing is one of many benefits that Terramate Catalyst provides, namely:</p><ul><li>For platform teams, creating reusable blueprints and packaging them into Bundles is easier than ever.</li><li>Bundles can create and maintain multiple stacks via a single configuration, allowing to provide a single API to users, AI agents, or internal developer portals.</li><li>It’s YAML for the end-user. No need to learn HCL or understand the underlying IaC engine used.</li><li>Bundles can create Terraform, OpenTofu, Kubernetes Manifests, Helm instantiations, and everything else.</li><li>Enable full self-service for non-expert users and expert users alike, with compliance and configuration guaranteed by your team of expert platform engineers.</li></ul><p>Ready to see it in action? Check out our <a href="https://terramate.io/rethinking-iac/technical-introduction-to-terramate-catalyst/">introduction guide</a> to see how Catalyst transforms your IaC workflow.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a85ce2fd5db7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/terramate-catalyst-the-new-efficient-frontier-for-infrastructure-as-code-a85ce2fd5db7">Terramate Catalyst: The New Efficient Frontier for Infrastructure-as-Code</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Technical Introduction to Terramate Catalyst]]></title>
            <link>https://medium.com/terramate/technical-introduction-to-terramate-catalyst-3fad8852cddb?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/3fad8852cddb</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[iac]]></category>
            <category><![CDATA[platform-engineering]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[opentofu]]></category>
            <dc:creator><![CDATA[Sören Martius]]></dc:creator>
            <pubDate>Tue, 13 Jan 2026 14:51:18 GMT</pubDate>
            <atom:updated>2026-01-13T14:51:18.364Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W5e4Y4c1JhoSeIrHPvZvEg.png" /></figure><p>In our previous blog posts, we discussed <a href="https://terramate.io/rethinking-iac/the-infrastructure-as-code-self-service-myth/">why enabling Developer self-service with Infrastructure-as-Code often doesn’t work</a> and <a href="https://terramate.io/rethinking-iac/how-terramate-catalyst-reimagines-iac-self-service/">how Terramate Catalyst is reimagining Infrastructure-as-Code (IaC) self-service</a>.</p><p>In this post, we will explore the technical capabilities of Terramate Catalyst hands-on by working through different examples. At the end of this guide, you will know how you can use Terramate Catalyst to enable developers to deploy AWS services, such as S3 or ECS, in self-service using existing Terraform modules.</p><p>If you prefer, you can take a look at the final result of this guide in the <a href="https://github.com/terramate-io/terramate-catalyst-examples">terramate-catalyst-examples</a> repository on GitHub.</p><h3>How Catalyst Works Under the Hood</h3><p>Before we start writing some code, let’s learn about the basics of Catalyst.</p><p>At its core, Catalyst transforms how infrastructure is delivered and consumed inside organizations by introducing two new primitives: <strong>Bundles</strong> and <strong>Components</strong>.</p><h3>Components</h3><p>Components are reusable, opinionated infrastructure blueprints — defined by platform engineers. They encode organizational standards, governance rules, naming conventions, security policies, cost controls, and so on. In practice, a Component may represent a “database setup,” “message queue,” “VPC,” “cache cluster,” or any other infrastructure pattern. Also, Components can be any arbitrary IaC. E.g., you can define a bunch of Terraform and OpenTofu resources in a Component, use Terraform modules, or any other IaC, such as Kubernetes manifests. The idea of Components is to provide infrastructure patterns that can be reused by platform engineers and sourced by a single or multiple Bundles.</p><h3>Bundles</h3><p>Bundles assemble one or more Components into ready-to-use, deployable units. These are what developers and AI agents consume when requesting infrastructure. Bundles abstract away all the complexity: no need to write Terraform, manage state, or deal with providers — you declare what you need (e.g., “a database for service X in environment Y”). Catalyst fills in the rest. Bundles are meant as a unit of reuse for application developers, who aren’t experts in IaC.</p><h3>Division of responsibilities</h3><p>This separation creates a <strong>clear division of responsibility</strong>:</p><ul><li>Platform engineers design and maintain infrastructure logic, compliance, scalability, and IaC best practices.</li><li>Application developers (or AI agents) request infrastructure via simple, high-level abstractions — without needing to understand Terraform, module variables, or backend configuration.</li></ul><p>In other words: Catalyst doesn’t replace IaC — it operationalizes it and elegantly hides the complexity for non-expert infrastructure “consumers”.</p><h3>Ease of onboarding</h3><p>Onboarding Catalyst to an existing IaC setup is straightforward. E.g, Catalyst comes with helpers that allow importing existing Terraform modules as Components. Another command helps you easily create new Bundles without having to write all the required configuration from scratch.</p><p>Part of the value prop of Catalyst is that any existing IaC setup can be easily reused to turn into a self-service infrastructure vending machine.</p><h3>Versioning of Bundles and Components</h3><p>Both Components and Bundles can be managed and versioned in Git repositories and in the upcoming Terramate Registry using <a href="https://semver.org/">semantic versioning</a>. If you use the Registry, Terramate Cloud provides a dashboard to track Bundle and Component usage, as well as versions across multiple repositories and teams.</p><h3>Scaffold complex IaC</h3><p>Catalyst basically works by scaffolding the entire IaC, including state configuration and providers, but it doesn’t require developers to know, e.g., Terraform, OpenTofu, or their configuration language HCL. Developers can either use the terramate scaffold command to choose from Bundles available in the current repository, a remote repository, or the upcoming registry in Terramate Cloud. Alternatively, you may use any of the other existing approaches, such as the <a href="https://github.com/terramate-io/terramate-mcp-server">Terramate MCP Server</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Au4fScQiZJEElG91ZFGbcQ.png" /></figure><h3>Getting Started: Installing Terramate Catalyst</h3><p>Let’s start working on some examples. Terramate Catalyst is not part of Terramate CLI but available as a separate binary on <a href="https://github.com/terramate-io/terramate-catalyst">GitHub</a>. It comes with two binaries, terramate and terramate-ls that act as drop-in replacements for Terramate CLI. The easiest way to install Terramate Catalyst is by using the <a href="https://asdf-vm.com/">asdf package manager</a>.</p><pre>asdf plugin add terramate-catalyst https://github.com/terramate-io/asdf-terramate-catalyst<br>asdf global terramate-catalyst 0.15.2-beta11 </pre><p>Alternatively, you can also download the binaries from the repository directly by choosing a <a href="https://github.com/terramate-io/terramate-catalyst/releases">release</a>.</p><p>We will provide more convenient installation methods, such as additional package managers, soon.</p><h3>Example: Enable Developers to create an S3 Bucket in self-service</h3><p>In this example, we focus on a simple use case. Allowing developers to deploy a simple S3 bucket by defining its name only and without ever touching Terraform or OpenTofu.</p><p>In <a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/components/example.io/terramate-aws-s3-bucket/v1/component.tm.hcl">components/terramate-aws-s3-bucket/v1/component.tm.hcl</a>, you can see how a Component is configured.</p><p>component.tm.hcl</p><pre>define component metadata {<br>  class   = &quot;example.io/tf-aws-s3&quot;<br>  version = &quot;1.0.0&quot;<br><br>  name         = &quot;AWS S3 Bucket Component&quot;<br>  description  = &quot;Component that allows creating an S3 bucket on AWS with configurable ACL (default: private) and versioning enabled.&quot;<br>  technologies = [&quot;terraform&quot;, &quot;opentofu&quot;]<br>}<br><br>define component {<br>  input &quot;name&quot; {<br>    type        = string<br>    prompt      = &quot;S3 Bucket Name&quot;<br>    description = &quot;The name of the S3 bucket&quot;<br>  }<br><br>  input &quot;acl&quot; {<br>    type        = string<br>    description = &quot;Access Control List (ACL) for the bucket. Valid values: &#39;private&#39;, &#39;public-read&#39;, &#39;public-read-write&#39;, &#39;aws-exec-read&#39;, &#39;authenticated-read&#39;, &#39;bucket-owner-read&#39;, &#39;bucket-owner-full-control&#39;, &#39;log-delivery-write&#39;&quot;<br>    default     = &quot;private&quot;<br>  }<br><br>  input &quot;tags&quot; {<br>    type        = map(string)<br>    description = &quot;Tags to apply to resources&quot;<br>    default     = {}<br>  }<br>}</pre><p>Components configure metadata such as class, version, name, description, and also expose the inputs available to Bundles.</p><p>Once created and configured, any IaC can be added to a Component. For example, find the configuration for a simple S3 bucket in <a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/components/example.io/terramate-aws-s3-bucket/v1/main.tf.tmgen">componments/example.io/terramate-aws-s3-bucket/v1/main.tf.tmgen</a> using simple Terramate code generation.</p><p>main.tf.tmgen</p><pre>module &quot;s3_bucket&quot; {<br>  source  = &quot;terraform-aws-modules/s3-bucket/aws&quot;<br>  version = &quot;5.9.0&quot;<br><br>  bucket = component.input.name.value<br>  acl    = component.input.acl.value<br><br>  control_object_ownership = true<br>  object_ownership         = &quot;ObjectWriter&quot;<br><br>  # Disable Block Public Access settings when using public ACLs<br>  block_public_acls       = !tm_contains([&quot;public-read&quot;, &quot;public-read-write&quot;], component.input.acl.value)<br>  block_public_policy     = !tm_contains([&quot;public-read&quot;, &quot;public-read-write&quot;], component.input.acl.value)<br>  ignore_public_acls      = !tm_contains([&quot;public-read&quot;, &quot;public-read-write&quot;], component.input.acl.value)<br>  restrict_public_buckets = !tm_contains([&quot;public-read&quot;, &quot;public-read-write&quot;], component.input.acl.value)<br><br>  versioning = {<br>    enabled = true<br>  }<br><br>  server_side_encryption_configuration = {<br>    rule = {<br>      apply_server_side_encryption_by_default = {<br>        sse_algorithm = &quot;AES256&quot;<br>      }<br>    }<br>  }<br><br>  tags = component.input.tags.value<br>}</pre><p>You can see that the S3 bucket comes with versioning and encryption enabled by default, which we want to enforce for every bucket we create. Developers can only configure what matters to them, which, in this case, means the name of each bucket and whether it is private or public.</p><p>Next, let’s take a look at how we configure the Bundle for enabling developers to scaffold S3 buckets in self-service. Take a look at the Bundle configuration in <a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/bundles/example.io/tf-aws-s3/v1/bundle.tm.hcl">terramate-catalyst-examples/bundles/example.io/tf-aws-s3/v1/bundle.tm.hcl</a>.</p><p>bundle.tm.hcl</p><pre>define bundle metadata {<br>  class   = &quot;example.io/tf-aws-s3/v1&quot;<br>  version = &quot;1.0.0&quot;<br><br>  name         = &quot;S3 Bucket&quot;<br>  description  = &lt;&lt;EOF<br>    This Bundle creates and manages an S3 Bucket on AWS. The bucket can be configured as private or public, with private as the default.<br>  EOF<br>  technologies = [&quot;terraform&quot;, &quot;opentofu&quot;]<br>}<br><br>define bundle {<br>  alias = tm_slug(bundle.input.name.value)<br><br>  input &quot;env&quot; {<br>    type                  = string<br>    prompt                = &quot;Environment&quot;<br>    description           = &quot;A list of available environments to create the S3 bucket in.&quot;<br>    allowed_values        = global.environments<br>    required_for_scaffold = true<br>    multiselect           = false<br>  }<br><br>  input &quot;name&quot; {<br>    type                  = string<br>    prompt                = &quot;S3 Bucket Name&quot;<br>    description           = &quot;The name of the S3 bucket&quot;<br>    required_for_scaffold = true<br>  }<br><br>  input &quot;visibility&quot; {<br>    type        = string<br>    prompt      = &quot;Bucket Visibility&quot;<br>    description = &quot;Whether the bucket should be private or public&quot;<br>    default     = &quot;private&quot;<br>    allowed_values = [<br>      { name = &quot;Private&quot;, value = &quot;private&quot; },<br>      { name = &quot;Public Read&quot;, value = &quot;public-read&quot; },<br>      { name = &quot;Public Read/Write&quot;, value = &quot;public-read-write&quot; }<br>    ]<br>  }<br>}<br><br>define bundle {<br>  scaffolding {<br>    path = &quot;/stacks/${bundle.input.env.value}/s3/_bundle_s3_${tm_slug(bundle.input.name.value)}.tm.hcl&quot;<br>    name = tm_slug(bundle.input.name.value)<br>  }<br>}<br><br>define bundle stack &quot;s3-bucket&quot; {<br>  metadata {<br>    path = tm_slug(bundle.input.name.value)<br><br>    name        = &quot;AWS S3 Bucket ${bundle.input.name.value}&quot;<br>    description = &lt;&lt;EOF<br>      AWS S3 Bucket ${bundle.input.name.value}<br>    EOF<br><br>    tags = [<br>      &quot;example.io/aws-s3-bucket&quot;,<br>      &quot;example.io/bundle/${bundle.uuid}&quot;,<br>      &quot;example.io/aws-s3-bucket/${bundle.uuid}&quot;,<br>      &quot;example.io/aws-s3-bucket/${tm_slug(bundle.input.name.value)}&quot;,<br>    ]<br>  }<br><br>  component &quot;s3-bucket&quot; {<br>    source = &quot;/components/example.io/terramate-aws-s3-bucket/v1&quot;<br>    inputs = {<br>      name        = bundle.input.name.value<br>      acl         = bundle.input.visibility.value<br>      bundle_uuid = bundle.uuid<br>      tags = {<br>        &quot;example.io/bundle-uuid&quot; = bundle.uuid<br>      }<br>    }<br>  }<br>}</pre><p>A few things are happening here. First, we configure the Bundle metadata as we did for the Component in the previous section. But if you look at the configuration, you can see that we are doing a few things in addition:</p><ul><li>The Bundle exposes three inputs: name which can be a string and env which is a select field that can be either dev, stg or prd and visibility which can either be private, public-read or public-write .</li><li>In the define bundle scaffolding block, we are defining the target path of the Bundle. So each time a user is running terramate scaffold to create a new S3 bucket the IaC will be scaffolded in a unique path. For example, a bucket named terramate-catalyst-example in the dev environment will be scaffolded in stacks/dev/s3/terramate-catalyst-example/ .</li><li>It defines the required configuration for a single or multi-stack architecture, including orchestration configuration, state backend and providers.</li><li>It passes input variables down to the individual Components.</li></ul><p>To test this example, clone the <a href="https://github.com/terramate-io/terramate-catalyst-examples">terramate-catalyst-examples</a> repository and run terramate scaffold in the root of the repository.</p><pre>git clone git@github.com:terramate-io/terramate-catalyst-examples.git<br><br>cd terramate-catalyst-examples<br><br>terramate scaffold</pre><p>Running the scaffold command shows you the Bundles you can use to initiate infrastructure from.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ri3-AwNiycQ9LHDT1yXOjQ.png" /></figure><p>Next, choose S3 Bucket and create a new private bucket named catalyst-example-bucket in the dev environment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EJw-O3aZAOfhsvca_ccaqA.png" /></figure><p>Creating a new instance of the S3 Bundle will generate a configuration file in terramate-catalyst-examples/stacks/dev/s3/_bundle_s3_catalyst-example-bucket.tm.yml that will look similar to this:</p><pre>apiVersion: terramate.io/cli/v1<br>kind: BundleInstance<br>metadata:<br>  name: catalyst-example-bucket<br>  uuid: fa2a2e9e-1a29-4e03-9ff6-c9d53cfdc157<br>spec:<br>  source: /bundles/example.io/tf-aws-s3/v1<br>  inputs:<br>    <br>    # A list of available environments to create the S3 bucket in.<br>    env: dev<br>    <br>    # The name of the S3 bucket<br>    name: catalyst-test-bucket<br>    <br>    # Whether the bucket should be private or public<br>    visibility: private</pre><p>This developer-friendly YAML file contains the configuration for our Bundle instance.</p><p>The final step is to generate all required files from the Bundle configuration. To achieve this, run terramate generate to generate the Terraform configuration.</p><pre>❯ terramate generate<br>Code generation report<br><br>Successes:<br><br>- /stacks/dev/s3/catalyst-example-bucket<br>        [+] backend.tf<br>        [+] component_s3-bucket_main.tf<br>        [+] stack.tm.hcl<br>        [+] terraform.tf<br><br>Hint: &#39;+&#39;, &#39;~&#39; and &#39;-&#39; mean the file was created, changed and deleted, respectively.</pre><p>If you take a look at the generated component_s3-bucket_main.tf, you can see that the Terraform configuration for deploying a private S3 bucket named catalyst-example-bucket has been created in terramate-catalyst-examples/stacks/dev/s3/catalyst-example-bucket/component_s3-bucket_main.tf.</p><p>component_s3-bucket_main.tf</p><pre>// TERRAMATE: GENERATED AUTOMATICALLY DO NOT EDIT<br><br>module &quot;s3_bucket&quot; {<br>  acl                      = &quot;private&quot;<br>  block_public_acls        = true<br>  block_public_policy      = true<br>  bucket                   = &quot;catalyst-example-bucket&quot;<br>  control_object_ownership = true<br>  ignore_public_acls       = true<br>  object_ownership         = &quot;ObjectWriter&quot;<br>  restrict_public_buckets  = true<br>  server_side_encryption_configuration = {<br>    rule = {<br>      apply_server_side_encryption_by_default = {<br>        sse_algorithm = &quot;AES256&quot;<br>      }<br>    }<br>  }<br>  source = &quot;terraform-aws-modules/s3-bucket/aws&quot;<br>  tags = {<br>    &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>  }<br>  version = &quot;5.9.0&quot;<br>  versioning = {<br>    enabled = true<br>  }<br>}</pre><p>The result is native Terraform code that configures the S3 bucket, providers and Terraform state backend, which can be deployed without further effort using <a href="https://terramate.io/docs/cli/automation/">automation workflows</a>.</p><p>To deploy the bucket, you can orchestrate the terraform apply command using the Terramate Orchestration Engine. Make sure that you <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration">have valid AWS credentials configured</a> in our environment.</p><p>Initialize the Terraform environment first by orchestrating terraform init.</p><pre>❯ terramate run -X -- terraform init<br><br>terramate: Entering stack in /stacks/dev/s3/catalyst-example-bucket<br>terramate: Executing command &quot;terraform init&quot;<br>Initializing the backend...<br><br>Successfully configured the backend &quot;s3&quot;! Terraform will automatically<br>use this backend unless the backend configuration changes.<br>Initializing modules...<br>Downloading registry.terraform.io/terraform-aws-modules/s3-bucket/aws 5.9.0 for s3_bucket...<br>- s3_bucket in .terraform/modules/s3_bucket<br>Initializing provider plugins...<br>- Finding hashicorp/aws versions matching &quot;&gt;= 6.22.0, ~&gt; 6.25.0&quot;...<br>- Finding hashicorp/null versions matching &quot;~&gt; 3.2.0&quot;...<br>- Installing hashicorp/aws v6.25.0...<br>- Installed hashicorp/aws v6.25.0 (signed by HashiCorp)<br>- Installing hashicorp/null v3.2.4...<br>- Installed hashicorp/null v3.2.4 (signed by HashiCorp)<br>Terraform has created a lock file .terraform.lock.hcl to record the provider<br>selections it made above. Include this file in your version control repository<br>so that Terraform can guarantee to make the same selections by default when<br>you run &quot;terraform init&quot; in the future.<br><br>Terraform has been successfully initialized!<br><br>You may now begin working with Terraform. Try running &quot;terraform plan&quot; to see<br>any changes that are required for your infrastructure. All Terraform commands<br>should now work.<br><br>If you ever set or change modules or backend configuration for Terraform,<br>rerun this command to reinitialize your working directory. If you forget, other<br>commands will detect it and remind you to do so if necessary.</pre><p>Next, apply the changes by orchestrating terraform apply.</p><pre>❯ terramate run -X -- terraform apply<br>                                       <br>terramate: Entering stack in /stacks/dev/s3/catalyst-example-bucket<br>terramate: Executing command &quot;terraform apply&quot;<br>module.s3_bucket.data.aws_region.current: Reading...<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Reading...<br>module.s3_bucket.data.aws_partition.current: Reading...<br>module.s3_bucket.data.aws_caller_identity.current: Reading...<br>module.s3_bucket.data.aws_region.current: Read complete after 0s [id=us-east-1]<br>module.s3_bucket.data.aws_partition.current: Read complete after 0s [id=aws]<br>module.s3_bucket.data.aws_caller_identity.current: Read complete after 0s [id=975086131449]<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Read complete after 1s [id=9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80]<br><br>Terraform used the selected providers to generate the following execution plan. Resource<br>actions are indicated with the following symbols:<br>  + create<br><br>Terraform will perform the following actions:<br><br>  # module.s3_bucket.aws_s3_bucket.this[0] will be created<br>  + resource &quot;aws_s3_bucket&quot; &quot;this&quot; {<br>      + acceleration_status         = (known after apply)<br>      + acl                         = (known after apply)<br>      + arn                         = (known after apply)<br>      + bucket                      = &quot;catalyst-example-bucket&quot;<br>      + bucket_domain_name          = (known after apply)<br>      + bucket_prefix               = (known after apply)<br>      + bucket_region               = (known after apply)<br>      + bucket_regional_domain_name = (known after apply)<br>      + force_destroy               = false<br>      + hosted_zone_id              = (known after apply)<br>      + id                          = (known after apply)<br>      + object_lock_enabled         = false<br>      + policy                      = (known after apply)<br>      + region                      = &quot;us-east-1&quot;<br>      + request_payer               = (known after apply)<br>      + tags                        = {<br>          + &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>        }<br>      + tags_all                    = {<br>          + &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>        }<br>      + website_domain              = (known after apply)<br>      + website_endpoint            = (known after apply)<br><br>      + cors_rule (known after apply)<br><br>      + grant (known after apply)<br><br>      + lifecycle_rule (known after apply)<br><br>      + logging (known after apply)<br><br>      + object_lock_configuration (known after apply)<br><br>      + replication_configuration (known after apply)<br><br>      + server_side_encryption_configuration (known after apply)<br><br>      + versioning (known after apply)<br><br>      + website (known after apply)<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_acl.this[0] will be created<br>  + resource &quot;aws_s3_bucket_acl&quot; &quot;this&quot; {<br>      + acl    = &quot;private&quot;<br>      + bucket = (known after apply)<br>      + id     = (known after apply)<br>      + region = &quot;us-east-1&quot;<br><br>      + access_control_policy (known after apply)<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_ownership_controls.this[0] will be created<br>  + resource &quot;aws_s3_bucket_ownership_controls&quot; &quot;this&quot; {<br>      + bucket = (known after apply)<br>      + id     = (known after apply)<br>      + region = &quot;us-east-1&quot;<br><br>      + rule {<br>          + object_ownership = &quot;ObjectWriter&quot;<br>        }<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_public_access_block.this[0] will be created<br>  + resource &quot;aws_s3_bucket_public_access_block&quot; &quot;this&quot; {<br>      + block_public_acls       = true<br>      + block_public_policy     = true<br>      + bucket                  = (known after apply)<br>      + id                      = (known after apply)<br>      + ignore_public_acls      = true<br>      + region                  = &quot;us-east-1&quot;<br>      + restrict_public_buckets = true<br>      + skip_destroy            = true<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_versioning.this[0] will be created<br>  + resource &quot;aws_s3_bucket_versioning&quot; &quot;this&quot; {<br>      + bucket = (known after apply)<br>      + id     = (known after apply)<br>      + region = &quot;us-east-1&quot;<br><br>      + versioning_configuration {<br>          + mfa_delete = (known after apply)<br>          + status     = &quot;Enabled&quot;<br>        }<br>    }<br><br>Plan: 5 to add, 0 to change, 0 to destroy.<br><br>Do you want to perform these actions?<br>  Terraform will perform the actions described above.<br>  Only &#39;yes&#39; will be accepted to approve.<br><br>  Enter a value: yes <br><br>module.s3_bucket.aws_s3_bucket.this[0]: Creating...<br>module.s3_bucket.aws_s3_bucket.this[0]: Creation complete after 8s [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Creating...<br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Creating...<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Creation complete after 2s [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Creating...<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Creation complete after 1s [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Creating...<br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Creation complete after 3s [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Creation complete after 1s [id=catalyst-example-bucket,private]<br>Releasing state lock. This may take a few moments...<br><br>Apply complete! Resources: 5 added, 0 changed, 0 destroyed.</pre><p>Congratulations, you just learned how to provide self-service golden paths for deploying a S3 bucket on AWS to developers.</p><h3>Example: Reconfigure the S3 Bucket to be public instead of private</h3><p>But how about if a developer wants to change an existing S3 bucket created with Terramate Catalyst? It’s dead simple: just open the _bundle_s3_catalyst-example-bucket.tm.yml file in terramate-catalyst-examples/stacks/dev/s3/_bundle_s3_catalyst-example-bucket.tm.yml and change the visbility attribute from private to public-read.</p><p>_bundle_s3_catalyst-example-bucket.tm.yml</p><pre>apiVersion: terramate.io/cli/v1<br>kind: BundleInstance<br>metadata:<br>  name: catalyst-example-bucket<br>  uuid: fa2a2e9e-1a29-4e03-9ff6-c9d53cfdc157<br>spec:<br>  source: /bundles/example.io/tf-aws-s3/v1<br>  inputs:<br>    <br>    # A list of available environments to create the S3 bucket in.<br>    env: dev<br>    <br>    # The name of the S3 bucket<br>    name: catalyst-test-bucket<br>    <br>    # Whether the bucket should be private or public<br>    visibility: public-read</pre><p>Afterwards run terramate generate again to regenerate the Terraform configuration.</p><pre>❯ terramate generate                      <br>Code generation report<br><br>Successes:<br><br>- /stacks/dev/s3/catalyst-example-bucket<br>        [~] component_s3-bucket_main.tf<br><br>Hint: &#39;+&#39;, &#39;~&#39; and &#39;-&#39; mean the file was created, changed and deleted, respectively.</pre><p>You can see how only the component_s3-bucket_main.tf is generated again to reflect the updated configuration.</p><p>component_s3-bucket_main.tf</p><pre>// TERRAMATE: GENERATED AUTOMATICALLY DO NOT EDIT<br><br>module &quot;s3_bucket&quot; {<br>  acl                      = &quot;public-read&quot;<br>  block_public_acls        = false<br>  block_public_policy      = false<br>  bucket                   = &quot;catalyst-example-bucket&quot;<br>  control_object_ownership = true<br>  ignore_public_acls       = false<br>  object_ownership         = &quot;ObjectWriter&quot;<br>  restrict_public_buckets  = false<br>  server_side_encryption_configuration = {<br>    rule = {<br>      apply_server_side_encryption_by_default = {<br>        sse_algorithm = &quot;AES256&quot;<br>      }<br>    }<br>  }<br>  source = &quot;terraform-aws-modules/s3-bucket/aws&quot;<br>  tags = {<br>    &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>  }<br>  version = &quot;5.9.0&quot;<br>  versioning = {<br>    enabled = true<br>  }<br>}</pre><p>To deploy the changes, simply orchestrate terraform apply again.</p><pre>❯ terramate run -X -- terraform apply<br><br>terramate: Entering stack in /stacks/dev/s3/catalyst-example-bucket<br>terramate: Executing command &quot;terraform apply&quot;<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Reading...<br>module.s3_bucket.data.aws_caller_identity.current: Reading...<br>module.s3_bucket.data.aws_partition.current: Reading...<br>module.s3_bucket.data.aws_region.current: Reading...<br>module.s3_bucket.data.aws_partition.current: Read complete after 0s [id=aws]<br>module.s3_bucket.aws_s3_bucket.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.data.aws_region.current: Read complete after 0s [id=us-east-1]<br>module.s3_bucket.data.aws_caller_identity.current: Read complete after 0s [id=975086131449]<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Read complete after 1s [id=9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80]<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Refreshing state... [id=catalyst-example-bucket,private]<br><br>Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following<br>symbols:<br>  ~ update in-place<br><br>Terraform will perform the following actions:<br><br>  # module.s3_bucket.aws_s3_bucket_acl.this[0] will be updated in-place<br>  ~ resource &quot;aws_s3_bucket_acl&quot; &quot;this&quot; {<br>      ~ acl                   = &quot;private&quot; -&gt; &quot;public-read&quot;<br>        id                    = &quot;catalyst-example-bucket,private&quot;<br>        # (3 unchanged attributes hidden)<br><br>      ~ access_control_policy (known after apply)<br>      - access_control_policy {<br>          - grant {<br>              - permission = &quot;FULL_CONTROL&quot; -&gt; null<br><br>              - grantee {<br>                  - id            = &quot;9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80&quot; -&gt; null<br>                  - type          = &quot;CanonicalUser&quot; -&gt; null<br>                    # (3 unchanged attributes hidden)<br>                }<br>            }<br>          - owner {<br>              - id           = &quot;9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80&quot; -&gt; null<br>                # (1 unchanged attribute hidden)<br>            }<br>        }<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_public_access_block.this[0] will be updated in-place<br>  ~ resource &quot;aws_s3_bucket_public_access_block&quot; &quot;this&quot; {<br>      ~ block_public_acls       = true -&gt; false<br>      ~ block_public_policy     = true -&gt; false<br>        id                      = &quot;catalyst-example-bucket&quot;<br>      ~ ignore_public_acls      = true -&gt; false<br>      ~ restrict_public_buckets = true -&gt; false<br>        # (3 unchanged attributes hidden)<br>    }<br><br>Plan: 0 to add, 2 to change, 0 to destroy.<br><br>Do you want to perform these actions?<br>  Terraform will perform the actions described above.<br>  Only &#39;yes&#39; will be accepted to approve.<br><br>  Enter a value: yes<br><br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Modifying... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Modifications complete after 1s [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Modifying... [id=catalyst-example-bucket,private]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Modifications complete after 1s [id=catalyst-example-bucket,public-read]<br>Releasing state lock. This may take a few moments...<br><br>Apply complete! Resources: 0 added, 2 changed, 0 destroyed.</pre><p>Finally, if you want to destroy the S3 bucket again, simply orchestrate terraform destroy.</p><pre>❯ terramate run -X --reverse terraform destroy<br>                       <br>terramate: Entering stack in /stacks/dev/s3/catalyst-example-bucket<br>terramate: Executing command &quot;terraform destroy&quot;<br>module.s3_bucket.data.aws_caller_identity.current: Reading...<br>module.s3_bucket.data.aws_region.current: Reading...<br>module.s3_bucket.data.aws_partition.current: Reading...<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Reading...<br>module.s3_bucket.data.aws_partition.current: Read complete after 0s [id=aws]<br>module.s3_bucket.data.aws_region.current: Read complete after 0s [id=us-east-1]<br>module.s3_bucket.aws_s3_bucket.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.data.aws_caller_identity.current: Read complete after 1s [id=975086131449]<br>module.s3_bucket.data.aws_canonical_user_id.this[0]: Read complete after 1s [id=9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80]<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Refreshing state... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Refreshing state... [id=catalyst-example-bucket,public-read]<br><br>Terraform used the selected providers to generate the following execution plan. Resource actions are<br>indicated with the following symbols:<br>  - destroy<br><br>Terraform will perform the following actions:<br><br>  # module.s3_bucket.aws_s3_bucket.this[0] will be destroyed<br>  - resource &quot;aws_s3_bucket&quot; &quot;this&quot; {<br>      - arn                         = &quot;arn:aws:s3:::catalyst-example-bucket&quot; -&gt; null<br>      - bucket                      = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - bucket_domain_name          = &quot;catalyst-example-bucket.s3.amazonaws.com&quot; -&gt; null<br>      - bucket_region               = &quot;us-east-1&quot; -&gt; null<br>      - bucket_regional_domain_name = &quot;catalyst-example-bucket.s3.us-east-1.amazonaws.com&quot; -&gt; null<br>      - force_destroy               = false -&gt; null<br>      - hosted_zone_id              = &quot;Z3AQBSTGFYJSTF&quot; -&gt; null<br>      - id                          = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - object_lock_enabled         = false -&gt; null<br>      - region                      = &quot;us-east-1&quot; -&gt; null<br>      - request_payer               = &quot;BucketOwner&quot; -&gt; null<br>      - tags                        = {<br>          - &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>        } -&gt; null<br>      - tags_all                    = {<br>          - &quot;example.io/bundle-uuid&quot; = &quot;db8204c7-1fa3-49ae-9311-bca744f681f0&quot;<br>        } -&gt; null<br>        # (3 unchanged attributes hidden)<br><br>      - grant {<br>            id          = null<br>          - permissions = [<br>              - &quot;READ&quot;,<br>            ] -&gt; null<br>          - type        = &quot;Group&quot; -&gt; null<br>          - uri         = &quot;http://acs.amazonaws.com/groups/global/AllUsers&quot; -&gt; null<br>        }<br>      - grant {<br>          - id          = &quot;9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80&quot; -&gt; null<br>          - permissions = [<br>              - &quot;FULL_CONTROL&quot;,<br>            ] -&gt; null<br>          - type        = &quot;CanonicalUser&quot; -&gt; null<br>            # (1 unchanged attribute hidden)<br>        }<br><br>      - server_side_encryption_configuration {<br>          - rule {<br>              - bucket_key_enabled = false -&gt; null<br><br>              - apply_server_side_encryption_by_default {<br>                  - sse_algorithm     = &quot;AES256&quot; -&gt; null<br>                    # (1 unchanged attribute hidden)<br>                }<br>            }<br>        }<br><br>      - versioning {<br>          - enabled    = true -&gt; null<br>          - mfa_delete = false -&gt; null<br>        }<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_acl.this[0] will be destroyed<br>  - resource &quot;aws_s3_bucket_acl&quot; &quot;this&quot; {<br>      - acl                   = &quot;public-read&quot; -&gt; null<br>      - bucket                = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - id                    = &quot;catalyst-example-bucket,public-read&quot; -&gt; null<br>      - region                = &quot;us-east-1&quot; -&gt; null<br>        # (1 unchanged attribute hidden)<br><br>      - access_control_policy {<br>          - grant {<br>              - permission = &quot;READ&quot; -&gt; null<br><br>              - grantee {<br>                    id            = null<br>                  - type          = &quot;Group&quot; -&gt; null<br>                  - uri           = &quot;http://acs.amazonaws.com/groups/global/AllUsers&quot; -&gt; null<br>                    # (2 unchanged attributes hidden)<br>                }<br>            }<br>          - grant {<br>              - permission = &quot;FULL_CONTROL&quot; -&gt; null<br><br>              - grantee {<br>                  - id            = &quot;9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80&quot; -&gt; null<br>                  - type          = &quot;CanonicalUser&quot; -&gt; null<br>                    # (3 unchanged attributes hidden)<br>                }<br>            }<br>          - owner {<br>              - id           = &quot;9da783ff7be6e9971d5ad7ce8956eb03ea19ecbe4c1250ace4ad596753f83e80&quot; -&gt; null<br>                # (1 unchanged attribute hidden)<br>            }<br>        }<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_ownership_controls.this[0] will be destroyed<br>  - resource &quot;aws_s3_bucket_ownership_controls&quot; &quot;this&quot; {<br>      - bucket = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - id     = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - region = &quot;us-east-1&quot; -&gt; null<br><br>      - rule {<br>          - object_ownership = &quot;ObjectWriter&quot; -&gt; null<br>        }<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_public_access_block.this[0] will be destroyed<br>  - resource &quot;aws_s3_bucket_public_access_block&quot; &quot;this&quot; {<br>      - block_public_acls       = false -&gt; null<br>      - block_public_policy     = false -&gt; null<br>      - bucket                  = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - id                      = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - ignore_public_acls      = false -&gt; null<br>      - region                  = &quot;us-east-1&quot; -&gt; null<br>      - restrict_public_buckets = false -&gt; null<br>      - skip_destroy            = true -&gt; null<br>    }<br><br>  # module.s3_bucket.aws_s3_bucket_versioning.this[0] will be destroyed<br>  - resource &quot;aws_s3_bucket_versioning&quot; &quot;this&quot; {<br>      - bucket                = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - id                    = &quot;catalyst-example-bucket&quot; -&gt; null<br>      - region                = &quot;us-east-1&quot; -&gt; null<br>        # (1 unchanged attribute hidden)<br><br>      - versioning_configuration {<br>          - status     = &quot;Enabled&quot; -&gt; null<br>            # (1 unchanged attribute hidden)<br>        }<br>    }<br><br>Plan: 0 to add, 0 to change, 5 to destroy.<br><br>Do you really want to destroy all resources?<br>  Terraform will destroy all your managed infrastructure, as shown above.<br>  There is no undo. Only &#39;yes&#39; will be accepted to confirm.<br><br>  Enter a value: yes<br><br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Destroying... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Destroying... [id=catalyst-example-bucket,public-read]<br>module.s3_bucket.aws_s3_bucket_acl.this[0]: Destruction complete after 0s<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Destroying... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_ownership_controls.this[0]: Destruction complete after 1s<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Destroying... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket_public_access_block.this[0]: Destruction complete after 0s<br>module.s3_bucket.aws_s3_bucket_versioning.this[0]: Destruction complete after 1s<br>module.s3_bucket.aws_s3_bucket.this[0]: Destroying... [id=catalyst-example-bucket]<br>module.s3_bucket.aws_s3_bucket.this[0]: Destruction complete after 1s<br>Releasing state lock. This may take a few moments...<br><br>Destroy complete! Resources: 5 destroyed.</pre><h3>Additional Examples</h3><p>The <a href="https://github.com/terramate-io/terramate-catalyst-examples">terramate-catalyst-examples</a> repository also comes with additional examples that focus on more complex use-cases such as multi-state deployments and dependencies among Bundles.</p><h3>VPC and ALB (<a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/bundles/example.io/tf-aws-vpc-alb/v1/bundle.tm.hcl">tf-aws-vpc-alb</a>)</h3><p>Creates and manages a VPC with public and private subnets, NAT gateway, and an Application Load Balancer infrastructure. The ALB is configured with a basic HTTP listener, and target groups and routing rules are automatically added when deploying ECS services.</p><ul><li>Creates a VPC with public and private subnets</li><li>Sets up NAT Gateway and Internet Gateway</li><li>Deploys an Application Load Balancer (ALB) in public subnets</li><li>Provides foundational networking infrastructure</li><li>Manages VPC and ALB in different state files</li></ul><h3>ECS Fargate Cluster (<a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/bundles/example.io/tf-aws-ecs-fargate-cluster/v1/bundle.tm.hcl">tf-aws-ecs-fargate-cluster</a>)</h3><p>Creates and manages an ECS Fargate cluster on AWS with a default capacity provider strategy that balances cost savings (Fargate Spot) with reliability (Fargate on-demand).</p><ul><li>Creates an ECS Fargate cluster</li><li>Configures capacity provider strategy (Fargate Spot + on-demand)</li></ul><h3>ECS Fargate Service (<a href="https://github.com/terramate-io/terramate-catalyst-examples/blob/main/bundles/example.io/tf-aws-ecs-fargate-service/v1/bundle.tm.hcl">tf-aws-ecs-fargate-service</a>)</h3><p>Creates and manages an ECS Fargate service that can be attached to existing ECS clusters, VPCs, and Application Load Balancers. It uses filter tags to discover and reference existing infrastructure resources created via the above-mentioned bundles using data sources.</p><ul><li>Creates an ECS Fargate service attached to existing cluster, VPC, and ALB</li><li>Uses AWS data sources to discover resources by tags</li><li>Configures container definitions and load balancer integration</li></ul><h3>Summary</h3><p>That’s it, you just learned how to use Terramate Catalyst to provide self-service for your non-infra-expert developers. They can now deploy a lot of standardized, secure, and compliant infrastructure in almost no time without DevOps support: Essentially the promise of AI infra but without the probabilistic nature of AI.</p><p>If you’d like to have an expert look at your infra self-service potential, feel free to <a href="https://terramate.io/demo/">schedule a meeting with us</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fad8852cddb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/technical-introduction-to-terramate-catalyst-3fad8852cddb">Technical Introduction to Terramate Catalyst</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing the Terramate MCP Server]]></title>
            <link>https://medium.com/terramate/introducing-the-terramate-mcp-server-27c741b9dfed?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/27c741b9dfed</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[mcp-server]]></category>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <dc:creator><![CDATA[Selina Nazareth]]></dc:creator>
            <pubDate>Thu, 13 Nov 2025 16:02:05 GMT</pubDate>
            <atom:updated>2025-11-13T16:02:05.054Z</atom:updated>
            <content:encoded><![CDATA[<p>Author: <a href="https://medium.com/u/b74e93d5ed97">Sören Martius</a> | Chief Product Officer at Terramate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SM8GWgXAA1LEcr0JxPLUqw.png" /></figure><p>At Terramate, we believe Infrastructure as Code enables innovation and plays a fundamental role in the cloud-native era. That’s why we are building <a href="https://cloud.terramate.io/">Terramate</a>, the Infrastructure as Code development platform that helps teams to organize, transform and rapidly speed up their Terraform and OpenTofu projects.</p><p>As part of the rise of AI-native IDEs such as Claude Code, Cursor, or Zed, it becomes more relevant to bring the right context into those IDEs. To enable those workflows, we just released the Terramate MCP (<a href="https://modelcontextprotocol.io/">Model Context Protocol</a>) Server.</p><p>The Terramate MCP Server enables you to integrate context from your Terramate Cloud organization, including Pull Request Previews, Deployments, Alerts for drift and policy violations, and Asset Inventory, into your IDE to facilitate better AI-driven workflows.</p><p>Built for developers who want to connect their AI tools to Terramate context and capabilities, from simple natural language queries to complex multi-step agent workflows.</p><h3><a href="https://terramate.io/rethinking-iac/introducing-the-terramate-mcp-server/#what-you-can-do-with-mcp">What You Can Do With MCP</a></h3><p>The Terramate MCP Server unlocks valuable use cases by allowing developers to work with Terramate using natural language. To mention a few:</p><ul><li>💬 Chat with your code base: You can now discover and understand stacks and resources available in a repository.</li><li>🔍 Drift Detection: View drift runs and retrieve Terraform plan outputs for AI-assisted reconciliation.</li><li>🔀 Preview Integration: Review terraform plans for all stacks in PRs/MRs before merging and deploying.</li><li>🚢Deployment Tracking: Monitor CI/CD deployments, view Terraform and OpenTofu logs to debug failures.</li><li>🛠 Fix Misconfigurations: Fix policy misconfigurations directly inside your IDE with AI.</li><li>📊 Reporting Use Case: Create reports about your Terramate projects in your IDE using natural language.</li></ul><p>For a demo, please watch the video below.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fmp9v3N1KlEQ%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dmp9v3N1KlEQ&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fmp9v3N1KlEQ%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c99a6059d59f35921fcd9f2cf496d12/href">https://medium.com/media/0c99a6059d59f35921fcd9f2cf496d12/href</a></iframe><h3><a href="https://terramate.io/rethinking-iac/introducing-the-terramate-mcp-server/#try-it-out">Try it out</a></h3><p>The Terramate MCP Server is now available as an open-source project at <a href="https://github.com/terramate-io/terramate-mcp-server">https://github.com/terramate-io/terramate-mcp-server</a>. Currently, you must run it locally with Docker, then follow our <a href="https://github.com/terramate-io/terramate-mcp-server?tab=readme-ov-file#using-docker">installation instructions</a> and start interacting with your environments directly from your IDE. In the future, we will integrate the MCP Server directly into Terramate Cloud.</p><p>The MCP Server is currently under heavy development, with new features being added regularly. Stay tuned for future updates and workflow enhancements.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=27c741b9dfed" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/introducing-the-terramate-mcp-server-27c741b9dfed">Introducing the Terramate MCP Server</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Terramate Catalyst Beta, AWS Marketplace Availability]]></title>
            <link>https://medium.com/terramate/terramate-catalyst-beta-aws-marketplace-availability-fda9a80dd2d3?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/fda9a80dd2d3</guid>
            <category><![CDATA[terramate]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[opentofu]]></category>
            <category><![CDATA[iac]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Selina Nazareth]]></dc:creator>
            <pubDate>Tue, 04 Nov 2025 10:12:07 GMT</pubDate>
            <atom:updated>2025-11-04T10:12:07.026Z</atom:updated>
            <content:encoded><![CDATA[<p>Author: <a href="https://medium.com/u/b74e93d5ed97">Sören Martius</a> | Chief Product Officer at Terramate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nUcPWb58p6TMrgHBJb1h5A.png" /></figure><p>Hello team,</p><p>We’re excited to share our latest updates designed to improve your experience with Terramate. Read on to discover what our team has been working on!</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-beta-aws-marketplace-availability/#terramate-catalyst-is-now-in-private-beta">Terramate Catalyst is now in private beta</a></h3><p>Since our <a href="https://github.com/terramate-io/terramate/issues/2052">announcement</a> back in February, we’ve been working hard to bring Terramate Catalyst (formerly named “Terramate Scaffolding”) to market. Today, we’re equally excited and proud to launch the private beta of Terramate Catalyst, which will redefine how developers provision and manage infrastructure.</p><p>Terramate Catalyst enables developers and AI Agents to provision, manage, and secure cloud infrastructure in self-service while, at the same time, allowing platform teams to retain full control by centrally defining and enforcing how infrastructure is provisioned using Infrastructure as Code tools such as Terraform or OpenTofu.</p><p>As of today, most platform teams are providing developers with a catalog of Terraform modules, often called a service catalog. But this approach comes with several challenges:</p><ul><li>Developers still need to learn Terraform/OpenTofu and know about implementation details, such as how to define state backends.</li><li>Developers often struggle with an overwhelming amount of configuration options (aka variables). For example, the well-adapted <a href="https://github.com/terraform-aws-modules/terraform-aws-eks">terraform-aws-eks</a> module exposes 101 input variables.</li><li>Current approaches only partially mitigate the problem by focusing mostly on the initial deployment of infrastructure (day 1) and completely ignoring the need for contentious maintenance, such as provider and module updates.</li></ul><p>With Terramate Catalyst, platform engineers can now provide simple-to-use CLI, GUI and prompt-driven workflows via an MCP server, allowing engineers to scaffold and continuously update complex infrastructure without having to know any Infrastructure as Code tools or cloud services in detail, leading to faster deployment cycles and reduced cognitive load.</p><p>At the same time, it allows platform teams to retain full control by centrally defining and enforcing how infrastructure is provisioned using Infrastructure as Code tools such as Terraform or OpenTofu. The nicest thing about Terramate Catalyst is that it seamlessly integrates with an existing Terraform module catalog, making the onboarding and migration as seamless as possible without requiring any migration effort.</p><p>Watch our 5-minute demo to see Terramate Catalyst in action.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F2ywtelqSvxc%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D2ywtelqSvxc&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F2ywtelqSvxc%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4bfae723e03f516e6bc9c96b0df55ecd/href">https://medium.com/media/4bfae723e03f516e6bc9c96b0df55ecd/href</a></iframe><p>Terramate Catalyst is now in closed beta. To get access, please <a href="https://terramate.io/demo/">book a demo</a> with one of our experts.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-beta-aws-marketplace-availability/#streamlined-pull-request-previews">Streamlined Pull Request Previews</a></h3><p>Previews of changes in Pull Requests are one of the most important features in Terramate Cloud, allowing teams to review critical infrastructure changes before deploying them. We have fundamentally redesigned the Pull Request previews feature in Terramate Cloud, which now allows teams to review all changes on a per-stack basis, review CI/CD logs, summarize changes with AI, and even more advanced concepts, such as showing state migrations on a per-stack basis. The new view allows teams to review changes even more efficiently, leading to higher deployment frequency and faster lead time for changes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ona_hpA2w5rpB_Ufngq-vw.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-beta-aws-marketplace-availability/#aws-marketplace-availability">AWS Marketplace Availability</a></h3><p>Terramate Cloud is now available for purchase on <a href="https://aws.amazon.com/marketplace/pp/prodview-dud2pxnrtgphk?sr=0-1&amp;ref_=beagle&amp;applicationId=AWSMPContessa">AWS Marketplace</a>. With this availability, AWS customers with existing AWS spend commitments can use their Terramate Cloud purchase against their AWS commitment. The streamlined contractual and legal terms of AWS Marketplace also make for a faster, more straightforward buying process.</p><p>We’ve also created our AWS Marketplace Vendor Insights profile to streamline the exchange of security and compliance information, accelerate transactions, and improve the transactional experience while streamlining our sales process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4oFLzG65XLHl1qjj0KoxGQ.png" /></figure><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-beta-aws-marketplace-availability/#better-collaborator-mapping">Better Collaborator Mapping</a></h3><p>Collaborators are a key concept in Terramate Cloud, allowing you to assign Alerts, Pull Requests and Deployments to members of your organization. In addition to automatic mapping, we just added the option to manually map your e.g., GitHub, GitLab, Bitbucket, Slack, etc. users to the right users in Terramate Cloud. This ensures that events, such as Alerts, are always assigned to the right person and thus ownership can be managed seamlessly, leading to faster response times and improvements in your <a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate">DORA metrics</a>.</p><h3><a href="https://terramate.io/rethinking-iac/terramate-catalyst-beta-aws-marketplace-availability/#minor-changes">Minor Changes</a></h3><ul><li>We released <a href="https://github.com/terramate-io/terramate/releases/tag/v0.14.7">Terramate CLI v0.14.7</a><a href="https://github.com/terramate-io/terramate/releases/tag/v0.14.0">,</a> which now supports the latest Terragrunt versions. Terramate will now detect the installed Terragrunt version and set the appropriate internal command-line flags.</li></ul><p>As always, we appreciate your feedback and support.</p><p>The Terramate Team 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fda9a80dd2d3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/terramate-catalyst-beta-aws-marketplace-availability-fda9a80dd2d3">Terramate Catalyst Beta, AWS Marketplace Availability</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to improve your DORA Metrics with Terramate]]></title>
            <link>https://medium.com/terramate/how-to-improve-your-dora-metrics-with-terramate-ad884caf9148?source=rss----467b6143fa7---4</link>
            <guid isPermaLink="false">https://medium.com/p/ad884caf9148</guid>
            <dc:creator><![CDATA[Selina Nazareth]]></dc:creator>
            <pubDate>Wed, 30 Jul 2025 12:26:16 GMT</pubDate>
            <atom:updated>2025-07-30T12:26:16.007Z</atom:updated>
            <content:encoded><![CDATA[<p>Author: <a href="https://medium.com/u/9e0999b709c1">Chris Schagen</a> | Chief Executive Officer at Terramate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qm5EsITtTqVKvjvC-K4F5w.png" /></figure><p>In our previous articles, we discussed <a href="https://terramate.io/rethinking-iac/the-importance-of-dora-metrics-in-infrastructure-automation/">the importance of DORA Metrics in Infrastructure Automation</a> and how Terramate Cloud now gives you an <a href="https://terramate.io/rethinking-iac/announcing-dora-metrics-in-terramate-cloud/">out-of-the-box way to measure DORA metrics</a> quickly.</p><p>Now, we want to explore what platform teams can do to improve DORA metrics.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#split-your-state-into-smaller-stacks">Split your state into smaller stacks</a></h3><p>At Terramate, we have always been proponents of splitting your state files into independent units of deployment with small state: the Terramate Stack. If stacks are sized in <a href="https://terramate.io/rethinking-iac/how-to-structure-and-size-terraform-stacks/">the “Goldilocks” zone</a>, you can address a host of <a href="https://terramate.io/rethinking-iac/why-you-should-break-down-your-terraform-into-stacks/">problems of large state files</a> commonly referred to as <a href="https://masterpoint.io/blog/terralith-monolithic-terraform-architecture/">Terraliths</a>.</p><p>But in the context of DORA metrics, other key qualities of smaller stacks emerge:</p><ul><li>Better Reviews — when stacks are smaller, there is a lot less context and thus ground to cover in a review. Which — especially for engineers who don’t know the whole codebase by heart — is a huge benefit to be able to make sense of a Terraform Plan quickly. And the faster the review, the faster the Change Lead Time.</li><li>Clear Ownership Model — the old adage “divide and conquer” (attributed to Julius Cesar) also applies in complex infrastructure. Having small stacks allows for a much simpler establishment of an ownership model, so that the team can specialize and get to a high competency level of “their” part of the codebase faster. Which in turn leads to a better Deployment Rate as well as a faster Change Lead Time.</li></ul><p>And this is in addition to faster deployments (which help with Change Lead Time, Deployment Rate, and MTTR) as well as smaller blast radii (which help with Change Failure Rate).</p><p>So small is beautiful… at least when it comes to improving DORA metrics.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#tune-your-infrastructure-automation">Tune your infrastructure automation</a></h3><p>While even in year 2025, there seems to be <a href="https://www.linkedin.com/posts/ned-bellavance_what-are-people-using-to-automate-their-iac-activity-7320858917624823809-OR6h?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAAAGRUBsw-ilTCco7tQZyKvXl2eCRtlrQE">24% of companies doing manual Terraform/IaC deployments</a>, 76% area already automating. And tuning your automation can yield a number of improvements on the DORA front as well.</p><ul><li>Granular Orchestration — building on the state splitting above: Once you have a plethora of stacks and an (implicit or explicit) relationship graph between those stacks, you can use all kinds of filters to make more precise deployments. E.g., you can filter by directory, by tag, by environment, by changes, heck with Terramate Cloud you can even do stateful orchestration and filter by drifted and failed stacks. You can also ideally combine multiple dimensions, think filter all changed stacks in staging with the tag networking. The more granular your orchestration, the simpler your pull request, the faster your preview, the faster your review, and the faster and less risky your deployments.</li><li>GitOps — following a GitOps flow may initially appear to add to the Change Lead Time. But if you have fast pipelines, that added cost may be trivial (seconds to minutes) compared to the benefits. With GitOps, you obtain auditability, versioning, reproducibility, and a single source of truth. All of which actually help the Change Lead Time, but even more so the Change Failure Rate and MTTR.</li><li>Change Detection — at Terramate, we are big on <a href="https://terramate.io/docs/cli/change-detection/">only running plans and applies on changes</a>. That way, the amount of infra that has to go through the pipeline is greatly reduced, massively speeding up the deployments and also enabling the team to collaborate in parallel, especially if you have already established an ownership model (see above).</li><li>Parallelism — the icing on your cake would be <a href="https://terramate.io/docs/cli/orchestration/parallel-execution">to add massive parallelism in your pipelines</a>, which requires you to again have a sound dependency graph as well as independently deployable stacks.</li></ul><p>The above laundry list helps you improve all four DORA metrics.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#monitor-route-alerts">Monitor &amp; route alerts</a></h3><p>In order to improve the reliability metrics MTTR and Change Failure Rate, by definition, you need to be able to quickly detect that something went wrong in the first place. Only then you can take action.</p><ul><li>Failure Detection — the crux with the plan and apply phases of Terraform and OpenTofu is that sometimes plans are smooth sailing, and then at the apply phase, errors emerge. Even worse, sometimes you have partially applied plans, leaving you in a state of limbo and unsure of what is actually going on. For that reason, at Terramate we always urge you to run a health check with means that you should run another plan after an apply to detect any partially applied plans or drift which validates the integrity of your previously applied changes.</li><li>Pinpoint Visibility — once you know that a deployment has (partially) failed, it is often great to have tooling in place that shows you exactly which resources of the plan have been applied and how the remaining plan looks like. So that the detective work of finding the remaining needle in the plan file “haystack” is reduced to a mere trivial lookup.</li><li>Alerting — the best monitoring is worth little if the people causing the trouble or the people best placed to apply the fix don’t know about the issues in the first place. Alerts are often routed to shared Slack channels, which many teams we talk to consider as too noisy. Alternatively, if you have an implicit ownership model from your Pull Requests, you can route <a href="https://terramate.io/rethinking-iac/archiving-stacks-alerts-2-0-us-launch-and-better-notifications/#alerts-2.0">individual Slack alerts directly to the collaborators on a PR</a>.</li></ul><p>The faster your team learns about an issue, and where the issue is, the easier it is to improve the MTTR.</p><p>Interestingly, one phenomenon we see is that once your whole pipeline is really rapid, and the MTTR is blazingly fast, teams are okay in tolerating a little more risk and accept a higher Change Failure Rate knowing that eventual failures are essentially transient and very short-lived.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#standardize-your-codebase">Standardize your codebase</a></h3><p>While in our everyday life we tend to encounter a lot of <a href="https://itnext.io/the-insidious-problem-of-configuration-sprawl-66360fce6ca3">sprawling codebases</a> with artisanal “units of one”, the <a href="https://itnext.io/variant-generation-is-the-primary-capability-of-infrastructure-as-code-773e6b404b49">true superpower of Infrastructure-as-Code is variant generation</a>. The idea is that the more standardized a codebase is, the easier it is to comprehend and act on, improving your Change Failure Rate, Change Lead Time, and overall Deployment Rate.</p><ul><li>Use Modules — modules are reusable configurations that can be used to manage a collection of related infrastructure resources. Think of them like functions in a programming language, but for infrastructure. Instead of writing the same block of Terraform code repeatedly for similar resources, you can define it once as a module and then call that module whenever you need to deploy that specific set of resources. Note that you want to be careful to <a href="https://www.linkedin.com/pulse/iac-paradox-how-sophistication-can-lead-catastrophe-freitas-msc--zlyif/">not create a cascade of dependencies between modules</a>, but still keep things simple, as module overuse can come at the expense of readability. Also, module consumption can be quite challenging for non-infra experts.</li><li>Code Generation — with code generation, you can strike a balance between readability of your codebase and DRYness. At Terramate, we are naturally big believers in code generation, as it allows you to generate your IaC code from templates and customize those with shared variables we call “Globals”. The net outtake is that some problems — e.g. backend generation — can be completely abstracted away with code generation.</li><li>Scaffolding — with scaffolding, you can separate the concerns of infrastructure experts in your platform teams from those that are non-expert infrastructure consumers, i.e., your developers who are building apps. Experts pre-configure outcome-oriented “Terramate Bundles” that are tested, governed, compliant, and structured in a way that the platform team always retains full control. Infrastructure consumers, however, don’t need to know anything about Terraform or OpenTofu to just scaffold their database or message queue; they just get the job done.</li></ul><p>With standardization, managing large-scale IaC codebases becomes a lot easier, making failures a much less frequent concern while also accelerating Change Lead Time and Deployment Rate.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#train-your-team">Train your team</a></h3><p>But even the best-tuned automation, the most elegant standardization, the most sophisticated architecture, it all is for naught if your team is poorly trained.</p><p>Train them so they are familiar with the codebase. Show them how the pipelines work. Introduce them to your tooling. And especially provide them with context around all the things that can and will go wrong, regardless of the errors and failures that may occur. <a href="https://terramate.io/rethinking-iac/introducing-ai-mate/">Enrich with AI when helpful</a> to make errors more accessible.</p><p>As the old adage attributed to Evan Kirshenbaum says: “An employer once said, ‘What if I train my people and they leave?’ I say, what if you don’t train them… and they stay…”.</p><h3><a href="https://terramate.io/rethinking-iac/how-to-improve-your-dora-metrics-with-terramate/#our-mission">Our mission</a></h3><p>At Terramate, our mission is to help organizations massively improve their infrastructure practices. It all starts with measuring things and creating transparency, because what you measure will get done.</p><p>From DORA metrics out, we strive to help you improve on all the 5 vectors above, providing you with tooling to assist you on your journey to elite DORA metrics and highest infrastructure maturity.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ad884caf9148" width="1" height="1" alt=""><hr><p><a href="https://medium.com/terramate/how-to-improve-your-dora-metrics-with-terramate-ad884caf9148">How to improve your DORA Metrics with Terramate</a> was originally published in <a href="https://medium.com/terramate">Terramate Blog</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>