# Goals and Rules of Deployer Pattern

Following lists the goals when the idea of having a `deployer` and `task` pattern came up. Most of the goals were learned from the incidents and difficulties we've seen in the development and maintenance of infra API.

1. De-couple the management of each resource. 
2. Reduce the fan-out of the IOs to the dependencies.
3. Group the similar functionalities in a single place.
4. Complexity grows horizontally. 
5. Seemless support for observability.
6. Painless troubleshooting.

To achieve the goals, we've cautiously followed the rules below:

1. Tasks do not depend on each other **explicitly**. Instead, they look up the shared context of the tasks and decide what actions to perform.
2. For the major resources (`network`/`cluster`), only write once to the API server.
3. A task only serves one functionality. Most of the time a task only manages a single resource.
4. Tasks are executed one by one without concurrency.
5. Input and outputs of a task are constrained and well-designed - it does not leak too many details into each task while providing enough information for logging and tracing. 
6. Expose the state of the deployment in the task context so it can be easily inspected in the logs or be checked in debugging.