# Terraform

This walkthrough shows you how to pass CloudTruth parameters as Environment Variables to Terraform.

You can also use CloudTruth to externally reference backend [tfstate output as an external parameter](/configuration-management/parameters/parameter-management/external-values/terraform-state-files.md#remote-state-with-terraform).

## Prerequisites

* You know basic [Terraform](https://learn.hashicorp.com/terraform).
* You have created a [CloudTruth API Access token](/org-management/access-control/access-tokens.md) and installed the [CLI](/configuration-management/cli-and-api/cloudtruth-cli.md#installation).

## Terraform deploy with CloudTruth

For this example we will build on top of the [Terraform AWS tutorial](https://learn.hashicorp.com/tutorials/terraform/aws-variables?in=terraform/aws-get-started) to deploy an EC2 instance defining variables with CloudTruth parameters. You can use any target for your deploys.

### Set CloudTruth Terraform Variables

Create a CloudTruth Project called `Terraform`.

```
cloudtruth project set Terraform
```

Now you can create the CloudTruth parameters in the Terraform project that we will pass to Terraform as [environment input variables](https://www.terraform.io/docs/language/values/variables.html#environment-variables) with the `TF_VAR_` convention.

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

### Create Terraform Configuration

From your [Terraform working directory](https://learn.hashicorp.com/tutorials/terraform/aws-build?in=terraform/aws-get-started) update your `main.tf` with the following configuration.

```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }
}

provider "aws" {
  profile = "default"
  region  = "us-west-2"
}

resource "aws_instance" "cloudtruth" {
  ami           = var.ami
  instance_type = var.instance_type 
  availability_zone = var.availability_zone_names[0]

  tags = var.resource_tags
}

output "zone" {
  value = aws_instance.cloudtruth.availability_zone
}

output "AMI" {
  value = aws_instance.cloudtruth.ami
}

output "instance_type" {
  value = aws_instance.cloudtruth.instance_type
}

output "instance_name" {
  value = aws_instance.cloudtruth.tags.Name
}

#########################
####### VARIABLES #######
#########################

variable "ami" {   
  description = "Value of the Amazon Machine Image"
  type        = string
  }

variable "instance_type" {   
  description = "Value of the Instance Type"
  type        = string
  }
  
variable "availability_zone_names"{
  description = "List of available regions"
  type        = list(string)
 }  
 
variable "resource_tags" {
  description = "Tags to set for all resources"
  type        = map(string)
}
```

This main.tf will deploy an EC2 instance to us-west-2 and [defines four variables](https://learn.hashicorp.com/tutorials/terraform/aws-variables?in=terraform/aws-get-started) that are centrally managed by CloudTruth. It also shows you how to use various Terraform variable [types](https://www.terraform.io/docs/language/expressions/types.html#types) such as a [map](https://www.terraform.io/docs/language/expressions/types.html#map) and [list](https://www.terraform.io/docs/language/expressions/types.html#list).

| Variable                  | Type   | CloudTruth Value                                                                            |
| ------------------------- | ------ | ------------------------------------------------------------------------------------------- |
| ami                       | string | ami-830c94e3                                                                                |
| instance\_type            | string | t2.micro                                                                                    |
| availability\_zone\_names | list   | \["us-west-2a", "us-west-2b"]                                                               |
| resource\_tags            | map    | {"Name":"Cloudtruth-Instance","project":"CloudTruth Run Terraform","environment":"default"} |

### Build Terraform Infrastructure

From your Terraform working directory [initialize the infrastructure](https://learn.hashicorp.com/tutorials/terraform/aws-build?in=terraform/aws-get-started#initialize-the-directory).

```
terraform init
```

Now when executing a `terraform plan` you will notice that you are prompted to enter values for each variable defined.

```
terraform plan
var.ami
  Value of the Amazon Machine Image

  Enter a value: 
```

**CloudTruth Run**

You can manage your Terraform configuration centrally with CloudTruth and pass Terraform [environment input variables](https://www.terraform.io/docs/language/values/variables.html#environment-variables) with the cloudtruth run CLI command.

The following command will pass the variables from the `Terraform` project where we set our input variables directly into `terraform apply`.

```
cloudtruth --project Terraform run -- terraform apply
```

Terraform will show the outputs and deploy the instance with our CloudTruth values.

```
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

AMI = "ami-830c94e3"
instance_name = "Cloudtruth-Instance"
instance_type = "t2.micro"
zone = "us-west-2a"
```

Couple this method with CloudTruth Environments and you can manage and deploy different instance types with various configuration setting to your Prod, Dev and Staging with a single command.

**Terraform Input Variables**

CloudTruth run injects environment variables into your terraform commands. Terraform searches the environment for variables that contain [`TF_VAR_`](https://www.terraform.io/docs/language/values/variables.html#environment-variables) preceding the variable name defined in your configuration script. The variable is case sensitive so if it is lower case in `main.tf` the variables must have lower case key names in CloudTruth.

Environment input variables have a specific [order of precedence](https://www.terraform.io/docs/language/values/variables.html#variable-definition-precedence) and CloudTruth run can be used with any combination that Terraform allows. Values from CloudTruth run be overridden by a file if the same variable exists in a `terraform.tfvars` or any of the higher precedence methods of passing values.

{% hint style="info" %}
Terraform loads variables in the following order, with later sources taking precedence over earlier ones:

* Environment variables
* The `terraform.tfvars` file, if present.
* The `terraform.tfvars.json` file, if present.
* Any `*.auto.tfvars` or `*.auto.tfvars.json` files, processed in lexical order of their filenames.
* Any `-var` and `-var-file` options on the command line, in the order they are provided. (This includes variables set by a Terraform Cloud workspace.)
  {% endhint %}


---

# 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/terraform.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.
