Referencing Terraform resource created in a different folder

20.9k views Asked by At

I have the following folder structure:

infrastructure
└───security-groups
│   │   main.tf
│   │   config.tf
│   │.  security_groups.tf
│   
└───instances
    │   main.tf
    │   config.tf
    │   instances.tf

I would like to reference the security group id instantiated in security-groups folder by reference. I have tried to output the required ids in the security_groups.tf file with

output "sg_id" {
  value = "${aws_security_group.server_sg.id}"
}

And then in the instances file add it as a module:

module "res" {
  source = "../security-groups"
}

The problem with this approach is that when I do terraform apply in the instances folder, it tries to create the security groups as well (which I have already created by doing terraform apply in the security-groups folder) and it fails because the SGs are existing.

What would be the easiest way to reference the resources created in a different folder, without changing the structure of the code?

Thank you.

2

There are 2 answers

0
lxop On BEST ANSWER

To refer to an existing resource you need to use a data block. You won't refer directly to the resource block in the other folder, but instead specify a name or ID or whatever other unique identifier it has. So for a security group, you would add something like

data "aws_security_group" "sg" {
  name = "the-security-group-name"
}

to your instances folder, and refer to that entity to associate your instances with that security group.

You should also consider whether you actually want to be just applying terraform to the whole tree, instead of each folder separately. Then you can refer between all your managed resources directly like you are trying to do, and you don't have to call terraform apply as many times.

0
skoll On

While lxop's answer is a better practice, if you really do need to refer to output in another local folder, you can do it like this:

data "terraform_remote_state" "sg" {
  backend = "local"

  config = {
    path = "../security-groups/terraform.tfstate"
  }
}

and then refer to it using e.g.

locals {
  sgId = data.terraform_remote_state.sg.outputs.sg_id
}