#terragrunt (2019-02)

terragrunt

Terragrunt discussions

Archive: https://archive.sweetops.com/terragrunt/

2019-02-05

Samuli avatar

any best practices on how to reference between terraform dependencies on different terragrunt modules. eg. I have vpc as a module and bastion as another module (terragrunt modules both) and I need to reference the vpc-id (and subnet-ids) from vpc in bastion

antonbabenko avatar
antonbabenko

if you want you can try code generated by modules.tf - draw vpc+asg in cloudcraft.co and click export

antonbabenko avatar
antonbabenko

I wrote small shell script which does replacement using hooks

Samuli avatar

looks interesting. Have to give them a try at some point

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

yes, use SSM

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

or use remote state provider

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

we have examples of both in this repo https://github.com/cloudposse/terraform-root-modules

cloudposse/terraform-root-modules

Example Terraform service catalog of “root module” invocations for provisioning reference architectures - cloudposse/terraform-root-modules

joshmyers avatar
joshmyers

@Samuli Are these modules being run in the same Terraform run? (do they share state)

Samuli avatar

It would be straight forward if they did but with terragrunt modules they are not. So I went with remote_state..

2019-02-14

rohit.verma avatar
rohit.verma

@Erik Osterman (Cloud Posse) how are we suppose to use terragrunt in your new setup. I see eligible terraform.tfvars only in atlantis-repo sub-module.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/root.cloudposse.co

Example Terraform Reference Architecture for Geodesic Module Parent (“Root” or “Identity”) Organization in AWS. - cloudposse/root.cloudposse.co

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

this is all you need

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

that said, I see no strong use-case for it anymore

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I think make is a better task runner

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

and tfenv let’s use define module imports

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/testing.cloudposse.co

Example Terraform Reference Architecture that implements a Geodesic Module for an Automated Testing Organization in AWS - cloudposse/testing.cloudposse.co

rohit.verma avatar
rohit.verma

want to avoid tfenv, it seems over populating the environment by appending all current env variables with TF_VAR

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

with tfenv, we don’t need any wrappers to call terraform

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

fair enough

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/root.cloudposse.co

Example Terraform Reference Architecture for Geodesic Module Parent (“Root” or “Identity”) Organization in AWS. - cloudposse/root.cloudposse.co

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

i just don’t like this

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

overloading .tfvars with a non-portable terraform code that is vendor specific to terragrunt

rohit.verma avatar
rohit.verma

also i am thinking may be its kind of simpler if we have a whitelisting variables rather then excluding regex

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

while envs are universal across apps

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
06:16:40 AM
Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

TFENV_WHITELIST is supported

rohit.verma avatar
rohit.verma

I saw that, I was saying more about ideology. The whitelist value is .*.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

what i don’t like is terraform telling me how envs should look in the first place. just like i don’t like chamber telling me that envs must be upper case (which doesn’t work with terraform)

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so we have env warfare

rohit.verma avatar
rohit.verma

Should be something like geodesic whitelist, and customer whitelist. Where we convert all the values required for geodesic modules. SPECIALLY the ones which we are currently getting

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I just wish terraform and terragrunt would not stipulate a convention on envs and then things would just work. so tfenv is an ambassador. it does the dirty work.

rohit.verma avatar
rohit.verma

the approach makes sense in the current context, its just having too much env variables makes my life hard

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

just set TFENV_WHITELIST and TFENV_BLACKLIST in your environment however you want

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

we were so busy mapping envs from one tool to the next. that’s what we wanted to avoid.

rohit.verma avatar
rohit.verma

too much work to make a module get up. Its as good as doing a export variable in a tfenv.sh

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so setting too many envs makes everyones life hard

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

but the env always has many envs, that’s just a fact-of-linux

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

on OSX, I have 87 envs that i never set

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
export|wc
rohit.verma avatar
rohit.verma

i have total 57, out of which I know about atleast 40

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so in our Dockerfile we had SOOOOOO many envs. it was unmanageable.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so we’ve gotten rid of most of them (compared to before)

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

then moved to .envrc (direnv) so we localize these settings

rohit.verma avatar
rohit.verma

yeah regarding that, I saw below snippet in rc.d terraform

# Translate environment variables to terraform arguments
	[ -z "${TF_FROM_MODULE}" ] || export TF_CLI_INIT_FROM_MODULE="${TF_FROM_MODULE}"
	[ -z "${TF_STATE_FILE}" ] || export TF_CLI_INIT_BACKEND_CONFIG_KEY="${TF_BUCKET_PREFIX}/${TF_STATE_FILE}"
	[ -z "${TF_BUCKET}" ] || export TF_CLI_INIT_BACKEND_CONFIG_BUCKET="${TF_BUCKET}"
	[ -z "${TF_BUCKET_REGION}" ] || export TF_CLI_INIT_BACKEND_CONFIG_REGION="${TF_BUCKET_REGION}"
	[ -z "${TF_DYNAMODB_TABLE}" ] || export TF_CLI_INIT_BACKEND_CONFIG_DYNAMODB_TABLE="${TF_DYNAMODB_TABLE}"
	[ -z "${AWS_PROFILE}" ] || export TF_CLI_INIT_BACKEND_CONFIG_PROFILE="${AWS_PROFILE}"
	[ -z "${AWS_ROLE_ARN}" ] || export TF_CLI_INIT_BACKEND_CONFIG_ROLE_ARN="${AWS_ROLE_ARN}"
Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

