Joy
Joy

Reputation: 535

How to use terraform output as input variable of another terraform template

Is there any way I can use a Terraform template output to another Terraform template's input?

Ex: I have a Terraform template which creates an ELB and I have another Terraform template which is going to create an auto scale group which need the ELB information as an input variable.

I know I can use shell script to grep and feed in the ELB information, but I'm looking for some Terraform way to doing this.

Upvotes: 22

Views: 45050

Answers (4)

Sachithra
Sachithra

Reputation: 1

When you are integrating terraform with Jenkins you can simply define a variable in the Jenkinsfile you are creating. Suppose you want to run ec2-instance using terraform and Jenkinsfile. So when you need to get the public IP address of the instance you can use this command inside your Jenkinsfile.

script {
  def public_ip = sh(script: 'terraform output public_ip | cut -d \'\"\' -f2', returnStdout: true).trim()                      
}   

This makes proper formatting and saves only the IP address in the public_ip variable. To do that you have to define the output block in the terraform script to output the public ip

Upvotes: 0

Mihai
Mihai

Reputation: 346

The question is about ELB, but I will give an example with S3. It is less things to write. If you don't know how to store terraform state on AWS, read the article.

Let's suppose you have two independent projects: project-1, project-2. They are located in two different directories (two different repositories)!

Terraform file /tmp/project-1/main.tf:

// Create an S3 bucket
resource "aws_s3_bucket" "main_bucket" {
  bucket = "my-epic-test-b1"
  acl    = "private"
}

// Output. It will available on s3://multi-terraform-project-state-bucket/p1.tfstate
output "bucket_name_p1" {
  value = aws_s3_bucket.main_bucket.bucket
}

// Store terraform state on AWS. The S3 bucket and dynamo db table should be created before running terraform
terraform {
  backend "s3" {
    bucket = "multi-terraform-project-state-bucket"
    key = "p1.tfstate"
    dynamodb_table = "multi-terraform-project-state-table"
    region  = "eu-central-1" // AWS region of state resources
  }
}

provider "aws" {
  profile = "my-cli-profile" // User profile defined in ~/.aws/credentials
  region = "eu-central-1" // AWS region
}

You run terraform init, and terraform apply.

After it you move to the terraform file /tmp/project-2/main.tf:

// Create an S3 bucket
resource "aws_s3_bucket" "main_bucket" {
  bucket = "my-epic-test-b2"
  acl    = "private"

  tags = {
    // Get the S3 bucket name from another terraform state file. In this case it is s3://multi-terraform-project-state-bucket/p1.tfstate
    p1-bucket = data.terraform_remote_state.state1.outputs.bucket_name_p1
  }
}

// Get date from another state file
data "terraform_remote_state" "state1" {
  backend = "s3"
  config = {
    bucket = "multi-terraform-project-state-bucket"
    key = "p1.tfstate"
    region  = "eu-central-1"
  }
}

// Store terraform state on AWS. The S3 bucket and dynamo db table should be created before running terraform
terraform {
  backend "s3" {
    bucket = "multi-terraform-project-state-bucket"
    key = "p2.tfstate"
    dynamodb_table = "multi-terraform-project-state-table"
    region  = "eu-central-1" // AWS region of state resources
  }
}

provider "aws" {
  profile = "my-cli-profile" // User profile defined in ~/.aws/credentials
  region = "eu-central-1" // AWS region
}

You run terraform init, and terraform apply.

Now check the tags in the my-epic-test-b2. You will find there the name of the bucket from the project-1.

Upvotes: 0

user10273842
user10273842

Reputation: 31

Looks like in newer versions of Terraform you'd access the output var like this

your_elb = "${data.terraform_remote_state.your_state.your_output_resource}"

All the rest is the same, just how you referenced it.

Upvotes: 3

mcheshier
mcheshier

Reputation: 745

Have you tried using remote state to populate your second template?

Declare it like this:

resource "terraform_remote_state" "your_state" {
  backend = "s3"
  config {
    bucket = "${var.your_bucket}"
    region = "${var.your_region}"
    key = "${var.your_state_file}"
  }
}

And then you should be able to pull out your resource directly like this:

your_elb = "${terraform_remote_state.your_state.output.your_output_resource}"

If this doesn't work for you, have you tried implementing your ELB in a module and then just using the output?

https://github.com/terraform-community-modules/tf_aws_elb is a good example of how to structure the module.

Upvotes: 14

Related Questions