# Terragrunt

This walkthrough will guide you through using Terragrunt with CloudTruth enabling you to manage your multiple environments parameters and secretes from a centralized location.

You can also use CloudTruth to externally reference backend [tfstate output as an external parameter](https://docs.cloudtruth.com/parameters/parameter-management/external-values/terraform-state-files#remote-state-with-terragrunt).

## Prerequisites

* You know basic [Terraform](https://learn.hashicorp.com/terraform).
* You have installed [Terragrunt](https://terragrunt.gruntwork.io/docs/getting-started/install/#install-terragrunt).
* You have created a [CloudTruth API Access token](https://docs.cloudtruth.com/org-management/access-control/access-tokens) and installed the [CLI](https://docs.cloudtruth.com/cli-and-api/cloudtruth-cli#installation).

## Terragrunt DRY deploy

Terragrunt with [CloudTruth](https://docs.cloudtruth.com/configuration-management/cli-and-api/cloudtruth-cli#cloudtruth-run) allows you to keep your code [DRY across multiple environments](https://terragrunt.gruntwork.io/docs/getting-started/quick-start/#promote-immutable-versioned-terraform-modules-across-environments) while centralizing your configuration input values.

Rather than using hardcoded and scattered Terragrunt [inputs](https://terragrunt.gruntwork.io/docs/features/inputs/) to define parameter values, we will inject inputs directly from a specified CloudTruth [project](https://docs.cloudtruth.com/configuration-management/projects) and [environment](https://docs.cloudtruth.com/configuration-management/environments).

This example deployed with Terragrunt HCL will create an AWS Instance in us-west-2 and an S3 bucket, utilizing CloudTruth to manage Terraform variable keys and values for a development, production, and staging environment.

You can follow along in your AWS account by cloning this [repo](https://github.com/cloudtruth-demo/terragrunt-cloudtruth-deploy.git).

`git clone https://github.com/cloudtruth-demo/terragrunt-cloudtruth-deploy.git`

The Terragrunt folder structure for this repo contains `development`, `production`, and `staging` directories.

```
# terragrunt-cloudtruth-deploy
├── development
│   ├── instance
│   │   └── terragrunt.hcl
│   ├── s3
│   │   └── terragrunt.hcl
│   └── terragrunt.hcl
│       
├── production
│   ├── instance
│   │   └── terragrunt.hcl
│   ├── s3
│   │   └── terragrunt.hcl
│   └── terragrunt.hcl
│       
└── staging
    ├── instance
    │   └── terragrunt.hcl
    ├── s3
    │   └── terragrunt.hcl
    └── terragrunt.hcl
```

The `instance` and `s3` sub-folders contain a `terragrunt.hcl` file that set the `source` parameter to point at the specific modules in the [`terragrunt-cloudtruth-modules`](https://github.com/cloudtruth-demo/terragrunt-cloudtruth-modules) repo. They also `include` the parent `terragrunt.hcl` which configures the AWS provider.

Example instance `terragrunt.hcl`:

```
terraform {
  source = "git::https://github.com/cloudtruth-demo/terragrunt-cloudtruth-modules.git//instance?ref=v0.0.1"
}

include {
  path = find_in_parent_folders()
}
```

{% hint style="info" %}
Notice that we are not hardcoding *inputs* in the terragrunt.hcl! Inputs will be centrally managed and sourced from CloudTruth and not buried in environment subdirectories. 🎉
{% endhint %}

#### Setup a CloudTruth Project and Environments

Create a CloudTruth [Project](https://docs.cloudtruth.com/configuration-management/projects) called `Terragrunt`.

```
cloudtruth project set Terragrunt
```

Now add the parameters to the `Terragrunt` project that are required by the [Terraform modules](https://github.com/cloudtruth-demo/terragrunt-cloudtruth-modules/blob/main/instance/variables.tf) we are calling in the terragrunt.hcl.

```
cloudtruth --project Terragrunt parameter set TF_VAR_ami -v ami-830c94e3
cloudtruth --project Terragrunt parameter set TF_VAR_instance_type -v t2.micro
cloudtruth --project Terragrunt parameter set TF_VAR_availability_zone_names -v '["us-west-2a", "us-west-2b"]'
cloudtruth --project Terragrunt parameter set TF_VAR_resource_tags -v '{"Name":"Cloudtruth-Instance","project":"CloudTruth Run Terraform","environment":"default"}'
```

Set unique resource tags that get applied to the EC2 instance and s3 bucket for each environment.

```
cloudtruth --project Terragrunt --env development parameter set TF_VAR_resource_tags -v '{"Name":"CloudTruth-development","project":"CloudTruth Run Terraform","environment":"development"}'
cloudtruth --project Terragrunt --env production parameter set TF_VAR_resource_tags -v '{"Name":"CloudTruth-production","project":"CloudTruth Run Terraform","environment":"production"}'
cloudtruth --project Terragrunt --env staging parameter set TF_VAR_resource_tags -v '{"Name":"CloudTruth-staging","project":"CloudTruth Run Terraform","environment":"staging"}'
```

Now your CloudTruth Terragrunt project is setup to centrally manage the `TF_VAR` variables with unique values for resource tags across our multiple environments.

#### Running a centrally managed DRY deploy

Terragrunt [respects ](https://terragrunt.gruntwork.io/docs/features/inputs/)any `TF_VAR_xxx` variables you’ve manually set in your environment and follows the same variable precedence as [Terraform](https://www.terraform.io/docs/configuration/variables.html#variable-definition-precedence). Using `CloudTruth Run` we will pass the CloudTruth configured `TF_VAR_xxx` variables directly to the Terraform modules through Terragrunt for the specified environment.

Change directory to `terragrunt-cloudtruth-deploy/development/`.

From `terragrunt-cloudtruth-deploy/development/` execute the following command which passes variables from the CloudTruth project `Terragrunt` for the `development` environment into terragrunt:

```
cloudtruth --project Terragrunt --env development run -- terragrunt run-all apply
```

{% hint style="success" %}
You have now deployed an instance in EC2 and an S3 bucket with a DRY Terragrunt configuration and CloudTruth! 🙌
{% endhint %}

You can view the outputs that display the parameter values from the CloudTruth Development environment by running `terragrunt run-all output`.

```
AMI = <sensitive>
instance_name = "CloudTruth-development"
instance_type = "t2.micro"
zone = "us-west-2a"
s3_bucket_name = "cloudtruth-grunt-free-panda"
s3_tag_name = "CloudTruth-development"
```

You can change to the production or staging directories and pass the respective CloudTruth environment to deploy various settings across your different infrastructure!

#### Cleanup

Destroy the AWS resources by passing environment variables the same way we created them.

```
cloudtruth --project Terragrunt --env development run -- terragrunt run-all destroy
```

You can see the source code for the Terraform modules and Terragrunt Deploy in the following repos.

{% embed url="<https://github.com/cloudtruth-demo/terragrunt-cloudtruth-deploy>" %}

{% embed url="<https://github.com/cloudtruth-demo/terragrunt-cloudtruth-modules>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cloudtruth.com/configuration-management/integrations/terragrunt.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
