- Home
- Documentation
- Customize Terraform
- Validation and Dependencies
Validation and Dependencies
Prevent Conflicting Attributes
Section titled “Prevent Conflicting Attributes”The x-speakeasy-conflicts-with extension indicates that a property conflicts with another, ensuring that certain combinations of properties are not set together. This is ideal for situations where certain attributes are mutually exclusive or setting one attribute invalidates another.
components: schemas: Pet: x-speakeasy-entity: Pet type: object properties: name: type: string name_prefix: type: string x-speakeasy-conflicts-with: name id: type: string generated_name_options: type: object properties: prefix: type: string x-speakeasy-conflicts-with: - ../name_prefix - ../name - ../idresource "example_pet" "happy_pet" { name = "Mrs Poppy" name_prefix = "Mrs"}$ terraform plan│ Error: Invalid Attribute Combination││ with example_pet.happy_pet,│ on provider.tf line 39, in resource "example_pet" "happy_pet":│ 3: name_prefix = "test"││ Attribute "name" cannot be specified when "name_prefix" is specifiedEnforce Mutually Exclusive Attributes (x-speakeasy-xor-with)
Section titled “Enforce Mutually Exclusive Attributes (x-speakeasy-xor-with)”The x-speakeasy-xor-with extension ensures that exactly one of the listed attributes must be configured at the same time. If multiple attributes are set simultaneously or if no attribute is set, Terraform plan validation fails. This differs from x-speakeasy-conflicts-with in that it requires exactly one attribute to be set, while conflicts-with allows zero or one attribute to be set.
components: schemas: Pet: x-speakeasy-entity: Pet type: object properties: this: type: string that: type: string another: type: string # user MUST configure exactly one of: this, that, or another x-speakeasy-xor-with: - ../this - ../thatresource "example_pet" "happy_pet" { this = "value1" that = "value2" # Error: exactly one field must be set}$ terraform plan│ Error: Invalid Attribute Combination││ with example_pet.happy_pet,│ on provider.tf line 2:│ 2: that = "value2"││ Exactly one of attributes [this, that, another] must be specifiedEnforce Required Attribute Dependencies (x-speakeasy-required-with)
Section titled “Enforce Required Attribute Dependencies (x-speakeasy-required-with)”The x-speakeasy-required-with extension ensures that when the annotated field is configured, all the specified dependent fields must also be configured. This is useful for enforcing that certain fields are always configured together.
components: schemas: Pet: x-speakeasy-entity: Pet type: object properties: name: type: string age: type: integer breed: type: string # when breed is set, name and age must also be set x-speakeasy-required-with: - ../name - ../ageresource "example_pet" "happy_pet" { breed = "Labrador" # Error: name and age must also be set when breed is set}$ terraform plan│ Error: Missing Required Attributes││ with example_pet.happy_pet,│ on provider.tf line 2:│ 2: breed = "Labrador"││ The following attributes must be configured when 'breed' is specified: [name, age]OpenAPI Plan Validators
Section titled “OpenAPI Plan Validators”Speakeasy automatically generates certain Terraform configuration value validation handlers based on your OpenAPI specification. When configuration validation is defined, Terraform raises invalid value errors before users can apply their configuration for a better user experience.
By default, these OpenAPI specification properties are automatically handled:
- For
stringtypes:enum,maxLength,minLength, andpattern - For
integertypes:enum,minimum, andmaximum - For
arraytypes:maxItems,minItems, anduniqueItems
For use cases not automatically handled, add custom validation logic or reach out to the team.
Add Custom Validation Logic
Section titled “Add Custom Validation Logic”Use the x-speakeasy-plan-validators extension to add custom validation logic to Terraform plan operations and ensure configurations meet predefined criteria before execution. This extension is essential for scenarios requiring advanced validation logic that JSON Schema cannot accommodate.
components: schemas: Pet: type: object x-speakeasy-entity: Pet properties: name: type: string age: type: integer x-speakeasy-plan-validators: AgeValidatorNote
Once you’ve added the x-speakeasy-plan-validators extension with a modifier, Speakeasy’s next Terraform provider generation will bootstrap a custom validator file. Using the previous YAML snippet as an example, the modifier will be located at internal/validators/int64validators/age_validator.go, and import the schema configuration wherever x-speakeasy-plan-validators: AgeValidator is referenced. You can modify the validator file to contain your logic.
Implementation Notes
Section titled “Implementation Notes”-
A plan validator is a type conformant to the
terraform-plugin-frameworkexpected interface. A unique plan validator will be bootstrapped in the appropriate subfolder for the Terraform type it is applied to:boolvalidators,float64validators,int64validators,listvalidators,mapvalidators,numbervalidators,objectvalidators,setvalidators, orstringvalidators. Speakeasy will always create and use a file assnake_case.gofor a givenx-speakeasy-plan-validatorsvalue. -
A plan validator operates on the raw (untyped) Terraform value types. However, you can convert a Terraform type to a value type Speakeasy manages (
type_mytype.go) by using the included reflection utility. This is useful for applying validators to complex types likelist,map,object, andset. -
While working with a plan validator, you have the ability to perform various tasks, including initiating network requests. However, it’s important to ensure that plan validations do not result in any unintended side effects. Please refer to the HashiCorp guidance on plan validator development or reach out in our Slack if you have questions.
-
It is possible to have an array of plan validators, for example,
x-speakeasy-plan-validators: [MinAgeValidator, MaxAgeValidator]. -
A validator can only be applied to a resource attribute. Validators cannot be applied at the same level as the
x-speakeasy-entityannotation because that becomes the “root” of the Terraform resource. However, validators can access or refer to any data in the entire resource (for an example, see thex-speakeasy-conflicts-withvalidator). The annotation will be ignored for data sources. -
Speakeasy regenerations do not delete user-written code. If the validator is no longer in use, it will be ignored (no longer referenced) but the source file will remain. You might want to delete such an orphaned validation file for repository hygiene.