Blog

Authoring Modules for Developers, Not for DevOps

Written by Kunal Dabir | Jul 14, 2026, 4:00:00 PM

The single biggest predictor of whether developer self-service works isn't the platform. It's whether your platform team treats module authoring as a product, and authors for developers instead of for other DevOps engineers.

Part 6 of 6 in the Aiden for InfraOps series. Start with the series overview »

The short version

  • Real developer self-service requires a mindset shift: platform teams become product owners who design and curate a catalog of high-level, domain-specific Modules built for developers.
  • Two anti-patterns sink it. The "library dump" imports your whole Terraform library (say, 400 Modules) and hands developers a side panel of 200 variables. The "glorified form" locks an imported appStack and exposes a few fields, killing all flexibility.
  • Principle 1: hide complexity, expose intent. A developer wants "user storage," not `aws_s3_bucket` with 50 variables.
  • Principle 2: bake organizational semantics into the Module, so a "network" block is a data-source lookup of the existing VPC, not a new one.
  • Principle 3: the author must experience the developer's view. Authoring inside the appStack UI makes a bad, 200-variable Module feel bad, which forces a better one.

For Aiden for InfraOps to deliver on true developer self-service, platform teams have to change how they think about their own job. The most common failure isn't technical. It's treating the platform as a simple passthrough for an existing Terraform library, when the job is actually to design something new.

The shift is from plumber to product owner. A platform team's mandate becomes designing, curating, and maintaining a catalog of high-level, domain-specific Modules tailored for one specific audience: the developers who will consume them. This post covers the two ways teams get this wrong, and the three principles that get it right.

Two anti-patterns that kill self-service

Before the principles, the traps. Both are common, both feel reasonable, and both quietly prevent the self-service they're meant to enable.

The "library dump"

The most frequent anti-pattern is the library dump. A team adopts the platform and immediately imports its entire existing library of Terraform Modules, sometimes 400 of them, straight into the catalog. Done. Surely more Modules is more value.

It isn't, and the reason is who those Modules were written for. They were written by DevOps engineers, for other DevOps engineers. They're low-level, complex, and they expose every possible configuration option, because that's the right design when your audience is an infrastructure expert.

Hand that to the actual consumer and the experience collapses. A developer drags one of these Modules onto the appStack canvas and is immediately confronted with a side panel of 200 variables. That is not self-service. It's overwhelming, effectively unusable, and it exposes the developer to implementation details they should never have to think about. The catalog is technically full and practically empty. (The catalog's job is curation, not volume; see Why Your Module Catalog Isn't an IDE.)

The "glorified form"

The natural overcorrection is worse. Stung by the library dump, a platform engineer swings to total lockdown, sometimes called the Backstage flow. The recipe: use an import tool to bring in an existing, complex environment, lock the resulting appStack so the developer can't change the architecture, and expose a few select variables to fill in, like an image tag or a port number.

This turns the platform into a glorified form, and we reject it deliberately, for four reasons:

  • Brittleness. It's a static template. It can't be cleanly versioned or upgraded, and it allows no flexibility.
  • Restricted freedom. It absolutely curtails developer freedom. It prevents developers from using the appStack canvas to compose, experiment, or build anything new.
  • Lack of self-service. It's a rigid, top-down provisioning model, which is precisely the legacy workflow the platform exists to replace.
  • Obscured value. If the platform is just a UI wrapped around a git commit, it isn't providing differentiated value. Developers correctly perceive it as one extra step and a hindrance.

The library dump overwhelms developers with control they can't use. The glorified form removes all control and calls it safety. Neither is self-service. The way out is between them.

The philosophy: build domain-specific abstractions

The real role of the platform team is to be an enabler and a translator. (That Enabler archetype is its own subject in Enablers vs. Accelerators.) You use your deep technical expertise to build a new layer of high-quality Modules that abstract away cloud complexity and expose developer intent. These aren't thin wrappers. They're opinionated, purpose-built, semantically rich products. Three principles make them work.

Principle 1: Hide complexity, expose intent

Developers don't think in cloud primitives like S3 or IAM. They think in application concepts: "user storage," "a website," "somewhere to put uploads." The Modules they consume should reflect how they think, not how the cloud is built.

