Nullstone GitOps Best Practices
Nullstone GitOps was built to improve software development practices.
- Improve clarity and signal for developers
- Minimize environment disparity
- Reduce misconfiguration issues
This page details a set of practices that you should follow to improve your process and tooling. These guidelines are meant to help; it's OK to break them if there is thoughtful intention.
Define service infra in same repository as codebase
Many teams that are practicing GitOps host repositories with the sole intention of holding IaC. Since Nullstone GitOps is built with developer self-service in mind, your IaC files should colocate with your application code. This is done to keep everything necessary to run a service within a single repository.
It's important to note that this does not prevent infrastructure teams from maintaining separate infrastructure repositories.
Repository ownership
A block belongs to the first repository that syncs it, whether through a GitOps push or nullstone iac sync. A sync from a different repository that defines the same block name is rejected, so define each block in exactly one repository. Because ownership is checked against the syncing repository, nullstone iac sync needs to know which repository it is running for: it reads the origin remote of the current git clone, or you can pass --repo=<owner>/<name> when running from a checkout without git metadata.
Events defined under events in your IaC files are owned the same way, by the repository url that synced them.
If ownership goes stale (for example the owning repository was disconnected before a final sync could release its blocks, or a block moved between repositories out of order), a sync from the new repository fails with an ownership error that lists the blocks or events and the repository that owns them. A stack owner or architect can fix this without touching the database: the IaC ownership section on a block's settings page sets or clears the block's owning repository, and the same section on an event's edit page (Environment > Events > the event) does it for that event. Clearing a block's owner lets the next sync from any repository take it over. For events, set the url to the new repository instead of clearing it: a sync does not adopt an unowned event with the same name, so a cleared event stays UI-managed and a repository defining that name will fail on the duplicate.
Keep overrides files tiny
The .nullstone/config.yml file is intended to be the primary file that holds configuration within a repository. To keep environments in sync, it's best to use a single definition to describe all environments. There are pragmatic and good reasons to have differences in environments. (e.g. costs, time-to-launch, access controls, sanitized data) However, the differences should be specific and targeted rather than wholesale changes to an architecture.