3

In file1.tf (generated by kops) I have a resource like this:

resource "aws_vpc" "my-vpc-tf-id" {
...
}

The resource ID was dynamically generated by kops and also added to terraform.tfvars (so it can be used in other places in the .tf files):

my_var = "my-vpc-tf-id"

Now I would like to reference the VPC resource from file2.tf without hardcoding its name:

resource "aws_security_group" "db" {
  ...
  vpc_id      = "${aws_vpc.${var.my_var}.id}"
  ...
}

but Terraform complains that the ${var.my_var} is not allowed. So instead I define this in file2.tf:

resource "aws_security_group" "db" {
  ...
  vpc_id      = "${aws_vpc.{{MY_VAR_VAL}}.id}"
  ...
}

and I use sed to replace the placeholder with the value. This works well but complicates certain other tasks so I was wondering if there were other ways of achieving this without using sed or hardcoding the my_var value (just Terraform's HCL).

ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177
Oliver
  • 27,510
  • 9
  • 72
  • 103
  • 2
    Generating a file with a varible resource name is not the intended way to use terraform. The names within terraform should be logical and fixed. Unfortunately, you are bound to this due to your usage of kops. The `sed` workaround seems to be best in this case. Maybe open an issue with kops and describe your problem there? – Markus Jul 31 '18 at 06:38
  • Markus's comment is correct, per https://github.com/hashicorp/terraform/issues/18456. Unfortunately the workaround described there does not seem applicable. – Oliver Aug 03 '18 at 13:28

2 Answers2

1

The normal way to do this is to use data sources to look up the thing you want to refer to.

The VPC data source allows you to filter based on a number of different things but a typical one is to use the Name tag:

data "aws_vpc" "selected" {
  tags {
    Name = "${var.vpc}"
  }
}

And then you can refer to this VPC with:

resource "aws_security_group" "db" {
  ...
  vpc_id = "${data.aws_vpc.selected.id}"
  ...
}
ydaetskcoR
  • 53,225
  • 8
  • 158
  • 177
  • 2
    If the VPC is to be created during the same run, this could lead to problems, since the data source is not dependend on the VPC and thus, the information is [being fetched upon state refresh](https://www.terraform.io/docs/configuration/data-sources.html#data-source-lifecycle). At this point, the VPC is not yet available. – Markus Jul 31 '18 at 06:20
-1

The two cases are

(i) if they are both vpc and security group are in same run we can directly refer vpc id in security group without any data sources

resource "aws_security_group" "db" {
  ...
  vpc_id = "${aws_vpc.my-vpc-tf-id.id}"
  ...
}

(ii) if they are run differently (using same remote state files or importing config) use data source as mentioned above by ydaetskcoR

Sudhakar MNSR
  • 594
  • 1
  • 3
  • 17
  • As stated by Oliver, the resource is not named `my-vpc-tf-id`, but rather some variable name (e.g. `vpc-47384-33234`). The name is stored in a varible called `my_var`. – Markus Aug 01 '18 at 06:18
  • what iam trying to say here is we dont need to store it in any variable if it is in single run. – Sudhakar MNSR Aug 01 '18 at 15:23