Compare the options. A bad Module is aws_s3_bucket: it exposes 50 variables for versioning, logging, replication, IAM policies, lifecycles, and everything else. A good Module is Static-Content-Repository, which exposes two variables — ContentPath and EnableCDN? — and is internally pre-configured by the platform team as a public-read website bucket, with versioning and logging correctly implemented and hidden. An even tighter one is User-Generated-Document-Storage, which exposes a single variable, name, and is pre-configured as a private S3 bucket with a pre-signed-URL policy baked in, ready to connect to an application API.

Same underlying resource. Wildly different products. The developer chooses intent and gets fifty correct decisions for free.

Principle 2: Bake organizational semantics into the Module

This is the most important principle. The Module itself should encode your organization's rules, logic, and best practices. The clearest illustration is the data-source-versus-resource problem.

The VPC scenario. A developer drags a generic VPC Module onto the canvas. It provisions a new VPC, which is almost never the right thing to do in an established organization. The fix isn't to train every developer on networking. It's to not offer a generic VPC Module at all. Instead the platform team provides a Module named Production-Network or User-Facing-Network, implemented internally as a Terraform data source rather than a resource. It looks up the existing network. The developer never needs to know the difference: they drag the "network," connect it to their EKS cluster, and it works, safely and correctly. (More on data-source-backed Modules.)

The Lambda artifact scenario. A developer needs to reference their code's .zip file, which lives in an S3 bucket. With a generic S3 Module, they're forced to figure out how to configure it as a data source, when all they wanted was to connect their source code to a Lambda function. The fix is an Artifact-Repository Module: the developer drags it, connects it to their Lambda Module, and provides the function name. The Module internally handles referencing the correct bucket and key.

In both cases the Module becomes an abstraction not just of the cloud resource, but of its correct usage within your organization. That's the semantic layer generic modules can't provide.

Principle 3: The author must experience the developer's view

The first two principles are easy to nod along to and hard to actually do, because of a perception gap. When a DevOps engineer writes a Module in an IDE, 200 variables don't feel like a problem. It's just text in a file; you scroll past it. The author has no felt sense of the experience they're creating.

This is the core justification for the appStack-owned Module, or sandbox, feature. When that same engineer authors the Module inside the appStack UI, the feedback is instant and tangible. They see the mile-long scroll on the right-hand side panel. They feel the poor developer experience they're about to ship. (More on the sandbox authoring feature.)

That feedback loop — see the render, edit the code, see the render again — is what forces the author to think like an end user and iterate toward something simpler and more purposeful. You can't design a good consumer experience you never have to look at. Authoring in the consumer's view is what closes the gap.

What good looks like

Put the principles together and the developer's world changes shape. Instead of being handcuffed to a static template, or drowning in a 200-variable panel, the developer gets a palette of powerful, safe, intelligent building blocks with names like Production-Database, CMS-Team-EKS, and Artifact-Repository. They compose those blocks on the appStack canvas to build new and valuable applications, confident that the organizational rules and best practices are already baked in. (Composition on the canvas is the consumer half of the producer-consumer model in Modules vs. appStacks.)

This is the heavy lifting Aiden for InfraOps is designed to enable, and it's the differentiated value that separates a real platform from a simple AI wrapper or a basic GitOps flow: a real-time, productive producer-consumer loop for infrastructure, where the platform team's expertise is encoded into blocks and developers build freely and safely on top of them.

What this means for you

If you're on a platform team, your highest-leverage work isn't importing what you already have. It's authoring the domain-specific layer that doesn't exist yet. Start by naming the application concepts your developers actually reach for — storage for uploads, a network to attach to, a place to put a build artifact — and build a small number of opinionated Modules for those, with intent on the outside and complexity hidden inside. Author them in the appStack view so you feel what your developers will feel. Resist both the urge to dump everything and the urge to lock everything.

Do that and self-service stops being a slogan. It becomes the natural result of good blocks in the hands of developers who can finally build without either being overwhelmed or being boxed in.

Continue the Aiden for InfraOps series

← Previous — Part 5: Meeting Teams Where They Are: A Terraform Maturity Guide

See all six parts in the series overview »