-
Notifications
You must be signed in to change notification settings - Fork 9.7k
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
Allow plugins to export custom functions #2771
Comments
I should note that you can create a plugin that exports resources to compute things for you right now, but I think functions would be more appropriate than read-only + compute-once resources in many/most cases. |
Yep totally - this is something I've thought about as well. The use case is absolutely clear, but the implementation is very important to get right so we don't shoot our future selves in the foot with a difficult-to-support ecosystem of configs. I will join @mitchellh in the |
Just glad to hear that there's interest in this. Looking forward to what you come up with :) |
+1 on CIDR functions |
Heh... this is the first time I came across this issue, but funny that two of your three example use-cases have been implemented in the mean time:
No URL parsing yet, but I think that's suitably generic that it could be in core too. I think continuing to add things to core Terraform will be sufficient at least until a function comes along that is truly specific to one particular set of resources, e.g. a function for parsing AWS IAM policy documents. |
Why not support a "sh" function in variable interpolation, and then the user can run anything he wants? |
This is also something I'll like to have. My use case is to remove account section and region section of AWS ARNs to store them in policy documents. This is provider specific and can not be a generic function, and I want this because this allows to reuse policies with resources across regions. For example if I use in the resource section |
As another example usecase: we have a standard set of tags that we like to apply across all of our AWS resources, and the values of some of the tags vary per-resource (usually on the names of things). Being able to create a function that returned a map of those tags would be an effective way to make sure we're tagging everything consistently. For example, something like |
It seems that this issue has grown to represent a couple different use-cases. That's fine (we may choose to split them later if one gets addressed first, but we'll see), but I just wanted to write them down here for future reference: Functions as part of a provider pluginA few times now we've seen situations where it would be handy to have a function that does something provider-specific, like parsing an AWS ARN. It's felt weird to add such functions to Terraform Core, but they could potentially be at home in the A possible design we considered for this is to extend HCL with a "function namespace" syntax, allowing extension functions to be placed in a namespace named after the provider itself. For example, if we choose This is not something we plan to do in the very near future because it may require some changes to HCL and so we want to make sure those changes feel right for HCL in general (since HCL is used by more than just Terraform) before moving forward with it. But we do see how it would be useful, and would like to do something like it eventually. User-defined functions in configurationWith the above implemented, you could potentially write a provider plugin that only includes functions and use that to deal with user-defined functions, which are truly specific to a particular configuration or set of configurations and make no sense to share with others. However, we've also thought about offering some syntax for this inside the configuration language itself, allowing local functions to be written as well as local values. Some challenges/questions down this path are:
General constraints on extension functionsHowever they are implemented, there are some constraints that must hold for functions in Terraform's current model. While some of these may be able to change slightly, I think for initial design we should assume they are fixed design constraints:
As a consequence of the above restrictions, I expect that functions-in-providers support would be implemented by running the functions in an unconfigured provider context, constrained similarly to the context used for validation, and that user-defined functions would be implemented in HCL itself or some other language that can guarantee "pure function" behavior. As was implied in other earlier comments above, this is one of those issues where the design of it is the hardest part -- making sure whatever is added is reliable, sustainable, and interacts well with other features -- with the subsequent implementation then probably relatively straightforward. Therefore we're going to keep "thinking" on this for now, representing that there's still some more design work to do. We've been focused on configuration language work for a long time now, so I expect in the very near future we're going to cast our attention into some other areas that have been somewhat neglected during development of v0.12.0. We do still intend to return to this problem of extensible functions eventually, though. |
@jhoos I've accomplished this by doing something like the following:
|
A use case I have would be for some string operations. A common pattern we have for resource names is "(current-git-branch)-(resource-specific-suffix)". These can get quite long, and sometimes long branch names will mean it goes over the limit of a given resource name (and of course each resource name has different limits). What I'd love to be able to define is a function that would combine these, and truncate the git branch name as needed (possibly with a sha of the git branch name as a suffix so that 2 git branches differing in only the last character don't clash). This would be wonderful as a pure string manipulation function that I could define once and use everywhere, but is a nightmare if I have to do it in every single resource. (Even better would be if somehow the function could know the resource name limits for the resource in which it was being invoked, but I imagine that's a step too far) |
Indeed. I would like to create a function that would essentially do this and be able to call it to generate a compliant name for all the resources that need it by simply passign the right arguments:
That way I could create different functions for different Azure resources with different weird name rules instead of having to declare a local for every resource and repeat the code all over the place. |
How about extending hcl by a function that can pass a query into external data resources inline... something like the external_lookup function below:
|
I think the main use case here for enterprises is to simplify naming conventions and extracting things from them, to simplify end-user configs like shown in comment above. Custom functions would help greatly with that ! |
regarding the need for functions to be Sounds like the only problem to solve here is distribution and how functions are referenced? |
#31419 add jsonindent function |
Hi @MallikharjunaTeja! Thanks for your interest in contributing. The implementation of the feature described here is non-trivial and so if you are interested in working on it then I think we'd prefer to first discuss the design you have in mind. We wouldn't want to encourage you to implement it and then afterwards have to ask you to significantly change your approach if it were not a good fit for Terraform Core's architecture. I previously wrote an initial prototype implementation of this in #31225, and my opening comment there includes some notes about some remaining design questions we need to answer before we could proceed with an implementation of this mechanism. |
This can already be done with local_exec and introduces issue, namely platform dependency (now everywhere your terraform code is used needs to have the right shell or utilities called by the shell like jq or cat or sed which are not platform independent eg on macos sed has a few different switches than the one used on ubuntu). |
Hi all! A first round of this is coming in the forthcoming Terraform v1.8. Of course, this is one of those things where having it just in Terraform Core doesn't really achieve anything because there are not yet any functions to call, and providers can't offer functions until the SDK and framework offer a way to do that, so the work in this repository is done for now (and so I'm going to close this issue) but it will take some time for the surrounding ecosystem to make use of this. The provider framework documentation section Functions has information on how this feature is exposed for provider developers. Work on those docs will continue as this feature rolls out. |
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. |
It would be interesting to allow the set of functions allowed in interpolations to be an extension point for plugins. For example, one could write a plugin that exports a function to encode a string into base64, split a root CIDR block into a list of smaller CIDR blocks that covers the root block, or read a string from a URL.
The text was updated successfully, but these errors were encountered: