-
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
lang/funcs: add template function #24978
base: main
Are you sure you want to change the base?
Conversation
Codecov Report
|
Hi @barryib! Thanks for working on this. Not having dynamic templates was an intentional designed decision for For that reason, I feel reluctant to add this as a core Terraform Language feature: while there are certainly some unusual situations where such a thing can be useful, having a prominent built-in language function often makes something appear to be a recommended practice rather than a pragmatic compromise. I'd be curious to see if you can solve your original problem using the If you'd be willing, I'd also be curious to hear more about your use-case that benefits from dynamic template rendering, separately from how that might be solved. I've heard a few reasonable use-cases already, but it's always useful to hear the motivation for less-common requests to see if they might be addressed in a different way in future. Thanks again for working on this! |
Hi @apparentlymart Thanks for your answer.
I'm know getting some explanation about why we don't just have a
I'm one of maintainers of terraform-aws-eks and we recently took the move to remove the template_file datasource. The template_file datasource was causing a lot of unexpected changes during plan phase. As @dpiddockcmp mentioned in terraform-aws-modules/terraform-aws-eks#854
Furthermore, in the template provider, there is a recommendation using the template function.
Using the template function solves all those issue and we got more confident in our In the terraform-aws-eks module we allow users to provide their own template for the userdata. Some of them (like @mbarrien) need to generate some part of that userdata dynamically (gather components created by another team) before passing it to the module. So I will happy to use the template file datasource, but so far, it sounds like there isn't the recommended way to deal with template in Terraform 0.12 and it adds noise during refreshes. Maybe @mbarrien or @dpiddockcmp want to add more inputs. |
Thanks for sharing those additional details, @barryib. If I'm understanding correctly the issue you had with With that said, I'd like to wait and see how the situation changes with #24904 merged. If that resolves the problem of Terraform pessimistically marking the template result as unknown during planning then I expect we'd choose to resolve this by changing the recommendation in the Thinking specifically about the use-case of rendering a First, I'd add an output value to the module that includes all of the same data you were passing to output "user_data_vars" {
value = {
for worker in var.worker_groups : worker.name => merge(
{
platform = lookup(worker, "platform", local.workers_group_defaults["platform"])
cluster_name = aws_eks_cluster.this[0].name
endpoint = aws_eks_cluster.this[0].endpoint
cluster_auth_base64 = aws_eks_cluster.this[0].certificate_authority[0].data
pre_userdata = lookup(
worker,
"pre_userdata",
local.workers_group_defaults["pre_userdata"],
)
additional_userdata = lookup(
worker,
"additional_userdata",
local.workers_group_defaults["additional_userdata"],
)
bootstrap_extra_args = lookup(
worker,
"bootstrap_extra_args",
local.workers_group_defaults["bootstrap_extra_args"],
)
kubelet_extra_args = lookup(
worker,
"kubelet_extra_args",
local.workers_group_defaults["kubelet_extra_args"],
)
},
lookup(
worker,
"userdata_template_extra_args",
local.workers_group_defaults["userdata_template_extra_args"]
)
)
) if var.create_eks
}
} You can then define an input variable for passing in user data for each worker: variable "worker_user_data" {
type = map(string)
description = "A map from worker names as defined in worker_groups to user data strings. Use values from the output value user_data_vars to construct these dynamically."
} Your users can then produce the values from module "eks" {
source = "terraform-aws-modules/eks/aws"
# ...
worker_user_data = {
for name, vars in module.eks.user_data_vars :
name => templatefile("${path.module}/eks_user_data.tpl", vars)
}
} If the change in #24904 ends up addressing the problem here then this would be moot and unnecessary, but I'm just including this here for completeness now so that other future readers of this can see some of the different options on the table to address this use-case. |
@apparentlymart Indeed #24904 would improve the template_file datasource consistency in Terraform 0.13. Thanks for sharing this information.
I can see that #24904 is now merged. Did you get time to test it ? But I'm still thinking that a it worth adding a generic template function which can be used for file contains or dynamic one. With all the recent improvement you've made in the Furthermore, the double escaping you're referring to will be used for only inline (with here docs) template. Users will probably do that, but for only a small (few lines) template. Maybe we should let user decide what they want to use and in that way, I think we can just add As for the workaround you shared, I would probably help in theory. But when I tried it, Terraform complains for Cycles.
In your example, you use the module output as input for the same module. module "eks" {
source = "terraform-aws-modules/eks/aws"
# ...
worker_user_data = {
for name, vars in module.eks.user_data_vars :
name => templatefile("${path.module}/eks_user_data.tpl", vars)
}
} Any suggestion to solve this ? Again, Thanks a lot for your time and your comments. They really help to move forward ❤️ |
I have not yet tested #24904 with your module and likely will not have time to in the very immediate term, because that PR belongs to a project that other members of the team are working on and so my development focus is currently elsewhere. However, if you'd like to test yourself in the meantime you could potentially build Terraform yourself from the That cycle error suggests that some of the values included in the The requirement here is that the |
I'll wait Terraform 0.13.0-beta1 for tests. But it'll be for my personal knowledge, because users are still far from using it in production.
Unfortunately, we can't fulfill that requirement.
In the modulelocals {
launch_template_userdata_vars = [for worker in var.worker_groups_launch_template : merge(
{
platform = lookup(worker, "platform", local.workers_group_defaults["platform"])
cluster_name = aws_eks_cluster.this[0].name
endpoint = aws_eks_cluster.this[0].endpoint
cluster_auth_base64 = aws_eks_cluster.this[0].certificate_authority[0].data
pre_userdata = lookup(
worker,
"pre_userdata",
local.workers_group_defaults["pre_userdata"],
)
additional_userdata = lookup(
worker,
"additional_userdata",
local.workers_group_defaults["additional_userdata"],
)
bootstrap_extra_args = lookup(
worker,
"bootstrap_extra_args",
local.workers_group_defaults["bootstrap_extra_args"],
)
kubelet_extra_args = lookup(
worker,
"kubelet_extra_args",
local.workers_group_defaults["kubelet_extra_args"],
)
},
lookup(
worker,
"userdata_template_extra_args",
local.workers_group_defaults["userdata_template_extra_args"]
)
) if var.create_eks
]
}
output "workers_launch_template_user_data_vars" {
description = "User data template vars of worker launch template groups"
value = local.launch_template_userdata_vars
} In the root modulemodule "eks" {
source = "terraform-aws-modules/eks/aws"
# ...
worker_groups_launch_template = [
{
name = "worker-group-1"
instance_type = "t2.small"
asg_desired_capacity = 2
public_ip = true
# This are module.eks.workers_launch_template_user_data_vars passed by the module to it's template
# Use this to create/expand your template whatever you like
# For the example, we use `templatefile`, but you can use what you want
userdata_template_raw = templatefile("${module.path}/custom_userdata.sh", module.eks.workers_launch_template_user_data_vars)
},
{
name = "worker-group-2"
instance_type = "t2.medium"
asg_desired_capacity = 1
public_ip = true
# This are module.eks.workers_launch_template_user_data_vars passed by the module to it's template
# Use this to create/expand your template whatever you like
# For the example, we use `templatefile`, but you can use what you want
userdata_template_raw = templatefile("${module.path}/custom_userdata.sh", module.eks.workers_launch_template_user_data_vars)
},
]
} So if I summarizeIt sounds like there is no way for us to avoid using the "flaky" template_file datasource unless a function like For you, it's a no go for this PR or any other proposition to add function to render string template ? |
Hello @apparentlymart, it sounds like the template_file data source is now archived https://github.com/hashicorp/terraform-provider-template and superseded by the templatefile function. With that we loose the ability dynamically generate templates (because the template file must be present before terraform runs) Shouldn't we reconsider this PR ? |
Hi @pselle, how can we move forward on this ? |
@barryib Since this likely pinged people on-thread, I'll share some information about what's going on with my assignment here for some clarity :) The Terraform team recently took some time to evaluate some popular PRs, and this was one of them. What I'll be doing is evaluating whether or not to recommend this function addition move forward, before (or if at all) recommending updating this pull request to not-conflict with the latest Terraform codebase. There's no timeline attached to this, but I picked up this PR with the intention to answer this question: should this function be added to the Terraform codebase, or do alternative solutions (for example community modules) fulfill this gap. For example, the hashicorp/dir/template implements a template directory strategy for that particular need. I hope this gives some more context on what assignment "means" in this particular scenario, and I'll be returning to this PR at some point to share the decision of the Terraform Core team. |
Thank you so much @pselle for sharing this information. Really appreciated. I'll continue to update this PR and resolve conflict until a decision is made. Thanks again for your answer. PS: All my pings were about to get more information on the current decisions for this PR. My principal concern was to know if I should continue to work on this and keep updating this PR. And you answered that. |
5d0beaf
to
0f5336a
Compare
0f5336a
to
002a535
Compare
002a535
to
d86c215
Compare
Just as an additional input for the decision making: Looks like template provider has issues with the brand new terraform 0.14. I've got this issue while passing sensitive variable to template_file: Provider is archived so I am not even sure if it is going to be resolved (or even should be resolved). |
Hi, will this PR go somewhere ? Since the template datasource depreciate, it'll be nice to continue to support dynamic templating with this template function. |
Maybe #28700 will address this ? |
The
templatefile
function is great way ton render template in a consistent way. But so far, we don't have the ability to render dynamic templates in the same way and are forced to use the template_file data source.Here is our use case terraform-aws-modules/terraform-aws-eks#882 (comment).
This
template
(we can recall ittemplatestring
if needed) function is more generic and take a template as a string and try to render it.It can work with the
file
function and will behave like thetemplatefile
Maybe, this can replace the
templatefile
function ? Or at least, we can have both.Related links