-
Notifications
You must be signed in to change notification settings - Fork 115
Description
What problem are you facing?
While working on #4, we have realized that Terraform represents embedded blocks always with Sets/Lists of length of most 1 (if optional, length is 0 or 1, if required, it will be always of length 1). An example is the policy_settings block in azurerm_web_application_firewall_policy. In fact, this is an optional configuration block nested in azurerm_web_application_firewall_policy block. We would normally want to represents it with a CRD schema as follows:
type WebApplicationFirewallPolicyParameters struct {
// +kubebuilder:validation:Optional
PolicySettings *PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
...However, it looks like (probably due to HCL semantics), Terraform provider instead represents this as a list of length at most 1:
"policy_settings": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,Upjet CRD generation pipeline also does not allow directly embedding a pluginsdk.Resource directly under another pluginsdk.Resource as expected.
Thus, Terrajet currently generates the following instead of the above fragment:
type WebApplicationFirewallPolicyParameters struct {
// +kubebuilder:validation:Optional
PolicySettings []PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
...Since this is a generated API that reflects the underlying Terraform resource API, I believe this is okay. But we have some room for improvement for such nested blocks (structs) by asserting a max length of 1 with kubebuilder markers.
How could Terrajet help solve your problem?
We can use the Terraform resource schema to observe the pluginsdk.Schema.MaxItems to place the appropriate kubebuilder marker on the generated field. This will provide a better UX around the generated Crossplane provider API. The resulting generated code could be something like the following for the above field:
type WebApplicationFirewallPolicyParameters struct {
// +kubebuilder:validation:Optional
// +kubebuilder:validation:MaxItems=1
PolicySettings []PolicySettingsParameters `json:"policySettings,omitempty" tf:"policy_settings,omitempty"`
...