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
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.