DEV Community

Arseny Zinchenko
Arseny Zinchenko

Posted on • Originally published at rtfm.co.ua on

Terraform: terraform_remote_state  —  getting Outputs from other state-files

An example of using terraform_remote_state to import outputs from other state files

With the data "terraform_remote_state" we can get the outputs of one project to use in another.

For example, our AWS VPC is created separately from AWS EKS (although in the series Terraform: Building EKS, part 1 – VPC, Subnets and Endpoints VPCs were created as part of a cluster, but then I separated them).

So, to create an EKS, we need to pass the VPC ID to it, so from the data "aws_subnets" you can get a list of subnets in which the Kubernetes cluster will be created.

We could hardcode the VPC values - just set the string variable in which to store the values, and in this case, it is a more or less working solution, since the VPC ID is unlikely to change often. However, if you have many values, or they are dynamic, it makes sense to use terraform_remote_state, which can "go to" an AWS S3 bucket of another project and get the current values directly from the state file.

So, we have a project with a VPC module that has an output:

output "vpc_id" {
  value = module.vpc.vpc_id
}
Enter fullscreen mode Exit fullscreen mode

It’s already deployed, and we can get this ID from the state using the terraform output:

$ terraform output vpc_id
"vpc-0958e335e1c910ece"
Enter fullscreen mode Exit fullscreen mode

The project state itself is stored in AWS S3 with VPC:

$ aws --profile tf-admin s3 ls tf-state-backend-atlas-vpc/dev/
2023-09-22 15:14:43 81292 atlas-vpc-dev.tfstate
Enter fullscreen mode Exit fullscreen mode

Next, in the project with the EKS module, add data "terraform_remote_state":

data "terraform_remote_state" "vpc" {
  backend = "s3"
  config = {
    bucket = "tf-state-backend-atlas-vpc"
    key = "${var.environment}/atlas-vpc-${var.environment}.tfstate"
    region = "${var.aws_region}"
    dynamodb_table = "tf-state-lock-atlas-vpc-${var.environment}"
  }
}
Enter fullscreen mode Exit fullscreen mode

And here, unlike the usual terraform.backend{} configuration, we can use variables.

Create a local variable so that we do not have to change the entire EKS code when there are any changes in the outputs of the VPC:

locals {
  vpc_out = data.terraform_remote_state.vpc.outputs
}
Enter fullscreen mode Exit fullscreen mode

And use this vpc_out:

...
data "aws_subnets" "private" {
  filter {
    name = "vpc-id"
    values = [local.vpc_out.vpc_id]
  }

  tags = {
    subnet-type = "private"
  }
}

data "aws_subnets" "intra" {
  filter {
    name = "vpc-id"
    values = [local.vpc_out.vpc_id]
  }

  tags = {
    subnet-type = "intra"
  }
}
...
module "eks" {
  source = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"
  ...
  vpc_id = local.vpc_out.vpc_id
  subnet_ids = data.aws_subnets.private.ids
  control_plane_subnet_ids = data.aws_subnets.intra.ids
...
Enter fullscreen mode Exit fullscreen mode

Done.


Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Billboard image

Try REST API Generation for Snowflake

DevOps for Private APIs. Automate the building, securing, and documenting of internal/private REST APIs with built-in enterprise security on bare-metal, VMs, or containers.

  • Auto-generated live APIs mapped from Snowflake database schema
  • Interactive Swagger API documentation
  • Scripting engine to customize your API
  • Built-in role-based access control

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay