-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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
providers/aws: add tags for resource_aws_autoscaling_group #13574
Conversation
👍 |
Sorry for pinging directly. Is there any chance to get some initial feedback on this, so that we know if it's a feasible idea? |
Hi @s-urbaniak I agree that dynamic tags for ASG is a reasonable use case and we should support it. 👍 👌 We didn't have a good support for complex data structures like list of maps in the past and the situation still isn't ideal but will improve over time. There are some related caveats to mention:
Perhaps supporting schema validation for a map like this would be a solution: Schema: map[string]*Schema{
"validatableMap": {
Type: TypeMap,
Elem: map[string]*Schema{
"key": {
Type: TypeString,
ValidateFunc: validateKey,
},
"value": {
Type: TypeString,
ValidateFunc: validateValue,
},
"propagate_at_launch": {
Type: TypeBool,
},
},
},
}, but this is not something to implement on the provider/resource side - at least not now as schema doesn't support such validation and we need to figure out whether/how we're going to support deeper nesting, i.e. map of maps etc. I need to discuss this with other maintainers which work closer to the core to see what's the best way forward before I give you any specific suggestions. Thanks for the patience. |
Hi @radeksimko, thanks a lot for your detailed analysis!
Agreed, it would be very nice to add maps validation. I am fixing my local branch to simply ignore invalid map values for this use case.
That is actually a very good catch! I am already working on fixing that very crash including tests.
Our use case involves parametrization via configuration files, so indeed it does not apply.
That would be great to get some feedback on how to accomplish this feature! In the meanwhile I am working on fixing the mentioned edge cases. Having said that it would be great to land this as a stop-gap solution once I fix the above edge cases :-) |
e47c178
to
82bda74
Compare
@radeksimko I fixed the review comment about the potential crashes, also incorporating invalid values into the test. Do you mind to have another look? |
@radeksimko I have been brainstorming with @alexsomesan how we can come up with a more sensible solution while still being idiomatic with the current type system and its limitations: we leave the new attribute A sample configuration would then look like this:
In the example above the tag keys What do you think? |
Nice, I like that solution. |
Just pitching in to highlight the fact that this latter approach using plain maps is exactly in line with the current tagging syntax of the other resources, which also don't validate the tags map. |
Hello @radeksimko, just kindly pinging if you had the chance to reiterate on the comments above. Sorry for the noise, and thanks a lot! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @s-urbaniak
thank you for the patience. I took some time to discuss the problem with a few folks from the team which are more involved in the core/schema part of the codebase.
The conclusion is that we more or less agree this is not an ideal solution due to potential confusions in naming (tag
& tags
) and we generally perceive it as a workaround for currently limited HCL capabilities in Terraform.
That said we already have solid mechanisms in place which will allow us to deprecate one or the other field in the future gracefully when the HCL capabilities become more ideal, so it's not set in the stone forever and that is why we're happy to proceed with this PR.
I left you some questions/comments there - please have a look and let me know what you think.
} | ||
|
||
if v, ok := attr["propagate_at_launch"].(string); ok { | ||
propagate_at_launch, _ = strconv.ParseBool(v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any specific reason to ignore this error here?
Also - perhaps a nitpick - but we prefer camelCase for internal variables rather than under_score.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same reasoning as above, "ignore on error" and keep going. I am happy to introduce returning an error and also camelCase'ing.
} | ||
|
||
if _, ok := attr["value"]; !ok { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason to ignore such case as it's an invalid block of code? I think it would make more sense to just return error in case that key
, value
or propagate_at_launch
are not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There have been no strong reasons, other than "ignore on error". I will introduce returning an error then.
Type: schema.TypeList, | ||
Optional: true, | ||
Elem: &schema.Schema{Type: schema.TypeMap}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason we should accept both fields and deal with all kinds of potential edge cases related to that? If not, would you mind making them mutually exclusive via ConflictsWith
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Letting tag
and tags
be able to merge together just makes it nice when declaring default tags using tag
and bringing in additional tags
in like so: https://github.com/coreos/tectonic-installer/blob/45dfc2b/modules/aws/master-asg/master.tf#L35-L47.
I have no strong opinion on letting this be mutually exclusive, but from a logical standpoint I don't see why they should be.
I let you have the final word on this one :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, since you mentioned if I can make them mutually exclusive: please take a look at my example posted above and let me know if you stand with your opinion to make it mutually exclusive; again I am happy to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what do you mean - static, predefined tags combined with more tags from a variable.
I think this should work just fine
tags = [
{
key = "foo"
value = "bar"
propagate_at_launch = true
},
{
key = "lorem"
value = "ipsum"
propagate_at_launch = false
},
"${var.additional_tags}"
]
The main reason to make those mutually exclusive is to avoid having to document and deal with edge cases like duplicate tags or even conflicting ones (which one is the point of truth) and also to avoid any potential confusion in the heads of users - i.e. I don't want users to have to think about edge cases at all.
Also we don't have an acceptance test for importing ASGs yet, but I'm pretty confident it would fail in this PR because you're assuming that there's a config available - i.e. GetOk()
in Read()
decides which field to populate and during import none of those fields will be available, so none will be populated.
We need to decide which field is going to be the point of truth for this context. I'd vote for the existing tag
field to avoid breaking changes.
I'm going to create the mentioned test and cc you in the PR, just for context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually we do have a test for it, just in a different file I was expecting and it is failing on this branch:
=== RUN TestAccAWSAutoScalingGroup_importBasic
--- FAIL: TestAccAWSAutoScalingGroup_importBasic (206.37s)
testing.go:280: Step 1 error: ImportStateVerify attributes not equivalent. Difference is shown below. Top is actual, bottom is expected.
(map[string]string) {
}
(map[string]string) (len=13) {
(string) (len=5) "tag.#": (string) (len=1) "1",
(string) (len=18) "tag.4237349706.key": (string) (len=7) "FromTag",
(string) (len=34) "tag.4237349706.propagate_at_launch": (string) (len=4) "true",
(string) (len=20) "tag.4237349706.value": (string) (len=6) "value1",
(string) (len=6) "tags.#": (string) (len=1) "2",
(string) (len=8) "tags.0.%": (string) (len=1) "3",
(string) (len=10) "tags.0.key": (string) (len=9) "FromTags1",
(string) (len=26) "tags.0.propagate_at_launch": (string) (len=1) "1",
(string) (len=12) "tags.0.value": (string) (len=6) "value2",
(string) (len=8) "tags.1.%": (string) (len=1) "3",
(string) (len=10) "tags.1.key": (string) (len=9) "FromTags2",
(string) (len=26) "tags.1.propagate_at_launch": (string) (len=1) "1",
(string) (len=12) "tags.1.value": (string) (len=6) "value3"
}
I see where you're coming from with that idea, but I'm not too inclined to it. Terraform should make users aware that ASG tags are somewhat special - i.e. require Also I take it as benefit if we can stick to the conventions in the upstream API - i.e. list of maps as people coming from other tools or generating HCL/JSON may find it useful. |
@radeksimko No worries at all for the late reply! I appreciate your effort in looking at this! Regarding my second suggestion it was just a suggested workaround. We do like the current solution better too. I will post an update on this PR tomorrow which will address your review comments, just please let me know your final decision on the mutual exclusiveness on |
@s-urbaniak Thank you for a quick response. Just to add one important thing - can you make sure you run all relevant (that is all ASG) acceptance tests and check they're all passing with this PR?
|
@radeksimko definitely, thanks for the pointer on those tests, I already am half-through the comments locally (error handling) and will make sure those tests pass too. |
@radeksimko PTAL, I think I addressed all the review comments. Here is the output of the acceptance test. Without deeper investigation I believe the failed
|
The existing "tag" field on autoscaling groups is very limited in that it cannot be used in conjunction with interpolation preventing from adding dynamic tag entries. Other AWS resources don't have this restriction on tags because they work directly on the map type. AWS autoscaling groups on the other hand have an additional field "propagate_at_launch" which is not usable with a pure map type. This fixes it by introducing an additional field called "tags" which allows specifying a list of maps. This preserves the possibility to declare tags as with the "tag" field but additionally allows to construct lists of maps using interpolation syntax.
Hi @s-urbaniak I'm just waiting for acceptance tests to finish and if all pass I'll merge it. |
@radeksimko Great news, thanks a ton! |
Since upstream wants them mutually exclusive. See hashicorp/terraform#13574 (comment) for a rationale.
in what version of terraform will this be available? the example posted above by @s-urbaniak doesn't work with 0.11.1 |
@luisdavim You can double check your current core and provider versions with If you're still having trouble, I would suggest opening an issue in the terraform-provider-aws repository. Hope this helps! |
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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
The existing "tag" field on autoscaling groups is very limited in that it
is unable to accept a dynamic list of tag entries.
Other AWS resources don't have this restriction on tags because they work
directly on the map type.
AWS autoscaling groups on the other hand have an additional field
"propagate_at_launch" which is not usable with a pure map type.
This fixes it by introducing an additional field called "tags" which
allows specifying a list of maps. This preserves the possibility to
declare tags as with the "tag" field but additionally allows to
construct lists of maps using interpolation syntax.
/cc @philips @Quentin-M @sym3tri @alexsomesan