Proposal: helper/schema TypeEnum type #79
Labels
enhancement
New feature or request
subsystem/types
Issues and feature requests related to the type system of Terraform and our shims around it.
terraform-plugin-framework
Resolved in terraform-plugin-framework
This proposal is for a new type in
helper/schema
to represent an enum,schema.TypeEnum
, as well as highlighting two possible extensions/use cases for the type.To other provider contributors reading this; if you have use cases or ideas that you can add, feel free to add them below as comments.
It's a common pattern in the Google provider for us to want to consume an enum
value from a Terraform configuration. Using
google_bigtable_instance
'sstorage_type
field as an example, we specify it like this right now:A
schema.TypeEnum
would be represented as astring
; that means that it wouldnot be an object type, and could not have child elements like a
TypeList
orTypeSet
. It would have aValues
attribute which is a slice of strings.Terraform will automatically run
validation.StringInSlice
withignoreCase: false
on the value, and also run any additionalValidateFunc
that is set, ifany, displaying the set of errors if there are any.
Terraform will validate that the
Default
value is present inValues
whenperforming internal validation.
This means that we would have roughly the same behaviour, as well as validation
that our
Default
is correct. We could specifystorage_type
like:This functionality alone is what this issue is asking for; like this,
schema.TypeEnum
is a nice alias overschema.TypeString
that attaches somemore semantic significance. There are two ways we could extend it, though;
This extension would be a nice-to-have, and would provide a lot of benefit for
us. It's not necessary for
schema.TypeEnum
as a whole, but is something Iwould like to see as a provider developer.
Past Google Go clients have used
string
to represent enums in the API. NewerGoogle clients under the
cloud.google.com/go/
likebigtable
use constantsto represent enum values,
and we need to perform awkward mappings from string -> enum.
Instead of
Values
accepting a slice of strings, it would take in amap[string]interface{} of config-side keys to arbitrary values. The
responsibility of casting to the correct type would be on the client code. The
default value specified in schema would be the string key. If the enum is
represented as a string, like Google's older clients such as for
Compute
, youwould map from string to string.
For context for this example, Bigtable's enums are
bigtable.HDD
andbigtable.SSD
and have the typebigtable.StorageType
; that means we wouldthen write
storage_type
asIf a user specified
then we would get it in code in the correct type like:
This feature is just as much asking if it's possible as it is a nice-to-have; it
is completely unnecessary for the rest of the proposal, but it lets us handle a
gross edge case that comes up a few times in schema instead of code.
Having a constrained set of values would also let us perform validations based
on what the user has specified in their config file. As a specific example,
google_sql_database_instance
has a fielddatabase_version
that could be usedas an enum. It looks like this right now:
Even though we currently allow free-form input, and rely on the API for
validation, it has a constrained set of potential values. They are:
MYSQL_5_5
,MYSQL_5_6
,MYSQL_5_7
, andPOSTGRES_9_6
. So, it would look like:Because we know exhaustively the set of potential values and
schema.TypeEnum
cannot have children, we should be able to use
ConflictsWith
with specificenum values. This would give plan-time errors with invalid configurations.
For
google_sql_database_instance
, we support areplica_configuration
objectwhich represents the API-side
mysqlReplicaConfiguration
.This isn't valid when using a
POSTGRES_9_6
instance.We would specify it like so;
So if we specified this in our
google_sql_database_instance
body:We would receive an error at plan time like:
The text was updated successfully, but these errors were encountered: