We need to define some design principles for built-in resources so we can ensure that the resources that ship with DSC follow best practices and provide first-class ergonomics to users. The built-in resources serve both as examples for resource design and will be among the most-used resources.
During the review for the 3.2 GA, I noticed a few specific design principles we should call out. The following list is non-exhaustive:
- Only define the
_exist canonical property at the top-level for a resource instance JSON Schema and only when the resource can both create and delete instances. The resource must implement the canonical property in adherence to the contract. Don't define _exist for nested instances of a *List resource, since those instances can't participate in the engine semantics for existence.
- When a resource has the
_exist canonical property it should implement the get, set, export, and delete operations.
- Always implement what-if support for
set and delete operations.
- Always return all non-write-only properties for the actual state of a resource if those property values are knowable. If the values are not knowable for a given operation, omit those properties from the return data. In JSON Schema defining a property as
null and omitting the property are semantically distinct representations of data. Only populate a field with null when that actually matches the underlying resource behavior (when the resource has a nullable property, rather than an unset or undiscoverable property value).
- Always mark properties that can be passed to but not returned by the resource with the
writeOnly keyword.
- Always mark properties that can be returned by but not passed to the resource with the
readOnly keyword.
- Never add
null as a valid value for a property in the instance JSON Schema when null indicates that you aren't passing a value for the property. Only allow null for properties where null is a valid value for that property.
- When creating a
*List resource to manage multiple instances, also be sure to create a companion resource that manages a single instance. We should direct users towards the *List resource options only when the performance impact for single instances is too high. Those resources are much less ergonomic for result output and are somewhat obfuscated in the node graph. Using those resources necessitates tradeoffs in ergonomics for authoring vs reporting and performance vs clarity.
We need to define some design principles for built-in resources so we can ensure that the resources that ship with DSC follow best practices and provide first-class ergonomics to users. The built-in resources serve both as examples for resource design and will be among the most-used resources.
During the review for the 3.2 GA, I noticed a few specific design principles we should call out. The following list is non-exhaustive:
_existcanonical property at the top-level for a resource instance JSON Schema and only when the resource can both create and delete instances. The resource must implement the canonical property in adherence to the contract. Don't define_existfor nested instances of a*Listresource, since those instances can't participate in the engine semantics for existence._existcanonical property it should implement theget,set,export, anddeleteoperations.setanddeleteoperations.nulland omitting the property are semantically distinct representations of data. Only populate a field withnullwhen that actually matches the underlying resource behavior (when the resource has a nullable property, rather than an unset or undiscoverable property value).writeOnlykeyword.readOnlykeyword.nullas a valid value for a property in the instance JSON Schema whennullindicates that you aren't passing a value for the property. Only allownullfor properties wherenullis a valid value for that property.*Listresource to manage multiple instances, also be sure to create a companion resource that manages a single instance. We should direct users towards the*Listresource options only when the performance impact for single instances is too high. Those resources are much less ergonomic for result output and are somewhat obfuscated in the node graph. Using those resources necessitates tradeoffs in ergonomics for authoring vs reporting and performance vs clarity.