yea, that’s strictly for backwards compatibility

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I didn’t want to tell everyone to rewrite their envs

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

the TF_CLI_* convention is canonical

rohit.verma avatar
rohit.verma

which i assume should be good enough if we have all variables in left hand side set

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

~the ones on the LHS are the legacy ones we’ve had in our docs~

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

rohit.verma avatar
rohit.verma

yeah, my point even if we are using the legacy variables, things should work

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I mean the ones in the [ ... ] conditionals

rohit.verma avatar
rohit.verma

e.g TF_BUCKET_REGION

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

yep, so using that mapping they will continue to work

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

but TF_CLI_INIT_BACKEND_CONFIG_REGION is canonical

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

in that it maps precisely and consistently to the TF_CLI_ARGS_init=-backend-config=region=blah which is the terraform native convention

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

technically, even tfenv isn’t needed. it’s just a convenience.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so we can set k/v pairs as ENVs

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

rather than mucking with the tf flags in compacted envs

rohit.verma avatar
rohit.verma

this is what I am doing currently

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

the compacted envs?

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I don’t like terraform native envs

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
TF_CLI_ARGS_init="-from-module=git::<https://github.com/cloudposse/terraform-root-modules.git//aws/ecs?ref=tags/0.40.0> -backend-config=region=us-west-2 -backend-config=dynamodb_table=cpco-testing-terraform-state-lock -backend-config=bucket=cpco-testing-terraform-state -backend-config=key=ecs/terraform.tfstate"
Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

that’s what it looks like.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

PIA to toggle individual fields

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

so we just came up with a convention to not do that. but that’s opinionated and might not suit all parties.

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

I like it b/c you can set envs at different levels (E.g. Dockerfile, project, parent folder, etc)

rohit.verma avatar
rohit.verma

i was doing something like export TF_CLI_INIT_BACKEND_CONFIG_BUCKET=niki-root-terraform-state

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

that looks good

rohit.verma avatar
rohit.verma

but its still asking me for bucket name

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

TF_CLI_INIT_BACKEND_CONFIG_BUCKET="cpco-testing-terraform-state"

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

that’s what we are doing

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
TF_CLI_PLAN_PARALLELISM=2
TF_CLI_INIT_BACKEND_CONFIG_REGION=us-west-2
TF_CLI_INIT_FROM_MODULE=git::<https://github.com/cloudposse/terraform-root-modules.git//aws/ecs?ref=tags/0.40.0>
TF_CLI_INIT_BACKEND_CONFIG_DYNAMODB_TABLE=cpco-testing-terraform-state-lock
TF_CLI_INIT_BACKEND_CONFIG_BUCKET=cpco-testing-terraform-state
TF_CLI_INIT_BACKEND_CONFIG_KEY=ecs/terraform.tfstate

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

this definitely works with every terraform * command

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

if you use tfenv to cast it to the TF_CLI_ARGS_blah=....

rohit.verma avatar
rohit.verma

in short with my legacy variables, use_terraform and terraform init should give me required resuly

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

true

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

# Terraform State Bucket
ENV TF_BUCKET_REGION="${AWS_REGION}"
ENV TF_BUCKET="${NAMESPACE}-${STAGE}-terraform-state"
ENV TF_DYNAMODB_TABLE="${NAMESPACE}-${STAGE}-terraform-state-lock"
rohit.verma avatar
rohit.verma

i can’t use use_terraform also

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

is what we have in our docker file

rohit.verma avatar
rohit.verma

has to source it manually

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/geodesic

Geodesic is a cloud automation shell. It&#39;s the fastest way to get up and running with a rock solid, production grade cloud platform built on top of strictly Open Source tools. ★ this repo! h…

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/geodesic

Geodesic is a cloud automation shell. It&#39;s the fastest way to get up and running with a rock solid, production grade cloud platform built on top of strictly Open Source tools. ★ this repo! h…

rohit.verma avatar
rohit.verma

something like this is happening

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
cloudposse/geodesic

Geodesic is a cloud automation shell. It&#39;s the fastest way to get up and running with a rock solid, production grade cloud platform built on top of strictly Open Source tools. ★ this repo! h…

