-
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
Top-level Configuration Abstractions #23378
Comments
Thanks, @apparentlymart, I think you've captured my use case nicely here and the referenced discussions are perfectly topical. One note I'll add: Our configs are written by humans and we really like using HCL for this task! We prefer doing so over other alternative languages.
It's easy to get these languages wrong. HCL on the other hand has reasonable declaration and reference mechanisms (define a |
Hi all! Revisiting this some time later, I'm noticing that all of the different ideas listed under "Proposals" have since been met via some new language feature, even if the final design didn't exactly match what was proposed when I opened this:
Since this issue was representing a broad problem space, it's not really possible to objectively decide if it's "done", but it does seem like there are now language features addressing each of the points raised in the write-up and so I'm going to close this now. If anyone has any specific feedback about those features or about other missing pieces then I'd encourage opening a new issue where we can focus on that specific feedback. Thanks! |
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. |
I'm making this new issue to capture a use-case originally shared by @jakebiesinger-onduo in a comment on a PR, so that we can more easily discuss the use-case separately from the specific PR. I have added some general commentary from my own perspective here, so please refer back to the original comment to see the use-case as it was originally presented.
Current Terraform Version
Use-cases
Terraform is commonly by people who are familiar with Terraform concepts and are comfortable writing Terraform configurations, but there are other situations where Terraform is more of an implementation detail, where the intended interface to users is a higher-level configuration file or other interface that raises the level of abstraction in some way.
For example, @jakebiesinger-onduo shared this snippet of a higher-level configuration object for configuring SFTP-based data synchronization:
This configuration format raises the level of abstraction by introducing concepts like partners, triggers, sources, and destinations. The underlying Terraform concepts of modules and resources are encapsulated, allowing the author of such a configuration to think primarily about the higher-level problem being solved and less about the physical infrastructure or Terraform concepts used to implement it.
While Terraform does allow defining a higher-level data structure like the above, the module author must then write expressions to work with that data structure, which runs into challenges of normalization, validation, and conditional action based on how the structure is shaped.
Attempted Solutions
Consider for example the problem of identifying which subset of the partners has opted in to GCS-based triggering by setting
use_gcs_trigger
totrue
. We might want to permit the absense of GCS triggering to be expressed either by settinguse_gcs_trigger
tofalse
, by omitting thetrigger
attribute in the parent object entirely, or by omitting thepull-config
attribute from the partner object entirely.In order to give configuration authors that flexibility in the Terraform language today requires some quite awkward expression constructions:
Our current recommendation is to use module composition so that the module blocks themselves are representing the configuration concepts, which means expressing the configuration using some Terraform language concepts (modules) while still getting some abstraction. For example, we might imagine each partner in the above example having its own module that contains a call to one of many trigger implementations, one of many "source" implementations, and one of many "target" implementations, all connected together using normal module composition techniques:
While we often can model problems this way, it requires the problem to be described within structures imposed by Terraform itself, potentially forcing a less intuitive mental model on those writing the configuration and, most significantly for the use-case we're discussing here, forces those working with the system to be aware that Terraform is being used at all.
Proposals
So far we don't have a single proposal to address this, but there's a collection of existing discussions that might interact with this use-case:
for_each
for modules: could make it more reasonable to wrap module composition in an additional level of abstraction to translate between a higher-level structure and a set of module calls.jsonpath
function proposal (though would likely be a HCL-traversal-syntax based equivalent if we were to move forward with it, to avoid introducing another complex syntax into the Terraform language): can potentially make it easier to work with data structures whose shape is not predictable, as a shorthand for nestedlookup
calls with defaults.If we think about a goal of hiding Terraform entirely from the person who is writing these configurations (which is a more extreme version of this use-case, not necessarily a requirement) then there are some potential solutions in just-in-time Terraform code generation using external software, rather than expressing the entire solution inside Terraform itself. In return for the additional complexity of introducing some more software, the door is opened to possibly select a more appropriate source format for the configuration, such as a custom HCL-based format, or some other domain-specific format that makes sense for the target application.
Hopefully we can collect some other similar examples in this issue to see what common elements help to solve them.
The text was updated successfully, but these errors were encountered: