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