Home

Awesome

Terraform Monorepo Example

Maintenance lang GitHub stars

Learn how to design a scalable Terraform monorepo

Tools

Overview

High level folders

.
├── README.md
├── infra-live
│   ├── dev
│   │   ├── networking
│   │   ├── s3
│   │   ├── security
│   │   ├── stacks
│   │   └── .tfgen.yaml
│   ├── prod
│   │   ├── networking
│   │   ├── s3
│   │   ├── security
│   │   ├── stacks
│   │   └── .tfgen.yaml
│   └── .tfgen.yaml
└── modules
    └── my-custom-module
        └── main.tf

Patterns

Let's cover some patterns to organize the infra-live folder, which will contain all the actual infrastructure, separated by environment. Considering an environment folder, you can organize it in several ways.

By resource

You can create individual folders for each resources in the cloud, so you would have something like this:

.
├── ec2
├── rds
│   └── my-database-1
├── iam
│   ├── roles
│   └── users
├── s3
│   └── my-bucket-1
└── vpc

By resource group

You can create folders based on the resources type (compute, security, networking, etc):

.
├── compute
│   ├── my-asg
│   └── my-eks-cluster
├── security
│   └── iam
│       ├── roles
│       └── users
├── storage
│   ├── rds
│   └── s3
└── networking
    ├── vpc
    └── vpc-peering

Mixed

Using this pattern you'll have a mix of the previous two.

.
├── compute
│   ├── my-asg
│   └── my-eks-cluster
├── security
│   └── iam
│       ├── roles
│       └── users
├── stacks
│   ├── my-app-stack-1
│   └── my-app-stack-2
├── s3
│   ├── my-bucket-1
│   └── my-bucket-1
└── networking
    ├── vpc
    └── vpc-peering

Stacks

Let's talk about the stacks folder. Sometimes you have an app that uses multiple cloud resources, like SQS Queues, SNS Topics, S3 Buckets, so it could be confused to deploy these resources in different places, so maybe it makes sense to have a module just for this app. You could add it to the stacks folder, and deploy all of them together. If you do that, makes sense to give all the resources some kind of prefix, ideally the name of the app that uses it.

This pattern can get trick if you have a resources that's shared between more than one app, for example a SQS Queue that have a consumer and a writer.

Files organization

To organize your files and have a pattern across multiple modules, you can name your files like this:

Anti-Patterns

Some anti-patterns I observed and heard about

Single module for the entire infrastructure

In my opinion this is the most common anti-pattern. Some people may argument that having a module that deploys the entire infrastructure is a good thing and will be useful in a disaster recovery situation. But the problem is, that you probably never gonna need to do that. The operational overhead for keeping this structure will not be paid by the "benefit" it offers.

In addition, we have other problems by using this structure:

So, if you see something like this, run show them this repo!

.
└── entire-infra-module
    ├── backend.tf
    ├── s3.tf
    ├── iam.tf
    ├── eks.tf
    ├── vpc.tf
    └── rds.tf

Related