|
| 1 | +# Declarative-friendly interfaces |
| 2 | + |
| 3 | +Many services need to interact with common DevOps tools, particularly those |
| 4 | +that create and manage network-addressible resources (such as virtual machines, |
| 5 | +load balancers, database instances, and so on). These tools revolve around the |
| 6 | +principle of "configuration as code": the user specifies the complete intended |
| 7 | +landscape, and tooling is responsible for making whatever changes are necessary |
| 8 | +to achieve the user's specification. |
| 9 | + |
| 10 | +These tools are **declarative**: rather than specifying specific _actions_ to |
| 11 | +take, they specify the desired _outcome_, with the actions being derived based |
| 12 | +on the differences between the current landscape and the intended one. |
| 13 | + |
| 14 | +Furthermore, there are numerous popular DevOps tools, with more being |
| 15 | +introduced each year. Integrating hundreds of resource types with multiple |
| 16 | +tools requires strong consistency, so that integration can be automated. |
| 17 | + |
| 18 | +## Guidance |
| 19 | + |
| 20 | +Services **should** clearly delineate between "control plane" operations and |
| 21 | +"data plane" operations, ideally through the use of distinct services with |
| 22 | +their own interface definition documents. |
| 23 | + |
| 24 | +- Control plane operations are responsible for managing the _lifecycle_ of |
| 25 | + resources. |
| 26 | +- Data plane operations are responsible for managing the _content_ of |
| 27 | + resources. |
| 28 | + |
| 29 | +The same resource **may** have both control plane operations and data plane |
| 30 | +operations associated with it. For example, a database API would have |
| 31 | +operations to create or delete database tables (control plane) as well as |
| 32 | +operations to write and read rows to that table (data plane). |
| 33 | + |
| 34 | +### Resources |
| 35 | + |
| 36 | +Resources that are declarative-friendly **must** use only strongly-consistent |
| 37 | +standard methods for managing resource lifecycle, which allows tools to support |
| 38 | +these resources generically, as well as conforming to other |
| 39 | +declarative-friendly guidance (see [further reading](#further-reading)). |
| 40 | + |
| 41 | +Declarative-friendly resources **should** designate that they follow the |
| 42 | +declarative-friendly style: |
| 43 | + |
| 44 | +{% tab proto %} |
| 45 | + |
| 46 | +{% sample 'declarative_friendly.proto', 'message Book' %} |
| 47 | + |
| 48 | +{% tab oas %} |
| 49 | + |
| 50 | +{% sample 'declarative_friendly.oas.yaml', 'schema' %} |
| 51 | + |
| 52 | +{% endtabs %} |
| 53 | + |
| 54 | +### Annotations |
| 55 | + |
| 56 | +Declarative-friendly resources **must** include a `annotations` field to allow |
| 57 | +clients to store small amounts of arbitrary data: |
| 58 | + |
| 59 | +```typescript |
| 60 | +// A representation of a single book. |
| 61 | +interface Book { |
| 62 | + // The name of the book. |
| 63 | + // Format: publishers/{publisher}/books/{book} |
| 64 | + name: string; |
| 65 | + |
| 66 | + // Other fields... |
| 67 | + |
| 68 | + // A dictionary of key-value pairs. |
| 69 | + // This has no effect on the service's behavior, but clients may use it |
| 70 | + // to persistently store small amounts of information related to this |
| 71 | + // resource. |
| 72 | + annotations: { [key: string]: string }; |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +The `annotations` field **must** use the [Kubernetes limits][] to maintain wire |
| 77 | +compatibility, and **should** require dot-namespaced annotation keys to prevent |
| 78 | +tools from trampling over one another. |
| 79 | + |
| 80 | +**Note:** Annotations are distinct from various forms of labels. Labels can be |
| 81 | +used by server-side policies, such as IAM conditions. Annotations exist to |
| 82 | +allow client tools to store their own state information without requiring a |
| 83 | +database. |
| 84 | + |
| 85 | +<!-- prettier-ignore --> |
| 86 | +[kubernetes limits]: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/#syntax-and-character-set |
| 87 | + |
| 88 | +### Reconciliation |
| 89 | + |
| 90 | +If a resource takes time (more than a few seconds) for updates to be realized, |
| 91 | +the resource **should** include a `bool reconciling` field to disclose that |
| 92 | +changes are in flight. This field **must** be output only. |
| 93 | + |
| 94 | +A resource **must** set the `reconciling` field to `true` if the current state |
| 95 | +of the resource does not match the user's intended state, and the system is |
| 96 | +working to reconcile them. This is regardless of whether the root cause of |
| 97 | +going into reconciliation was user or system action. |
| 98 | + |
| 99 | +**Note:** Services responding to a `GET` request **must** return the resource's |
| 100 | +current state (not the intended state). |
| 101 | + |
| 102 | +## Further reading |
| 103 | + |
| 104 | +A significant amount of guidance is more strict for declarative-friendly |
| 105 | +interfaces, due to the focus on automation on top of these resources. This list |
| 106 | +is a comprehensive reference to declarative-friendly guidance in other AIPs: |
| 107 | + |
| 108 | +- Resources **must** use user-settable resource IDs: see AIP-133. |
| 109 | +- Resources **must** permit "create or update": see AIP-134. |
| 110 | +- Resources **should** permit "delete if existing": see AIP-135. |
| 111 | +- Resources **should not** employ custom methods: see AIP-136. |
| 112 | +- Resources **must** use the `Update` method for repeated fields: see AIP-144. |
| 113 | +- Resources **must** include certain standard fields: see AIP-148. |
| 114 | +- Resources **must** have an `etag` field: see AIP-154. |
| 115 | +- Resources **must** provide change validation: see AIP-163. |
| 116 | +- Resources **should** support soft delete: see AIP-164. |
0 commit comments