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 }
It’s already deployed, and we can get this ID from the state using the terraform output
:
$ terraform output vpc_id "vpc-0958e335e1c910ece"
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
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}" } }
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 }
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 ...
Done.