-
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
Render templates in a different module to where they are defined #26838
Comments
I have a similar use case that the templatefile function doesn't cover and I need to continue using the template_file module data source. In my case, the string templates are not coming directly from a file - they are coming from another terraform provider. The "awkward escaping" mentioned in the template_file documentation is a valid concern, but there isn't any other way to achieve this functionality that I know of without using the template provider. https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file Due to this, the deprecation of the template provider is a real problem as functionality is being removed without a templatestring function to replace it. This is what my use case looks like:
|
@apparentlymart Why is this not a no-brainer? |
Hi all, We have intentionally not implemented any new features that treat strings as templates because our experience with I understand that the underlying use-case here is to have a way for a module to accept as an argument something that describes how to construct a result based on data that the module itself will provide and which isn't accessible to the module caller. We do want to meet that use-case, but want to meet it in a way that avoids the user experience hazard that The The |
Here is my understanding
Our temporary solution now is to use multiple provider "aws" {
region = "us-east-1"
}
data "aws_iam_policy_document" "policy" {
statement {
actions = ["s3:GetObject"]
resources = [
"arn:aws:s3:::$${bucket_name}",
"arn:aws:s3:::$${bucket_name}/*",
"arn:aws:s3:::$${origin_path}/*",
"arn:aws:s3:::$${something_else}/*",
]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::0123456789:root"]
}
}
}
locals {
bucket_name = "bucket_name_world"
origin_path = "origin_path_hello"
something_else = "something_else_foobar"
}
output "override_policy" {
value = replace(replace(replace(data.aws_iam_policy_document.policy.json,
"$${bucket_name}", local.bucket_name),
"$${origin_path}", local.origin_path),
"$${something_else}", local.something_else)
} Which returns $ terraform plan
Changes to Outputs:
+ override_policy = jsonencode(
{
+ Statement = [
+ {
+ Action = "s3:GetObject"
+ Effect = "Allow"
+ Principal = {
+ AWS = "arn:aws:iam::0123456789:root"
}
+ Resource = [
+ "arn:aws:s3:::something_else_foobar/*",
+ "arn:aws:s3:::origin_path_hello/*",
+ "arn:aws:s3:::bucket_name_world/*",
+ "arn:aws:s3:::bucket_name_world",
]
+ Sid = ""
},
]
+ Version = "2012-10-17"
}
) |
@nitrocode It sounds like the hashicorp team is acknowledging the need but don't have a clear solution yet, not necessarily refusing to do anything. They're making a fair user experience argument, even though adding When I opened this ticket I did not know about the It does really suck that it is not being supported but still being suggested as a work around for this gap. |
@apparentlymart @allenhumphreys I believe |
Indeed, it's not clear whether the template provider will ever see new releases for platforms that didn't exist when it was last released. For the moment Terraform CLI itself is not officially released for As @allenhumphreys noted, my answer above was not to say that we don't intend to design an implement a new mechanism for this, but rather that our experience with constant user friction with One thing that |
Our use case is as follows. A user can specify an input variable which is UserData for an EC2 instance, and then leverage Terraform interpolation to bring in the relevant variables, for example, to mount a Terraform-managed EFS filesystem on instance startup. We might do this, for example:
It seems that even with I do suspect that the order of interpolation as well as when templates can be evaluated is some of the complication, and that we may need to move to specific TL;DR -- We need some kind of Terraform |
Second day using Terraform and I need this function... |
I was hoping there was a solution for this... I just started using terraform. |
An alternative is to use the copied template provider with an arm release. This has been done with the following provider and published to the registry. https://registry.terraform.io/providers/cloudposse/template/latest You can achieve this by creating a new file to pin the provider. Using cloudposse # versions.tf
terraform {
required_providers {
template = {
source = "cloudposse/template"
version = "~> 2.2.0"
}
}
} Using gxben # versions.tf
terraform {
required_providers {
template = {
source = "gxben/template"
version = "= 2.2.0-m1"
}
}
} e.g. # main.tf
provider "template" {}
data "template_file" "greeting" {
template = "my name is $${name}"
vars = {
name = "bob"
}
}
# outputs.tf
output "greeting" {
value = data.template_file.greeting.rendered
} returns Changes to Outputs:
+ greeting = "my name is bob" More info: https://gist.github.com/nitrocode/cf40a24054a66afe2b19ca54b7be5d68 |
Since I’ve opened this issue I’ve gotten a lot more experience with Terraform. It’s interesting that I’ve actually never managed to run into the hard edge again and it’s fascinating that so many people new to terraform are ending up here. I am looking forward to the improvements to templating flexibility that are coming because I think it’ll definitely unlock more patterns. But, I don’t currently find myself needing this, even for the thing that originally caused me to open the issue. |
Our use case is as follows: We use a child module to create AWS API gateways ( Our methodology has a number of variable substitutions that need to be done to populate certain elements of the spec file, depending on which of our AWS accounts the deployment is being done in and which app environment we're talking about (volatile, perf testing, prod, and so forth). This is done by having the spec file get returned as a TF-friendly template, which is then populated with those necessary values by means of the Why don't we just populate those values in the root module by pulling the spec, saving it as a temporary file, and then using |
An additional use case here is I only want to update the objects if a file has changed. So I create a data object by reading the file. A terraform_data resource to trigger the lifecycle on. But then because I can't process against a stream I have to reread the file. Seems like a bad design. |
We have a similar case to @MrE194, where we are working on a wrapper module to https://github.com/aws-ia/terraform-aws-eks-blueprints-addon where we receive a list of values (YAML strings) which we want to process as templates, injecting values (in this case IRSA names that are only known at the level of our module) and not at the level of whoever generates the templates. |
@joaocc does #26838 (comment) unblock you? |
@nitrocode that is indeed the workaround we ended up using. |
Thank you for your continued interest in this issue. Terraform version 1.8 launches with support of provider-defined functions. It is now possible to implement your own functions! We would love to see this implemented as a provider-defined function. Please see the provider-defined functions documentation to learn how to implement functions in your providers. If you are new to provider development, learn how to create a new provider with the Terraform Plugin Framework. If you have any questions, please visit the Terraform Plugin Development category in our official forum. We hope this feature unblocks future function development and provides more flexibility for the Terraform community. Thank you for your continued support of Terraform! |
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. |
Current Terraform Version
Use-cases
As part of our Azure configuration, we're making extensive use of API management's policies to perform various request validations. The policies are in XML with embedded C# code and they can be quite long. As part of our complex usage of the policies, we compose smaller policy snippets into complete policies at varying levels of the API management policy scopes. When devising the organization for such a complex set of templates, I encountered a situation where a 2 pass template processing would've been very helpful. Specifically, I wanted to have an initial
templatefile
step capable of outputting a string that would then go through another step of templating, thustemplatestring
.Attempted Solutions
Proposal
Add
templatestring
function to allow modules to output a template to be further processed and fed into the input of a resource or another module.References
The text was updated successfully, but these errors were encountered: