[Terraform] Refer to resource information described in different tfstate

My name is Teraoka and I am an infrastructure engineer

useful
, there's a
This time, I'd like to introduce it.

What is terraform_remote_state?

you want to reference information about resources described in different tfstate files
This data source is useful when

Terraform
when a deployment is executed using terraform apply
has a file called tfstate, which records resource information created

When building infrastructure with Terraform,
if you have multiple environments (such as a jump host, production, and development),
so that `terraform apply` doesn't affect other environments
it's essential to separate the tfstate for each environment

When you split tfstate,
information about resources created in the jump environment
you may want to reference
This is where "terraform_remote_state" comes in handy.

■When to use it

Below is an example using AWS

If we assume that SSH connections to the server are made via a jump server,
how would we create security groups and rules using Terraform?
First, I think we would create a VPC and security groups + rules for the jump server.

bastion.tf

terraform { backend "s3" { bucket = "terraform-tfstate" key = "terraform-blog/bastion.tfstate" region = "ap-northeast-1" } } resource "aws_vpc" "bastion" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { Name = "vpc-bastion" } } resource "aws_security_group" "bastion" { name = "bastion-sg" description = "for bastion server" vpc_id = "${aws_vpc.bastion.id}" tags { Name = "bastion-sg" } } resource "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.bastion.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" cidr_blocks = "XXX.XXX.XXX.XXX" }

In the backend configuration, the tfstate is stored in S3 under the name bastion.tfstate,
but this is fine as it only involves adding a VPC and security group plus an allow rule for specific IP addresses.
So, what about the settings on the "receiving side" from the jump host?

production.tf

terraform { backend "s3" { bucket = "terraform-tfstate" key = "terraform-blog/prod.tfstate" region = "ap-northeast-1" } } resource "aws_vpc" "prod" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { Name = "vpc-prod" } } resource "aws_security_group" "prod" { name = "prod-sg" description = "for production server" vpc_id = "${aws_vpc.prod.id}" tags { Name = "prod-sg" } } resource "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.prod.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" source_security_group_id = "${What should I specify???}" }

If you want to allow SSH connections from a jump server,
you need to allow access from the jump server's security group, so
you need to specify the ID of the jump server's security group using `source_security_group_id`.

However, because the backend description separates the jump server and tfstate,
it is not possible to reference the security group ID in this state.

■How to use it

Now that we've determined that it's not possible, I'd like to make it accessible.
First, we need to add the output setting to the bastion.tf file.

bastion.tf

terraform { backend "s3" { bucket = "terraform-tfstate" key = "terraform-blog/bastion.tfstate" region = "ap-northeast-1" } } resource "aws_vpc" "bastion" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { Name = "vpc-bastion" } } resource "aws_security_group" "bastion" { name = "bastion-sg" description = "for bastion server" vpc_id = "${aws_vpc.bastion.id}" tags { Name = "bastion-sg" } } resource "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.bastion.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" cidr_blocks = "XXX.XXX.XXX.XXX" } ## Add output "security_group_id" { value = "${aws_security_group.bastion.id}" }

When referencing values ​​from different tfstates,
you need to output the values ​​you want to reference beforehand.
In this case, we want to reference the ID of the bastion security group, so
we output aws_security_group.bastion.id.

In this state, you can reference the value from production.tf using terraform_remote_state

production.tf

terraform { backend "s3" { bucket = "terraform-tfstate" key = "terraform-blog/prod.tfstate" region = "ap-northeast-1" } } resource "aws_vpc" "prod" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags { Name = "vpc-prod" } } resource "aws_security_group" "prod" { name = "prod-sg" description = "for production server" vpc_id = "${aws_vpc.prod.id}" tags { Name = "prod-sg" } } resource "aws_security_group_rule" "prod_sg_rule" { security_group_id = "${aws_security_group.prod.id}" type = "ingress" from_port = "22" to_port = "22" protocol = "tcp" source_security_group_id = "${data.terraform_remote_state.bastion.security_group_id}" } ## Add data "terraform_remote_state" "bastion" { backend = "s3" config { bucket = "terraform-tfstate" key = "terraform-blog/bastion.tfstate" region = "ap-northeast-1" } }

We use the `terraform_remote_state` data source
to read the `tfstate` for the jump host stored in S3.
The value can be referenced by the name specified in `output`, so
the value to specify for `source_security_group_id`
will be `data.terraform_remote_state.bastion.security_group_id`.

Summary

`terraform_remote_state` is used quite often, so it's worth remembering.
This means you can split the `tfstate` file without any problems!

If you found this article helpful,please give it a "Like"!
1
Loading...
1 vote, average: 1.00 / 11
11,443
X Facebook Hatena Bookmark pocket

The person who wrote this article

About the author

Yuki Teraoka

Joined Beyond in 2016, I am currently
in my sixth year as an infrastructure engineer and MSP. I handle troubleshooting during incidents and
also design and build infrastructure using public clouds such as AWS. Recently, I have been working
container infrastructure such as Docker and Kubernetes, and
with HashiCorp tools such as Terraform and Packer as part of building and automating
I also take on the role of an evangelist, speaking at external study groups and seminars.

・GitHub
https://github.com/nezumisannn

• Speaking Engagements
: https://github.com/nezumisannn/my-profile

• Presentation materials (SpeakerDeck)
https://speakerdeck.com/nezumisannn

・Certification:
AWS Certified Solutions Architect - Associate
Google Cloud Professional Cloud Architect