-
We got a series of questions from a customer:
These questions come up often, so I'll post our recommendations below. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 1 reply
-
One repo for infra-live and one for infra-modules, or combine them?We recommend separate repos. The primary reason is so you can version your modules and run different versions of those modules in different environments: e.g., you might run
See here for how to lay out your One Terraform config for an entire environment, or split out by resource?Generally speaking, you want to keep Terraform modules small. Bigger modules are slower (e.g., That said, those pieces shouldn't be too small; you wouldn't want to do a single module per resource. You need to find a good balance, grouping things that are typically deployed together, have similar deployment cadences, have similar risk/security profiles, have common team ownership, etc. So, for example, you might have one module that handles all your networking; another module that sets up your data stores (e.g., RDS); another module that handles your orchestration tool (e.g., EKS); and perhaps a bunch of individual modules to deploy apps, each owned by a separate team. See the answer here for more info. Whether to use one branch per environment, or a single branch with all environments?We recommend a single branch for all environments, but with versioned modules everywhere, so different environments can deploy different versions. See How to manage multiple environments with Terraform for a comparison of Terraform workspaces, branches, and the Terragrunt approaches (we, of course, recommend the Terragrunt approach). How to handle global variables?Typically, you have a hierarchy of variables: some that are truly global across all accounts/environments; some that apply across a single account/environment; some that apply across a single region; some that apply across a set of services; etc. There are multiple ways to handle this, depending on the use case, but the most common pattern is:
For more details and the other options, see Keep your Terragrunt Architecture DRY. How to set up the backend (e.g., S3 bucket)?See How should I create the backend (e.g., S3 bucket) for storing Terraform state?. How to connect Terraform configuration to the backend (e.g., S3 state files)?See the tutorial here. This will allow you to define your How to handle module defaults?
How to handle tagging? |
Beta Was this translation helpful? Give feedback.
-
Regarding modules: |
Beta Was this translation helpful? Give feedback.
-
I believe gruntwork has given a good general recommendation for folder structures, principles and examples, but of cource developers can further customize the solution to meet their unique needs. Here are some practices we use in our organization,
|
Beta Was this translation helpful? Give feedback.
-
I also have an use case to submit into the "how do I..." category, for which I would like to see some more documentation about. I find that the examples available do a good job explaining the ideal Terragrunt structure for monolithic applications, where there is only one service that uses a bunch of modules like this. environments
│ ├ test
│ ├ westeurope
│ ├ app1
│ ├ rg
│ └─ terragrunt.hcl
│ ├ web_app
│ └─ terragrunt.hcl
│ ├ postgres
│ └─ terragrunt.hcl
│ ├ app2
│ ├ rg
│ └─ terragrunt.hcl
│ ├ functions
│ └─ terragrunt.hcl
│ ├ postgres
│ └─ terragrunt.hcl In this case it's quite a bit harder to manage your services, for two reasons.
One approach I've been trying to use to cope with this is to move the inputs for the individual components into a shared .hcl file a the root of the application. │ ├ westeurope
│ ├ app1.hcl
│ ├ app2.hcl
│ ├ app1
│ ├ rg
│ └─ terragrunt.hcl
│ ├ web_app
│ └─ terragrunt.hcl
│ ├ postgres
│ └─ terragrunt.hcl
[...] Where the app1.hcl contains the definitions for all the modules of the application in its input section. inputs = {
### rg
rg_name = foo
### web_app
container_image = bar:1.0
[...]
} to then import it into the individual modules of the applications like this:
and leaving the individual modules terragrunt.hcl files "empty". This makes everyday management of an application (like scaling, adding a flat value as input and being able to tell "at a glance" what an application is using) easier.
P.S. If someone is wondering why needing to have multiple .hcl files on a two-level hierarchy, instad of a single one containing "everything", it's because terragrunt only supports a single I would really appreciate if we could get some more documentation on what is the ideal way of handling microservice-oriented architecture with Terragrunt. |
Beta Was this translation helpful? Give feedback.
One repo for infra-live and one for infra-modules, or combine them?
We recommend separate repos. The primary reason is so you can version your modules and run different versions of those modules in different environments: e.g., you might run
v1.0.0
of youreks
module inprod
while testing outv2.0.0
of theeks
module instage
. As described in module versioning: