New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing aliases for resources (in collections) #1976

Closed
nevir opened this Issue May 15, 2015 · 3 comments

Comments

Projects
None yet
5 participants
@nevir
Contributor

nevir commented May 15, 2015

So, according to #571, interpolated resource names are considered an anti-pattern (and thus won't be supported). However, I'd like to argue that there is a relatively common need for being able to name resources that you wish to parameterize.

A quick example is wanting to have multiple aws_vpc resources, one per AWS region.

The current approach is to build a reverse lookup table so that you can go from name to resource index. It's awkward.

What I'd like to propose is to extend the recent concept of aliasing to resources. Something like:

# Grumble, grumble, list variables would be nice, too :)
variable regions { default = "us-west-1 us-east-1 eu-west-1 ap-southeast-1" }

provider "aws" {
  count = "${length(split(" ", var.regions))}"
  alias = "${element(split(" ", var.regions), count.index)}"
  region = "${element(split(" ", var.regions), count.index)}"
}

resource "aws_vpc" "main" {
  count = "${length(split(" ", var.regions))}"
  # Here's the important bit!
  alias = "${element(split(" ", var.regions), count.index)}"
  provider = "aws.${element(split(" ", var.regions), count.index)}"
  cidr_block = "10.0.0.0/16"
}

Which would let you refer to the resource via (for example) ${aws_vpc.main.eu-west-1}.

In essence, rather than treating the resources as a list, treat 'em as a map. alias defines the key, and if omitted, count.index is used.

@nevir nevir changed the title from Named resource interpolation to Collections of named resources May 15, 2015

@nevir nevir changed the title from Collections of named resources to Providing aliases for resources (in collections) May 15, 2015

@bfgoodrich

This comment has been minimized.

Show comment
Hide comment
@bfgoodrich

bfgoodrich Jun 29, 2016

This seems like a good feature, would allow me to reuse code much more efficiently and still reference useful/helpful names (alias)

bfgoodrich commented Jun 29, 2016

This seems like a good feature, would allow me to reuse code much more efficiently and still reference useful/helpful names (alias)

@uhef

This comment has been minimized.

Show comment
Hide comment
@uhef

uhef Aug 5, 2016

Any news on this?

I've been banging my head on the wall on how to get multi-environment setup working with Terraform while reusing as much resource definitions as possible. My initial try was to use interpolation with resource names but that didn't fly as we know.

To be specific I could use the approach outlined here like this:

variable environments { default = "staging production" }

resource "aws_autoscaling_group" "web-asg" {
  count = "${length(split(" ", var.environments))}"
  alias = "${element(split(" ", var.environments), count.index)}"
  # Beauty: I can now bind the autoscaling group with the associated launch configuration using aliases:
  launch_configuration = aws_launch_configuration.web-lc.${element(split(" ", var.environments), count.index)}
  # ... other required parameters would be here ...
}

resource "aws_launch_configuration" "web-lc" {
  count = "${length(split(" ", var.environments))}"
  # The trick in web-asg is possible because of the line below.
  alias = "${element(split(" ", var.environments), count.index)}"
  # ... other required parameters would be here ...
}

I might also get the environment-specific configuration all wrong, since I'm pretty new at Terraform. If there's an idiomatic and simple way to achieve the environment specific configuration in some other way, I'm all ears. Also if such an approach exists I would recommend adding it to Terraform documentation since being able to maintain multiple identical environments is probably pretty common use case for a lot of teams.

uhef commented Aug 5, 2016

Any news on this?

I've been banging my head on the wall on how to get multi-environment setup working with Terraform while reusing as much resource definitions as possible. My initial try was to use interpolation with resource names but that didn't fly as we know.

To be specific I could use the approach outlined here like this:

variable environments { default = "staging production" }

resource "aws_autoscaling_group" "web-asg" {
  count = "${length(split(" ", var.environments))}"
  alias = "${element(split(" ", var.environments), count.index)}"
  # Beauty: I can now bind the autoscaling group with the associated launch configuration using aliases:
  launch_configuration = aws_launch_configuration.web-lc.${element(split(" ", var.environments), count.index)}
  # ... other required parameters would be here ...
}

resource "aws_launch_configuration" "web-lc" {
  count = "${length(split(" ", var.environments))}"
  # The trick in web-asg is possible because of the line below.
  alias = "${element(split(" ", var.environments), count.index)}"
  # ... other required parameters would be here ...
}

I might also get the environment-specific configuration all wrong, since I'm pretty new at Terraform. If there's an idiomatic and simple way to achieve the environment specific configuration in some other way, I'm all ears. Also if such an approach exists I would recommend adding it to Terraform documentation since being able to maintain multiple identical environments is probably pretty common use case for a lot of teams.

@apparentlymart

This comment has been minimized.

Show comment
Hide comment
@apparentlymart

apparentlymart Jun 14, 2017

Contributor

Hi all! Sorry for the long silence here and thanks for sharing your use-cases.

This feels to me like a different, earlier take on #14275. Although this issue was earlier, the other issue includes a comment from me about the idea we've been thinking about as part of some early design work on the configuration language: a foreach attribute that is similar to count but that takes a map value and produces an instance for each key in the map.

When this issue was first filed, many moons ago, Terraform didn't have good support for lists and maps. Things have improved slightly in the mean time, but things are still a bit clunky in places. The early design work we've been looking at is a holistic look at various use-cases with the goal of making some improvements that compose well together, so along with foreach we would likely have other features to make it easier to construct and transform maps, thus making this solution more reasonable.

I'm going to close this here to consolidate on #14275. It's still early days on this design/prototype work, but we'll hopefully have some more details to share before too long.

Contributor

apparentlymart commented Jun 14, 2017

Hi all! Sorry for the long silence here and thanks for sharing your use-cases.

This feels to me like a different, earlier take on #14275. Although this issue was earlier, the other issue includes a comment from me about the idea we've been thinking about as part of some early design work on the configuration language: a foreach attribute that is similar to count but that takes a map value and produces an instance for each key in the map.

When this issue was first filed, many moons ago, Terraform didn't have good support for lists and maps. Things have improved slightly in the mean time, but things are still a bit clunky in places. The early design work we've been looking at is a holistic look at various use-cases with the goal of making some improvements that compose well together, so along with foreach we would likely have other features to make it easier to construct and transform maps, thus making this solution more reasonable.

I'm going to close this here to consolidate on #14275. It's still early days on this design/prototype work, but we'll hopefully have some more details to share before too long.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment