-
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
Ability to create custom types. #27365
Comments
Just wanted to check on the status of this -- it's very useful. It'd actually be useful to somehow be able to export a type definition from a module, as well. So we can define the input type(s) for a module and reuse them in other places. |
Has there been any discussion or consideration of this enhancement? I think this would be super valuable, and would be one of the best things that could be done to improve consistency and code quality within terraform. |
This would indeed be very helpful. Any chance we might be able to see this at some point? |
Complementing this feature request, it would be pretty useful to also have the same features as input variable in custom type definitions:
Below an example:
type "db_password" {
description = "Database administrator password"
type = string
sensitive = true
}
type "timestamp" {
description = "Example of how to validate a type a formula defined by an expression"
type = string
validation {
condition = can(formatdate("", type.timestamp))
error_message = "value for timestamp type requires a valid RFC 3339 timestamp"
}
default = timestamp()
}
type "result" {
description = "Example of validation for enum/option type"
type = string
validation {
condition = anytrue([
type.result == "good",
type.result == "bad",
type.result == "ugly"
])
error_message = "value for variable of type result must be 'good', 'bad', or 'ugly'"
}
default = "good"
}
local {
ip_address_regex = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
}
type "ip_address" {
description = "Example of using a local constant for type validation"
type = string
validation {
condition = can(regex(local.ip_address_regex, type.value))
error_message = "Invalid IP address provided."
}
}
type "configuration" {
description = "Example of using other types for type definition"
type = map(
object({
x = type.timestamp
y = type.result
z = list(type.ip_address)
})
)
}
variable "configuration" {
type = type.configuration
}
variable "multiple-configurations" {
type = list(type.configuration)
} |
Truely interested in this feature! |
That feature would be indeed very useful and a great complement of this optional var improvement coming in v1.3. |
I adhere to the declarative paradigm when it is available, because it adds visibility and versionning to previously unused branches (by me at least) such as infrastructure build and evolution, and it also describes "what we want" instead of "how we obtain" it... Unfortunately, it is still a pain today as many basic coding tools that exist in the imperative paradigm are quite far behind in Terraform. I'm quite new to contributing to opensource, I've seen in the contribution guide for Terraform that a new feature must be discussed and receive feedback before implementations are even considered. I'd say this issue is it, and would love to dip my toe in building a solution. As such, I'd love some pointers on where to start. Kudos for this feature request. |
I wished this existed more than once in the past. Every time a have to declare multiple variables of the same structure I wish I could declare a custom type once and use it multiple times declaratively instead of replicating the same structure over and over again in each var. |
This would be an incredibly useful feature, particularly if there is a mechanism to reuse definitions of complex types across multiple Terraform modules. If this goes forward, please avoid repeating the moderately annoying fandango with inconsistent nameing – e.g., the |
It would also be useful to specify another module as a type. So that a sub field of your config could be held to that modules interface, rather than having to redefine it. e.g. module/infra.tf
module/consumer.tf
This way you could have nested relationships / dependencies; but, wouldn't have to redefine the interface to ensure the correct variables were passed. |
I like the idea of some of the more complex suggestions, but honestly even just this would be nice. Often times simple resource modules are used in more complex module compositions and being able to pass complex variable types forward would make life so much easier. I think a great example of this is found in the AWS EKS module. As it currently stands the Example of what it could look like:
Additionally, what would also be nice is something like a data source that could be used to lookup and reference a non-local modules variable type. Something like this:
Building on this idea, perhaps we could even reference the type of a single module variable too:
|
One workaround I've found for this: variables.tf
typed_variables.tf
./modules/type-config/variables.tf
./modules/type-config/outputs.tf
Now you can use |
Nice! I still miss a shared type for variables instead of workarounds. Maybe someday. Another (ugly) workaround is using symlinks for variable definitions files: Pros:
Cons:
Example: In variable "env" {
description = "Environment Variables"
type = object({
name = string
project = string
region = string
zone = string
tags = map(string)
}) In env = {
name = "dev"
project = "POC-project-123456"
region = "us-east4"
zone = "us-east4-a"
tags = {
"costs": "owned",
"env": "dev",
}
} In
In terraform {
required_version = ">= 1.3.3, < 1.5.0"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.61.0, < 5.0.0"
}
}
}
provider "google" {
project = var.env.project
region = var.env.region
zone = var.env.zone
}
terraform {
backend "gcs" {
prefix = "tf/module1"
}
} In $ ls -s ../../shared/vars/env.tf env.tf
$ ls -s ../../shared/config config After this, one can run terraform as usual. In $ terraform init -backend-config=./config/tfstate-dev.tfbackend
$ terraform plan -var-file=./config/vars-env-aws-dev.tfvars TLDR: A lot of effort to share some types. |
Are there any official solutions about this issue nowadays. |
Coming here to wish for this. |
Custom data types is one of the most powerful features in Haskell, and it opens a lot of doors (pattern matching on sum types, for example). I would love to see a similar capability in Terraform! It would also improve our R&D feedback cycle, where |
Instead of something like this:
module-inputs.tf
infra-inputs.tf
which, here and especially for multiple top-level modules, involves a ridiculous amount of boilerplate, we'd like to see something along the lines of:
types.tf
and then
module-inputs.tf
infra-inputs.tf
The text was updated successfully, but these errors were encountered: