Skip to content

Instantly share code, notes, and snippets.

@mjmenger
Last active December 20, 2022 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjmenger/cd59672677b79466e473bd1901da0091 to your computer and use it in GitHub Desktop.
Save mjmenger/cd59672677b79466e473bd1901da0091 to your computer and use it in GitHub Desktop.
feature flags with terragrunt

directory structure

.
├── mod1
│   ├── main.tf
│   └── terragrunt.hcl
├── mod2
│   ├── main.tf
│   └── terragrunt.hcl
├── mod3
│   ├── main.tf
│   └── terragrunt.hcl
└── terragrunt.hcl

./terragrunt.hcl

terraform {
    extra_arguments "volterra" {
        commands = ["apply","plan","destroy"]
        arguments = []
        env_vars = {
            SOME_ENV_VAR = "hello there"
        }
    }
}

inputs = {
    feature_flag_a = false
    feature_flag_b = false
    feature_flag_c = false
}

mod*/terragrunt.hcl

In this simple example, the purpose of the terragrunt.hcl file in each module is to load the configuration of the parent.

include "root" {
  path = "../terragrunt.hcl"
}

mod1/main.tf

Mod1 creates a local file if feature_flag_a is true

variable feature_flag_a{
    type = bool
}

resource local_file myfile {
    count    = var.feature_flag_a ? 1 : 0
    filename = format("./mylocalfile01%02d",count.index)
    content  = "some test content"
}

mod2/main.tf

Mod2 creates a local file if feature_flag_b is true

variable feature_flag_b{
    type = bool
}

resource local_file myfile {
    count    = var.feature_flag_b ? 1 : 0
    filename = format("./mylocalfile01%02d",count.index)
    content  = "some test content"
}

mod3/main.tf

Mod3 creates a file if both feature_flag_a and feature_flag_b are true

variable feature_flag_a{
    type = bool
}

variable feature_flag_b{
    type = bool
}

resource local_file myfile {
    count    = var.feature_flag_a && var.feature_flag_b ? 1 : 0
    filename = format("./mylocalfile03%02d",count.index)
    content  = "some test content"
}

Depending on how the feature flags are set in ./terragrunt.hcl a plan or apply command deliver different results.

inputs = {
    feature_flag_a = true
    feature_flag_b = false
    feature_flag_c = false
}
terragrunt run-all plan

INFO[0000] The stack at /home/userhome/garbage/ff will be processed in the following order for command plan:
Group 1
- Module /home/userhome/garbage/ff/mod1
- Module /home/userhome/garbage/ff/mod2
- Module /home/userhome/garbage/ff/mod3
 

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.myfile[0] will be created
  + resource "local_file" "myfile" {
      + content              = "some test content"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./mylocalfile0100"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
inputs = {
    feature_flag_a = true
    feature_flag_b = true
    feature_flag_c = false
}
terragrunt run-all plan

INFO[0000] The stack at /home/userhome/garbage/ff will be processed in the following order for command plan:
Group 1
- Module /home/userhome/garbage/ff/mod1
- Module /home/userhome/garbage/ff/mod2
- Module /home/userhome/garbage/ff/mod3
 

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.myfile[0] will be created
  + resource "local_file" "myfile" {
      + content              = "some test content"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./mylocalfile0300"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.myfile[0] will be created
  + resource "local_file" "myfile" {
      + content              = "some test content"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./mylocalfile0100"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # local_file.myfile[0] will be created
  + resource "local_file" "myfile" {
      + content              = "some test content"
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./mylocalfile0200"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment