IaC Monkey Business

Abstract

Terraform provides the tools to manage Infrastructure as Code (IaC) configuration, but architecture, shared policy, and deployment remain our responsibility. My five-layer IaC methodology is one way to structure those responsibilities. It's simple enough for individual devices, yet scalable across entire fleets. A disciplined approach prevents the monkey business that turns IaC into module soup.

Background

A co-worker once asked me, "What do you think about Terraform and Ansible?" I replied, "Any monkey can push a button." After all, it's only a glorified network configuration manager (NCM), isn't it? The answer to that question is more fun than a barrel of monkeys.

CLI vs NCM vs IaC

Network management is entirely situational. There's no perfect one-size-fits-all solution. I respect a clean CLI. It's a quick and satisfying way to make changes. Indeed, the CLI paired with a solid NCM solution is entirely justifiable. It gives you form and function with the ability to roll back changes from previous versions. But the truth is, the CLI and NCM have limitations.

The CLI is single purpose. It's designed around interacting with one device at a time, which is entirely defensible if you manage ten to twenty devices. But it becomes inefficient at scale. What happens if you need to manage one hundred devices? Five hundred?

Beyond logistics, scale introduces the potential for mistakes or drift. People make mistakes. Mistakes have consequences. They can lock you out of a device. They can bring down service. They can open ports that leave your resources vulnerable to exploits. In some ways, the only difference between a net admin and a monkey is version control.

Even when CLI is scripted across many devices, it remains fundamentally device-centric. Infrastructure as Code (IaC) is different. It makes desired state explicit, repeatable, and manageable.

Monkey Wrench

CLI is like a handsaw. Measure once and cut. It's maximum simplicity and control over a single device. NCM + CLI is like upgrading to a circular saw and then measuring twice. Your work can quickly be rolled back to a previous state from any device. IaC is like working with a table saw, for when repeatable accuracy matters most.

But a table saw doesn't automatically produce better work. It produces more efficient work—the same repeatable cuts at scale. However you cut it, the final work depends on the craftsman behind the blade. The same is true of IaC. The tool is only as useful as the architecture.

Methodology

IaC can work like all three tools: a simple handsaw, a circular saw, or a beefy table saw. The difference boils down to how we structure the work. What follows is a custom Five-Layer IaC abstraction model. It is vendor-neutral and reusable beyond any particular tool or platform. Each layer answers a distinct question, and each is dependent on the previous. Each layer is insufficient on its own.


Layer 1: Structure

Where does everything belong?

Define the Git repository and how its components are organized.

  • Local, server, or cloud-based repository
  • Comprised of a flat Git repository
  • Scope wide and never deep

Without a deliberate structure, the repository becomes a disorganized junk drawer. At scale, you cannot find what you need, changes drift, and the next administrator inherits the mess. Structure is the foundation that makes every other layer possible.

Layer 2: Roles

How are components related?

Decide how devices and groups are classified and related. Child directories align perfectly with roles:

Device_intent: Dedicated 1:1 folders for managed nodes. Each folder contains respective configuration files. Terraform applies all files to the node.

Shared_policy: Dedicated 1:N folders for groups of managed nodes. Each nested folder contains respective configuration files that disseminate to all devices within the group. All files are applied to all devices in the group.

Templates: Dedicated 1:1 folders per model. Configuration contains placeholder stanzas intended for new rollouts. Simply copy the template to its respective new device or group directory.

Structure alone does not tell you how devices relate to one another. Roles make the relationships explicit: which devices are unique, which share policy, and which are starting points for new deployments. This prevents both duplication and accidental divergence.

Layer 3: Identity


How do we consistently identify nodes and shared policy?

We implement a naming convention that represents more than simple identification:

  • Device names: City-Vendor-Function-Model-ID (e.g., chi-jun-fw-1500-n0)
  • Group names: Group_identifier-city-vendor-function (e.g., Grp-mke-mt-fw)
  • TF Config Files: Align with vendor configuration stanza (e.g., ip_firewall_filter.tf)

Consistent identity makes automation reliable and allows human review. Each resource name encodes location, vendor, function, and role. It turns a directory listing into a map.

Layer 4: Policy

How do we enforce configurations and behaviors?

  • Policy determines how group and local device configurations apply in tandem.
  • Apply naming convention to configuration statements or comments (-grp / -loc).
  • Determine explicit precedence and order of operation.

This is where the methodology becomes concrete. For example, our RouterOS configuration establishes a "group" forwarding chain shared among its respective nodes. That chain includes a jump rule to a similar "device" chain. Configuration for the respective chain is entirely optional and configured per device. This process provides exceptions and preserves the default-deny ACL located in the group stanza.

Roles and identity tell you what exists and how it is named. Policy decides what actually happens when shared and local configurations meet. Without explicit precedence, you get silent overrides, surprising behavior, and configurations that cannot be reasoned about.

Policy impacts both group and individual devices. It's not a setting you can toggle. It's all derived from our custom methodology. It's the secret sauce that makes IaC unique.

Layer 5: Orchestration

How do we review and deploy changes?

Orchestration defines how configurations are reviewed and deployed. Its operational processes can include Git revisions, OpenTofu plans, reviewed applies, and Bash deployment scripts.

Each device maintains independent state, even when multiple devices consume the same shared policy. Shared configuration does not imply shared deployment fate. Our Bash orchestration is intentionally simple: select a group, iterate through its device roots, review plans, apply deliberately, and stop on failure. No elaborate management platform is required.

The previous layers produce a desired state. Orchestration is how that state is safely deployed. Independent state means a failure on one device does not cascade. The deliberate, reviewable process ensures the human-in-the-loop. It's monkey see and monkey do—in the best possible way. Engineering solutions do not require complexity.

RBAC vs IaC

I use a methodology similar to RBAC, but adapted for infrastructure as code. The roles are not security groups—they are the managed nodes and the groups those nodes belong to. The organization of the repository and the naming conventions do the heavy lifting. Everything is kept flat so I can quickly identify and work with a single device or an entire group.

The primary distinction is between the device directory and the shared policy directory. The device directory holds configuration that is unique to that node. The shared policy directory holds configuration that applies to every device in a given group. Reconciling the two is deliberate: shared policy is applied first, then local exceptions are layered on top under explicit precedence rules, with a final default deny. That keeps group consistency without preventing device-specific overrides.

These are different mechanisms from traditional RBAC, but they share a useful conceptual pattern: roles establish relationships, and those relationships determine how policies are applied. In both cases, the role is a layer of indirection that keeps the rules themselves simpler and more maintainable. The difference is what the role is organizing—authorization on one side, configuration ownership on the other.

See, Hear, and Speak no Evil

IaC without a coherent system is one more banana peel to slip on. However, a well-designed IaC approach is arguably the top-banana approach. It gives the next administrator a readable configuration, a transparent history, and a predictable evaluation process we can deploy at scale. If that's the case, I say the monkey can have his button. Just don't mistake it for the system behind it. 🐒

0 Comments:

Post a Comment

My Instagram