rohit.verma avatar
rohit.verma
 ✓  (root-admin) tfstate-backend ⨠  use_terraform 
 ✓  (root-admin) tfstate-backend ⨠  printenv | grep TF_CLI
TF_CLI_INIT_BACKEND_CONFIG_REGION=ap-south-1
TF_CLI_INIT_BACKEND_CONFIG_DYNAMODB_TABLE=niki-root-terraform-state-lock
TF_CLI_INIT_BACKEND_CONFIG_BUCKET=niki-root-terraform-state
TF_CLI_INIT_BACKEND_CONFIG_PROFILE=root-admin
TF_CLI_INIT_BACKEND_CONFIG_KEY=tfstate-backend/terraform.tfstate
 ✓  (root-admin) tfstate-backend ⨠  terraform init
Initializing modules...
- module.tfstate_backend
- module.tfstate_backend.s3_bucket_label
- module.tfstate_backend.dynamodb_table_label

Initializing the backend...
bucket
  The name of the S3 bucket

  Enter a value: 
Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)

zoom?

Erik Osterman (Cloud Posse) avatar
Erik Osterman (Cloud Posse)
rohit.verma avatar
rohit.verma

sure

2019-02-28

Tobias Hoellrich avatar
Tobias Hoellrich

Good afternoon #terragrunt - I have an odd situation I can’t explain and was wondering if one of you had any insight.

Tobias Hoellrich avatar
Tobias Hoellrich
11:25:57 PM
loren avatar

What happens if you run a) without –terragrunt-source?

Tobias Hoellrich avatar
Tobias Hoellrich

@loren - same thing happens: terragrunt wants to create all the wave resources.

loren avatar

And the contents of wave/terraform.tfvars? And do you have a parent terraform.tfvars?

loren avatar

At least the source line, if vars are sensitive

Tobias Hoellrich avatar
Tobias Hoellrich
terragrunt = {
  terraform {
    source = "git::<ssh://[email protected]/xxxxx/terraform-modules.git//wave>"
  }

  # dependencies for wave
  dependencies {
    paths = ["../vpc", "../route53", "../securitygroups"]
  }

  # Include all settings from the root terraform.tfvars file
  include = {
    path = "${find_in_parent_folders()}"
  }
}

terraform {
  backend "s3" {}
}

# -------------------------------------------------------------------------------------------------------

wave_es_cluster_name = "events"
Tobias Hoellrich avatar
Tobias Hoellrich

And yes, there is a parent terraform.tfvars. It sets up s3 remote states and dynamo locking.

loren avatar

I think the terraform backend bit is off… That should be in a .tf file, not .tfvars

loren avatar

I’ll have to take a look at my own setups when back at a computer to compare

Tobias Hoellrich avatar
Tobias Hoellrich

You mean this from the parent terraform.tfvars?

Tobias Hoellrich avatar
Tobias Hoellrich
terragrunt = {
  # Configure Terragrunt to automatically store tfstate files in an S3 bucket
  remote_state {
    backend = "s3"

    config {
      encrypt        = true
      region         = "ca-central-1"
      s3_bucket_tags {
        creator        = "terraform"
        terraform      = "true"
        purpose        = "canada"
        name           = "terraform state storage"
      }

      dynamodb_table_tags {
        creator        = "terraform"
        terraform      = "true"
        purpose        = "canada"
        name           = "terraform lock table"
      }
    }
  }
Tobias Hoellrich avatar
Tobias Hoellrich

(truncated)

loren avatar

No, sorry, I can’t copy/paste easily on my phone, I mean the block with backend "s3" {} in wave/terraform.tfvars

Tobias Hoellrich avatar
Tobias Hoellrich

ok - i’ll look

Tobias Hoellrich avatar
Tobias Hoellrich

I removed it, but still see the same situation: plan-all wants to create all wave-resources; plan-all --terragrunt-include-dir wave does not want to create them; plan inside the wave directory also does not want to create them.

loren avatar

ok, i’m not seeing anything, but have the sense it’s got to be something fundamental that is just easy for the eyes to pass over

loren avatar

maybe open an issue on the terragrunt repo… they’re pretty decent about responding to this kind of help request

Tobias Hoellrich avatar
Tobias Hoellrich

tks for your help!

1
Tobias Hoellrich avatar
Tobias Hoellrich

And I’m ashamed to admit that this was a stupid mistake where I had started a new component in a parallel directory, which had the terraform.tfvars file from the wave-directory in it. Hope I did not waste too much of your time, @loren. Thanks again!

loren avatar

Aha! That’ll do it! No worries, glad you figured it out!

Tobias Hoellrich avatar
Tobias Hoellrich

~Any ideas why plan-all in the root wants to create resources that already exist?~his turned out to be a stupid mistake where I had created a new component in the live directory and it had a copy of the wave terraform.tfvars in it …

    keyboard_arrow_up