Skip to content
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

Support for tag resource with dynamic keys #3143

Closed
dippynark opened this issue Jan 26, 2018 · 8 comments
Closed

Support for tag resource with dynamic keys #3143

dippynark opened this issue Jan 26, 2018 · 8 comments
Labels
new-resource Introduces a new resource. service/ec2 Issues and PRs that pertain to the ec2 service.
Milestone

Comments

@dippynark
Copy link

dippynark commented Jan 26, 2018

Terraform Version

v0.11.2

Affected Resource(s)

For our specific usecase, just aws_subnet, although this affects all resources that support tags

Terraform Configuration Files

We want to use the AWS Terraform provider to tag our public subnet for each Kubernetes cluster that needs to use it to house ELBs. The problem at the moment is that we cannot modify AWS resource tags from a Terraform environment that did not create the resource we want to tag. We also cannot specify dynamic keys for our resources.

Current format

With the current AWS Terraform provider, the best we can do is the following:

Terraform environment A

resource "aws_subnet" "public" {
  vpc_id                  = "${aws_vpc.main.id}"
  cidr_block              = "${aws_vpc.main.cidr_block}"

  tags {
    kubernetes.io/cluster/cluster_b = ""
    kubernetes.io/cluster/cluster_c = ""
    # We want to do something like the following
    # but these sorts of variable substitutions are not possible
    #kubernetes.io/cluster/${var.cluster_b_id} = ""
    #kubernetes.io/cluster/${var.cluster_c_id} = ""
  }
}

Proposed format

We would like an "aws_tag" resource that can use the resource ID imported from a remote state to change resource tags with dynamic keys

Terraform environment A

output public_subnet_id {
  value = "${aws_subnet.public.id}
}

Terraform environment B

resource "aws_tag" "cluster_tag" {
  subnet_id = "${data.remote_state.environment_a.public_subnet_id}"
  key = "kubernetes.io/cluster/${var.cluster_id}"
  value = ""
}

Terraform environment C

resource "aws_tag" "cluster_tag_" {
  subnet_id = "${data.remote_state.environment_a.public_subnet_id}"
  key = "kubernetes.io/cluster/${var.cluster_id}"
  value = ""
}

Expected Behavior

We should be able to assign resource tags with dynamic keys from a terraform environment that doesn't control the resource itself - just uses the resource ID imported from remote state

Actual Behaviour

We currently can only set static tag keys for resources and only from the same Terraform environment that the resource is created in

References

For our usecase, this change is required to use a single public subnet to house ELBs for multiple Kubernetes clusters housed in private subnets - kubernetes/kubernetes#29298 (comment)

@radeksimko radeksimko added enhancement Requests to existing resources that expand the functionality or scope. new-resource Introduces a new resource. service/ec2 Issues and PRs that pertain to the ec2 service. labels Jan 26, 2018
@rifelpet
Copy link
Contributor

This issue isn't specific to the AWS provider, here's a related issue on hashicorp/terraform with a workaround that uses kubernetes tagging as an example.

@seh
Copy link

seh commented May 23, 2018

@rifelpet, I think you missed the main thrust of this request, which also came up in hashicorp/terraform#17352. The idea is to add tags to resources that already exist, whether they're managed by Terraform or not. This is useful for cases like the subnet accumulating related Kubernetes clusters, where you create the subnet once—likely somewhere else, whether with another tool or in another Terraform root module—and later want to add tags to it as, say, new Kubernetes clusters are born.

Less clear is how to handle removal, in the absence of some kind of reference count. The simplest approach would be to have @dippynark's proposed "aws_tag" resource delete the tag from the target resource when the referencing "aws_tag" resource goes away, assuming full ownership over the tag.

@gswallow
Copy link

I looked into the Go code in the AWS provider repository, as was suggested in hashicorp/terraform#17352 (I don't know Go well enough to be helpful there, sorry). To me, it looks like each AWS resource type that the provider supports has its own method to manage tags; there isn't an "add tags to anything" resource that would invoke AWS's EC2 CreateTags API.

I created a janky workaround using the "external" provider, here: https://gist.github.com/gswallow/47a77aa153ff485dbd7f50eba667de15. So far, I've been able to run it more than once and it doesn't complain about updating the tag if it already exists.

@jaksonwkr
Copy link

I did some test here and EKS insert required tags on VPC and Subnets, but the new resource aws_tag can be very useful on another use case. It can be something like this:

resource "aws_tag" "tags_resources" {
  vpc_tags {
    tag {
      key   = "foo"
      value = "bar"
    }

    tag {
      key   = "bar"
      value = "foo"
    }
  }

  subnet_tags {
    tag {
      key   = "foo"
      value = "bar"
    }

    tag {
      key   = "bar"
      value = "foo"
    }
  }
}

So it can be enhanced with other resources types that accepts tags.

@pgporada
Copy link
Contributor

pgporada commented Aug 2, 2019

My issue at https://discuss.hashicorp.com/t/ignoring-changes-to-tags-with-glob/2201/1 may be of use to this conversation.

@bflad bflad removed the enhancement Requests to existing resources that expand the functionality or scope. label Jun 13, 2020
@bflad bflad added this to the v2.67.0 milestone Jun 13, 2020
@bflad
Copy link
Member

bflad commented Jun 13, 2020

A new aws_ec2_tag resource for managing individual EC2 resource tags has been merged and will release with version 2.67.0 of the Terraform AWS Provider, later next week. This resource should only be used in cases where EC2 resources are created outside Terraform (e.g. AMIs), being shared via Resource Access Manager (RAM), or implicitly created by other means (e.g. Transit Gateway VPN Attachments).

# Example configuration in Terraform 0.12 and later syntax
resource "aws_ec2_transit_gateway" "example" {}

resource "aws_customer_gateway" "example" {
  bgp_asn    = 65000
  ip_address = "172.0.0.1"
  type       = "ipsec.1"
}

resource "aws_vpn_connection" "example" {
  customer_gateway_id = aws_customer_gateway.example.id
  transit_gateway_id  = aws_ec2_transit_gateway.example.id
  type                = aws_customer_gateway.example.type
}

resource "aws_ec2_tag" "example" {
  resource_id = aws_vpn_connection.example.transit_gateway_attachment_id
  key         = "Name"
  value       = "Hello World"
}

As with any Terraform 0.12.6 or later configuration, this resource can be combined with for_each support to manage multiple resource tags, if necessary.

Thanks to @joestump and others who made the implementation possible. 👍

Another interesting new feature in this area is the recently released provider-level ignore_tags configuration, which can be used to ignore certain tag keys or tag key prefixes for all resources of the provider and can be very helpful when working with Kubernetes environments.

@bflad bflad closed this as completed Jun 13, 2020
@ghost
Copy link

ghost commented Jun 19, 2020

This has been released in version 2.67.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template for triage. Thanks!

@ghost
Copy link

ghost commented Jul 13, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@hashicorp hashicorp locked and limited conversation to collaborators Jul 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
new-resource Introduces a new resource. service/ec2 Issues and PRs that pertain to the ec2 service.
Projects
None yet
Development

No branches or pull requests

8 participants