Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
B
blog
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
nimrod
blog
Commits
5a7945e7
Commit
5a7945e7
authored
3 years ago
by
nimrod
Browse files
Options
Downloads
Patches
Plain Diff
fixup! Post about Terragrunt.
parent
4261dea3
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#2148
passed
3 years ago
Stage: .pre
Stage: deploy
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
content/tf-project-structure.rst
+48
-27
48 additions, 27 deletions
content/tf-project-structure.rst
with
48 additions
and
27 deletions
content/tf-project-structure.rst
+
48
−
27
View file @
5a7945e7
...
...
@@ -9,13 +9,14 @@ Recently I've been using `Terragrunt <https://terragrunt.gruntwork.io/>`_ and I
have thoughts on what it offers and is it useful. My usage has been in an
existing project that follows the Gruntworks guidelines closely and with the
paid subscription to the Gruntworks library. These opinions are my own and
they're the result of managing small and medium infrastructure with Terraform
for the last few years both as a single developer and part of small team.
they're based on my recent experience with Terragrunt as well as managing small
and medium infrastructure with Terraform for the last few years both as a single
developer and part of small team.
The main point of Terragrunt as I understand it is keeping from repeating
yourself in code. I am not a fan of copying and pasting big blocks of code nor
of having to change the same value in a few different places. So keeping
code
DRY is a worthwhile endeavor.
of having to change the same value in a few different places. So
for me
keeping
code
DRY is a worthwhile endeavor.
Keeping modules DRY
-------------------
...
...
@@ -24,33 +25,35 @@ Terragrunt works by using modules. I like Terraform modules. Even the Terraform
documentation suggests that you don't have a single top level module for your
entire infrastructure. It makes development more difficult with more merge
conflicts. It makes deploying for testing purposes more difficult because
Terraform will keep trying to delete resources that aren't your code (because
Terraform will keep trying to delete resources that aren't
in
your code (because
someone else working in a different branch has made changes for some other
reason). You can work around that by specifying the target you're interested in
but that error-prone and
can be
tiresome after a while.
but that
is
error-prone and
is
tiresome after a while.
In a previous project I worked on we had a module for roughly each service. We
had quite a lot of code that was copied from one module to another (like
creating a new RDS instance we also created the subnet group, the security
group
for the client, etc.). Over time we saw clearly what code was shared
between the
different modules, we created a :code:`library` directory and
started adding
sub-modules there and after a while we had a nice library of
reusable
sub-modules and things were
nice
.
when
creating a new RDS instance we also created the subnet group, the security
group
for the client, etc.). Over time we saw clearly what code was shared
between the
different modules, we created a :code:`library` directory and
started adding
sub-modules there and after a while we had a nice library of
reusable
sub-modules and things were
good
.
Because we waited a bit before creating a new sub-module they were pretty
stable. When we did have a change to the a sub-module that we wanted to deploy
across the entire infrastructure, we would open a branch, work on all the needed
changes there, test them in one of the testing environments, open a PR that has
all of the changes.
changes there, test them in one of the testing environments and then open a PR
that has all of the changes (the sub-module changes, the calling modules
changes, any fallout from those changes).
This process fit us nicely. The PR had the entire picture and we could really
This process fit
ted
us nicely. The PR had the entire picture and we could really
see if the change improved anything (like adding an output to a module and
fetching it in a different module would be clear if you see it being used). We
did on occasion had conflicting changes we did had to use targeted :code:`plan`
and :code:`apply` but as far as I can remember no more than once a quarter.
did on occasion had conflicting changes and we did had to use targeted
:code:`plan` and :code:`apply` but as far as I can remember no more than once a
quarter.
Terragrunt recommends s
e
tting
up 2
repositor
ies
, one for sub-modules and one
for
actually deployed modules. Then you create :code:`terragrunt.hcl` files that
Terragrunt recommends s
pli
tting
the
repositor
y in 2
, one for sub-modules and one
for
actually deployed modules. Then you create :code:`terragrunt.hcl` files that
list the sub-modules needed with the Git ref used. This allows you to use the
RDS database sub-module from today but the auto-scaling group from last year. I
see little point in this.
...
...
@@ -72,8 +75,8 @@ Environments, remote states and workspaces, oh my
-------------------------------------------------
Another way that Terragrunt keeps your code DRY is by generating the Terraform
backend configuration, because
Terraform
can't use variables
in
there. So
you
save less than
~7
lines. Cool. Also, you won't have by accident (because you
backend configuration, because
you
can't use variables there
with Terrafrom
. So
you
save less than
10
lines. Cool. Also, you won't have by accident (because you
copied that code from another module) used the same location for 2 modules and
have them delete each others resources. It happened to me more than once, but
you see it clearly when you first run :code:`terraform plan` so it's very easy
...
...
@@ -110,7 +113,7 @@ For making life a little easier I added the following snippet to each module:
}
Yes, this is copied code and along with the backend configuration, over 10 lines
of code mostly that is mostly duplicated. However, when I compare it the
of code mostly that is mostly duplicated. However, when I compare it
to
the
:code:`terragrunt.hcl` files, this is peanuts. I checked a few modules in the
codebase I'm working on and we have :code:`terragrunt.hcl` files that are 100s
of lines long and share all but a few lines.
...
...
@@ -119,17 +122,35 @@ I found that this convention is easy to document, easy for new developers to
pick up, uses existing tools so you can use your existing knowledge and all of
the benefits of avoiding to use another tool in your workflow.
Workflow
--------
Terragrunt builds a directory for each module (and each environment obviously),
clones the Git repos you mentioned with refs you specified and then mucks about
with the Terraform commands and plan files to stich everything togethere. Even
on paper this doesn't look like a good idea and it isn't one in practice, making
debugging issues difficult.
It also suggests that you can have different versions of the different
sub-modules in use across different environments, putting emphais on having
the :code:`main` branch match exactly what is each environment instead of
putting emphasis of avoiding drift between the different environments.
Conclusions
-----------
This post is a critique of the Gruntworks recommended setup and workflow and I
think that if you read it all you would see that I think that there are better
and easier ways. You can compare Terragrunt to a badly managed Terraform project
and find that it helps you. I didn't plan on reviewing Terragrunt until I used
it. Terragrunt makes life less enjoyable. It has a convoluted workflow locally
(with those bloody git clones), it makes debugging issues difficult and the
upside is just not there. I would recommend to anyone who thinks about adopting
Terrgrunt to first read the `workspaces documentation
and find that it helps you. But when you compare to it one that uses the suggested
convention, it makes things more difficult, doesn't deliver on the promise of
keeping your code DRY and promotes bad habbits.
I didn't plan on reviewing Terragrunt until I used it. Terragrunt makes life
less enjoyable. It has a convoluted workflow locally (with those bloody git
clones), it makes debugging issues difficult and the upside is just not there. I
would recommend to anyone who thinks about adopting Terrgrunt to first read the
`workspaces documentation
<https://www.terraform.io/docs/cli/workspaces/index.html>`_ before going with
Terragrunt and think hard on the code review, the testing and development
workflows.
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment