Happy Employees == Happy ClientsCAREERS AT DEPT®
DEPT® Engineering BlogTerraform

Terragrunt vs Terraform

In this article, I detail the benefits of using Terragrunt. At the end, I list the reasons why sometimes Terragrunt may not be the right choice for your project.

Terragrunt is a wrapper on top of Terraform that fixes some of Terraform's deficiencies. When you use Terragrunt, you are running Terraform behind the scenes.

In this article, I detail the benefits of using Terragrunt. At the end, I list the reasons why sometimes Terragrunt may not be the right choice for your project.

Intended Audience: Technical team members with some familiarity with Terraform and AWS.

Why use Terragrunt?

The two main benefits of Terragrunt are:‌

  • DRY clean code
  • Ease of use

Preamble

Directly from HashiCorp's Terraform best practices, you should avoid a monolithic configuration and eschew a large Terraform state file . In summary, if you put all your cloud resources like EC2, S3, RDS, etc. into Terraform files under one big directory, modifying a S3 bucket will slowly scan and potentially modify other AWS resources in that directory.

Seasoned Terraform users will group the TF configuration files into its own directory, such as VPC, IAM, EC2 or Frontend-UI, Backend-Service, Databases. In practice, this can lead to many duplicate configuration and variables.

DRY clean code

A fundamental tenet of clean code is Don't Repeat Yourself (DRY). If you duplicate code in more than one place, you must change the code in multiple places when doing fixes and enhancements. When you don't change the code in all the duplicated places, bugs occur.

  • DRY Input Variables
    Terragrunt
    You can put all your variables in one file and reuse it via the inputs block.
    Example config
    env.hcl

    Terraform
    You are forced to duplicate your input variables in multiple tfvars files.
    Example config
    vpc/terraform.tfvars
    s3/terraform.tfvars
    iam/terraform.tfvars
  • DRY Output Variables
    Terragrunt
    Output values are automatically generated from the Terraform module output variables.

    Terraform
    There are multiple outputs.tf files.
    Example config
    vpc/outputs.tf
    s3/outputs.tf
    iam/outputs.tf
  • DRY remote state backend
    Terragrunt
    The remote_state block dynamically generates the Terragrunt remote state configuration in the parent terragrunt.hcl file.
    Example config
    terragrunt.hcl

    Terraform
    The Terraform remote state configuration is defined via the backend block. Even worse, Terraform does not allow the use of variables in the backend block so you have to explicitly hard code everything. You must create multiple backend configuration files with nearly identical configuration.
    Example config
    vpc/providers.tf
    s3/providers.tf
    iam/providers.tf
  • DRY CLI arguments
    Terragrunt
    You can define required Terraform CLI arguments via the extra_arguments block in one central terragrunt.hcl.
    Example config
    terragrunt.hcl

    Terraform
    If you want to always run the terraform command line with certain required arguments, you would have to hack a custom script.

Ease of use

Terragrunt helps using Terraform more convenient for the operators.

  • run-all
    Terragrunt
    This is the killer feature of Terragrunt.
    The primary issue with multiple Terraform state stacks is running it in the right order. For example, you need to apply the VPC stack before the EC2 stack.

    You can explicitly define the correct order to apply the stacks viadependencies. Then executing terragrunt run-all apply will execute the resource creation in the correct order.
    Example config
    envcommon/app_ec2.hcl

    Terraform
    To apply the Terraform stacks in the proper order, you would have to code and maintain your own script.
    Example script
    terraform.run-all.sh
  • Before/After/Error hooks
    Terragrunt
    You may want to run an external program like Slack before and after running Terragrunt. This is accomplished via the before_hook, after_hook, and error_hook.
    Exanple config
    terragrunt.hcl

    Terraform
    To accomplish the above hooks in Terraform, it would be a custom wrapper script.
  • Auto-create remote state resource
    Terragrunt
    If the remote state backend store (S3 and DynamoDB in AWS) does not exist, Terragrunt will automatically create it for you with the correct security settings.
    Example config
    terragrunt.hcl

    Terraform
    Before you can start using Terraform, you either have to create the remote state backing store manually or create the store via Terraform using local state then migrate.
    Example config
    terraform_infra/main.tf
  • Auto-retry
    Terragrunt
    Cloud providers can be finicky or slow.  You can configure Terragrunt to automatically retry after a failure with the retry_max_attempts setting.
    Example config
    terragrunt.hcl

    Terraform
    Terraform has no built-in auto-retry setting.
  • Auto-init
    Terragrunt
    It's a small annoyance, but in Terraform you must manually execute terraform init  once on a new stack before you can terraform plan/apply.  Terragrunt is smart enough to recognize that an init is needed during the plan/apply phase and will automatically execute it for you.

Why not to use Terragrunt

Yet another tool

DevOps already has a lot of tools to learn. If your team is already overwhelmed, it may not be the right time to introduce yet another tool.

Terraform cloud

Terragrunt does not work well with Terraform Cloud. Terraform Cloud competes with Terragrunt, offering many of the same clean code and ease of use features.

Large Terraform codebase

Refactoring a large Terraform codebase into Terragrunt is a pain, involving many tedious terraform import. It's more prudent to introduce Terragrunt on a new project codebase instead.

Final thoughts on Terragrunt vs Terraform

I enjoy using Terragrunt on my projects and I wholeheartedly recommend it. Terragrunt offers so many additional benefits on top of the already wonderful Terraform.

If you enjoyed this article, come back next week for my article on "How to layout your Terragrunt project."

A preview can be found at GitHub
https://github.com/deptagency/engineering-blog-terraform-terragrunt/tree/main/soapbox/terragrunt