When creating an IaC repo for your organization, there are a number of architecture decisions that need to be made. One of the most important you can choose is how to build your repository structure… should you go multi-repo or mono-repo?
The one you chose for your organization is dependent on a number of factors, including the purpose of the IaC in the first place. Is it for development? Will they be deployed and managed in production? How is your application code architected? Does your infosec team weigh in here, too?
Sometimes you are graced with the ability to plan ahead and build out a longer-term repo strategy before the first commit is ever made. However, past design decisions often corner you into a particular strategy that proves limiting over time. Specifically affecting how your codebase interacts with external tooling can end up being a major source of frustration.
The good news is that whatever your primary repository strategy–mono repo or multi repo–env0’s leading IaC management platform is ready to help. In this article, we’ll walk you through how env0 works with your repo strategy, and how to use env0 effectively with each strategy type.
First, let’s ensure we’re on the same page with general structure and terminology.
The ideal way to use env0 is writing ‘context agnostic’ TF code, and using Projects to set the context. While this is the ideal, many teams have already written some Terraform code, and their repo structure is different. Read on to see your options.
Regardless of your selection, one part is imperative: you should be using a remote backend in order to store your Terraform state. This means that:
Although this typically is an anti-pattern, migrating one big Terraform deployment to env0 is pretty straight forward—just create a template pointing to your main.tf, and run that in env0. This misses out on a lot of things - for example RBAC will be the same for everyone, since there is only one project.
Why is this an anti-pattern? These repo types often create unnecessary interdependencies. A failure in one module or resource cascades, and may affect other non-dependent resources. For instance if you’re slow to deploy a change, it’s possible that a small PR could be blocked by another larger PR. This happens pretty frequently with Atlantis’ preferred repo model.
This is a ‘classic’ env0 structure. Create a template for each service, and a project for each stage. That way you can enjoy different RBAC and policies for each stage. For example - you’ll have a ‘Production’ project that most users can only view, and where ‘destroy’ is disabled for everyone. The ‘QA’ project will have different configuration settings, and members of your QA team can have full control over their environments. Optionally, you can store your config in code (tfvar) or you can use env0 variables.
Create a template for each stage - you’ll have multiple templates connected to the same repository, but configured for different folders.
Create a different project for each stage - to enforce RBAC and policies per stage.
You can set up your configuration variables based on template OR project, but we recommend doing so per Project - so Project RBAC is applied on the configuration as well.
You’ll have a single service per template + project.
This is the most common structure for Terragrunt users. This is similar to “deployment per stage” but you’ll have more templates, as you would need to create one per stage/service combination.
In env0, we still recommend creating a single project per stage and deploying all the services under that stage to that project, as it usually makes more sense to control RBAC like that.
You’ll have a single service per template. In the near future, env0 will allow you to create an environment without having to create a template.
In case of very complicated setups, we recommend splitting stages up to sub-stages, for example by region or cloud provider. Since env0 does not support “sub-projects” or a similar division, these would just be set up as separate projects, e.g. “Prod - us-east-2” or “Development - Azure”.
The good news is that regardless of your repo selection choice, there is a way to easily manage your Terraform at scale with env0. While your current repo architecture may not be ideal, if re-factoring is too impactful, there’s a good chance that using Terraform automation and Collaboration Software (aka TACOS) like env0 can help smoothe over the bumps.