For custom provider, schema validation, relationship between the keys

Writing my own custom provider,

I have my schema of the resource like a nested schema this :

Schema: map[string]*schema.Schema{
“zone” : {},
“type” : {},
“server” : {
Elem: Schema: map[string]*schema.Schema{
“name” : {},
“capacity”: {},
“mass_delete”: {},

I want to perform some high level validation on the server values, based on type key.
Like if type is default, name is not required, if type is user-defined name is mandatory, if type is custom, mass_delete is true

Is there any way to achieve this using ValidateFunc or RequiredWith/OneOf/RequiredWith parameters ?

Hi @ramuklawjju,

The declarative rules like OneOf can meet certain cases, but they are not fully general. The validation step is typically concerned with deciding if simple syntactic constraints are met, but it can be tricky to validate complicated relationship constraints at that step because Terraform hasn’t yet evaluated all of the external inputs to the resource configuration and so various parts of the configuration might not be known yet. If what you want to check is compatible with those declarative rules then I would suggest you use them for simplicity, because the SDK implementations of those already take into account the complexities of a configuration potentially being incomplete at the validation step.

However, if you have some more complicated rules to enforce, you can in principle do that using the CustomizeDiff field in your Resource object. If you set this to a function with the appropriate signature then you can use the schema.ResourceDiff object to interrogate the configuration during the plan step, where more (but still not all) configuration information is available. From an end user’s perspective this means that the rules you implement here would be reported by terraform plan but not by terraform validate.

For the sort of validation you’re talking about, you’d typically first use d.NewValueKnown to determine if all of the different arguments you are checking have “known” values (that is, they aren’t assigned from provider attributes that won’t be known until the apply step) and then if so you can use d.Get to retrieve the value of each of them in order to implement your validation rules.

If you return an error from CustomizeDiff then the SDK will return that to Terraform as a planning failure, which Terraform will then return to the user.

1 Like