HOW TO LEVERAGE HASHICORP TERRAFORM REMOTE STATE

Referencing resource attributes in Terraform by HashiCorp is fairly straight forward—it just differs slightly depending on where the resource block is defined. If all of the resources are defined in the same .tf file, then it’s simply a matter of referencing the required attribute with the syntax ‘<type>.<name>.<attribute>’. Our root configuration folder looks something like this:

And here in an abbreviated version of our main.tf, we can see the assignment of “${aws_subnet.pri-subnet.id}” to the aws_instance resource’s subnet_id argument:
resource “aws_subnet” “pri-subnet” {
vpc_id = “${aws_vpc.vpc.id}”
cidr_block = “${var.pri_cidr_block}”
availability_zone = “${var.pri_availability_zone}”
}
resource “aws_instance” “instance” {
ami = “${var.ami}”
instance_type = “${var.instance_type}”
subnet_id = “${aws_subnet.pri-subnet.id}”
:
}
As we get better at writing Terraform and decide to modularize what we can, the aws_subnet resource is now defined in a module created for provisioning vpcs. Our folder structure now looks something like this:

And now in order to reference the private subnet id, we will have to make it available as an output from the vpc module. For example:
output "pri_subnet_id" {
description = "Private subnet id"
value = "${aws_subnet.pri-subnet.id}"
}
In our main.tf, we can now see this change reflected in the assignment of the ‘subnet_id’ argument:
module “vpc” {
source = “../modules/vpc”:
}resource “aws_instance” “instance” {
ami = “${var.ami}”
instance_type = “${var.instance_type}”subnet_id = “${module.vpc.pri_subnet_id}”
:
}
So far, so good, right? However, what if the VPC is not provisioned by our main.tf? What if the network team is responsible for the Terraform configuration, which provisioned the VPC? Our file structure might now look something like this, where the network team has their own root configuration folder:

This is where terraform_remote_state steps in. Terraform remote state “Retrieves state data from a Terraform backend. This allows you to use the root-level outputs of one or more Terraform configurations as input data for another configuration”. It is referenced by the terraform_remote_state type and because it is a data source, it provides read-only access, so there is no danger of accidentally interfering with the state file.
As mentioned, the state is retrieved via a Terraform backend. Backends warrant their own post, so we will get deeper into that another time, but in short, a backend refers to where you state is being stored and managed. This could be locally like my folder structure above suggests, which is the default, or it could be in an AWS S3 bucket, in Consul, Artifactory, etc. The full list of supported backends can be found here.
The following is an example of what the ‘terraform_remote_state’ data source configuration in our main.tf might look like for both a local backend and a remote backend: