cuddle/README.md

132 lines
3.3 KiB
Markdown
Raw Permalink Normal View History

# cuddle
## What is Cuddle
Cuddle at its heart is a tool to extend your repository project from common
components to provide essential features, such as building the project,
deploying it, scaffolding code, or any other cross cutting feature that is
useful across your fleet of projects.
Cuddle exists to provide a golden path development for projects that are setup
from common templates, such as a rust-web-service, rust-cli, go-service etc.
Cuddle allows a small team of developers to develop curated development tools
targeted directly at what your developers needs to succeed.
## How
Cuddle by itself doesn't ship anything, it is a composition tool, but provides
some foundational components that a platform team can choose to compose to
achieve the result they want.
A common graph of dependencies will look like so:
- A golang service
- Depends on a github.com/kjuulh/cuddle-golang-service-plan
- Composes over
- docker build (Build pipelien)
- docker push (Push artifacts)
- kustomize (Compose actual manifest for deployment)
- kjuulh/release-manager (Deliver the manifest to deployment mechanism)
This means that no matter how many golang services we've got we only need a
single plan to service all of your users.
### Composition
Cuddle is a purely composition based tool, it means that it allows splitting
cross cutting needs into many small chunks which can then be included in your
service.
The way the services are usually created is that usually all the field are
templated, or setup with default configurations just to give a hint that those
features are available.
```nickel
let { Vars, .. } = import "github/kjuulh/cuddle" in
let { GoPlan, .. } = import "github/kjuulh/cuddle-go-service-plan" in
{
vars = {
name = "some-service",
owner = "kjuulh"
},
go_plan = {
version = "1.22",
database = true,
messagequeue = true,
cache = true,
external = true,
internal = true,
deployment = {
dev = {
cron = {
schedule = "* 0 * * *",
http = "/refresh-cache"
}
env = {
"openai.user" = "kjuulh" # Creates a env var with OPENAI_USER for the service
"openai.key" = { # Creates a env var with OPENAI_KEY managed by vault
from_vault = {
path = "/some/path/to/key"
}
}
}
}
}
}
} & Vars & GoPlan
```
A component has the same setup, but includes a different key to define what it
requires
```nickel
let { Vars, Component .. } = import "github/kjuulh/cuddle" in
{
vars = {
name = "docker build",
owner = "kjuulh"
},
component = {
actions = {
docker_build = {
type = rust
path = "actions/docker_build"
}
}
}
} & Vars & Component
```
A plan is usually a composition of other components.
```nickel
let { Vars, Component, .. } = import "github/kjuulh/cuddle" in
let { ServicePlan, .. } = import "github/kjuulh/cuddle/services" in
# in this case a service plan only really requires implementing a few actions
{
vars = {
name = "docker build",
owner = "kjuulh"
},
component = {
actions = {
ci = { # CI is now required to be implemented for the nickel spec to be parsed successfully
type = rust
path = "actions/ci"
}
}
}
} & Vars & Component & ServicePlan
```