Skip to content
Snippets Groups Projects
README.md 8.35 KiB
Newer Older
steeve.chailloux's avatar
steeve.chailloux committed

```
   ____
  | __ )  ___  __ ___   _____ _ __
  |  _ \ / _ \/ _` \ \ / / _ \ '__|
  | |_) |  __/ (_| |\ V /  __/ |
  |____/ \___|\__,_| \_/ \___|_|

```

## Description

steeve.chailloux's avatar
steeve.chailloux committed
`beaver` is a tool to build your k8s templates in a descriptive way.
steeve.chailloux's avatar
steeve.chailloux committed

## Features

- template engine:
	- [helm](https://helm.sh/)
	- [ytt](https://carvel.dev/ytt/)
	- [kubectl create](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#create)
    - [kustomize](https://kustomize.io)
steeve.chailloux's avatar
steeve.chailloux committed
- patch engine:
steeve.chailloux's avatar
steeve.chailloux committed
	- [ytt overlay](https://carvel.dev/ytt/docs/v0.39.0/ytt-overlays/)
- multi environment variables
- sha256 sum for any compiled resource can be used as variable
steeve.chailloux's avatar
steeve.chailloux committed
- inheritance between `beaver` project
steeve.chailloux's avatar
steeve.chailloux committed
- each built resource is output inside it's own file

## Usage

```
beaver build <path/to/beaver/project>
```

see `beaver build --help` for more options.

## Beaver project

steeve.chailloux's avatar
steeve.chailloux committed
A `beaver` project consists of a folder with a `beaver` config file,  either `beaver.yaml` or `beaver.yml`.
steeve.chailloux's avatar
steeve.chailloux committed

## Beaver config file

```yaml
# Default namespace used for this project
steeve.chailloux's avatar
steeve.chailloux committed
namespace: default
# an inherited beaver project - which can also inherit another beaver project
inherit: ../../base  # path is relative to this beaver config file
inherits:
- ../../base1
- ../../base2
steeve.chailloux's avatar
steeve.chailloux committed
# your project charts
charts:
  postgres:                           # your chart local name
steeve.chailloux's avatar
steeve.chailloux committed
    type: helm                        # can be either helm or ytt
steeve.chailloux's avatar
steeve.chailloux committed
    path: ../.vendor/helm/postgresql  # path to your chart - relative to this file
    name: pgsql                       # overwrite **helm** application name
    # Keyword `namespace` only available for Helm charts
    namespace: my-namespace           # Set namespace only for the current chart(Optional)
steeve.chailloux's avatar
steeve.chailloux committed
# beaver variables that can be used inside your charts value files
Steeven Herlant's avatar
Steeven Herlant committed
# They are two methods
# First method :
steeve.chailloux's avatar
steeve.chailloux committed
variables:
- name: tag      # give your variable a name
  value: v1.2.3  # and a value
Steeven Herlant's avatar
Steeven Herlant committed
# Second method :
variables:
  tag: v1.2.3
  my_dict1:
    my_key1: value1
    my_dict2:
      my_key2: value2
    my_list:
      - elem1
      - elem2
# You can also use inherit to overlay variables
# in project/base1/beaver.yaml :
variables:
  my_dict:
    key1: value1
    key2: value2
# If you want to redefine all dict
# in project/base2/beaver.yaml :
inherit: ../base1
variables:
  my_dict:
    newKey1: value3
# Or if you want to redifine part of dict
inherit: ../base1
variables:
  my_dict.key1: value3
# result of dict :
variables:
  my_dict:
    key1:value3
    key2: value1

steeve.chailloux's avatar
steeve.chailloux committed
# generate beaver variables from compiled resource file sha256
steeve.chailloux's avatar
steeve.chailloux committed
sha:
- key: configmap_demo               # use to generate beaver variable name
  resource: ConfigMap.v1.demo.yaml  # compiled resource filename
steeve.chailloux's avatar
steeve.chailloux committed
# create some resources using `kubectl create`
create:
- type: configmap       # resource kind as passed to kubectl create
  name: xbus-pipelines  # resource name
  args:                 # kubectl create arguments
  - flag: --from-file
    value: pipelines
steeve.chailloux's avatar
steeve.chailloux committed
```

## Value files

steeve.chailloux's avatar
steeve.chailloux committed
Value files filename use the following format:
steeve.chailloux's avatar
steeve.chailloux committed

```
<chart_local_name>.[yaml,yml]
```

steeve.chailloux's avatar
steeve.chailloux committed
you can provide a value file for your chart using its local name, and `beaver`
will pass this file to your template engine.
steeve.chailloux's avatar
steeve.chailloux committed

If you have a value file with the same name inside an inherited project then
steeve.chailloux's avatar
steeve.chailloux committed
`beaver` will also pass this one, but prior to your project file. This ensures
that your current values overwrite inherited values.
steeve.chailloux's avatar
steeve.chailloux committed

example:

```
# folder structure
.
├── base
│   ├── beaver.yml
│   └── postgres.yml
└── environments
    └── demo
        ├── beaver.yml
        └── postgres.yaml
```
```yaml
# base/beaver.yml
charts:
  postgres:
    type: postgres
    path: ../.vendor/postgresql
```
```yaml
# environments/demo/beaver.yml
inherit: ../../base
namespace: demo
```

steeve.chailloux's avatar
steeve.chailloux committed
In the example above `beaver` will automaticaly pass `base/postgres.yml` and then
`environments/demo/postgres.yaml` to helm using `.vendor/postgresql` as chart
folder.
steeve.chailloux's avatar
steeve.chailloux committed

## Beaver variables

`beaver` variables can be used inside your value files, using the following syntax:
steeve.chailloux's avatar
steeve.chailloux committed

```
<[variable_name]>
```

example:
```yaml
# base/beaver.yaml
variables:
- name: pg_tag
  value: 14.4-alpine
charts:
  postgres:
    type: postgres
    path: ../.vendor/postgresql
```
```yaml
# base/postgres.yml
image:
  tag: <[pg_tag]>
```

steeve.chailloux's avatar
steeve.chailloux committed
`beaver` variables are merged during inheritance, example:

```yaml
# base/beaver.yaml
variables:
- name: pg_tag
  value: 14.4-alpine
```

```yaml
# environments/demo/beaver.yaml
inherit: ../../base
variables:
- name: pg_tag
  value: 13.7-alpine
```

here `pg_tag` value will be `13.7-alpine` if you run
`beaver build environments/demo`.
### Beaver variables in the beaver namespace itself

You can set some variables in the 'namespace' keyword of a beaver file.

```yaml
# example/base/beaver.yml
namespace: <[myns]>
charts:
  demoytt:
    type: ytt
    path: demoytt.tmpl.yaml
```

in this case this means this base is not useable by itself but can now be adapted by the caller by setting a beaver
variable to fill the slot

```yaml
# example/ns1/beaver.yml
namespace: ns1
inherit: ../base
variables:
- name: myns
  value: ns1yo
```

This is a somewhat warped example but in this case the resulting ouput dir (namespace for beaver) will be example/build/ns1yo

### variables inside the charts.disabled flag

imagine a base with a chart that is disabled by default

```yaml
# example/base/beaver.yml
namespace: example
charts:
  demoytt:
    type: ytt
    path: demoytt.tmpl.yaml
    disabled: <[configmapDisabled]>
variables:
- name: configmapDisabled
  value: true
```

and another file that inherits from this base and want to have this chart enabled

```yaml
# example/configmapenabled/beaver.yml
namespace: ns1
inherit: ../base
variables:
- name: configmapDisabled
  value: false
```

This can be used to allow for options in some inheritance cases where you want to enable/disable a certain backend like
a Redis server, a Postgresql server.
Your base provides the diverse options and your inheritance will pick the ones they need.



steeve.chailloux's avatar
steeve.chailloux committed
## Output files

steeve.chailloux's avatar
steeve.chailloux committed
`beaver` output files have the following format:
Steeven Herlant's avatar
Steeven Herlant committed
- if the resource is namespaced :
```
<kind>.<apiVersion>.<metadata.namespace>.<metadata.name>.yaml
```
- if the resource is clusterwide :
steeve.chailloux's avatar
steeve.chailloux committed
```
<kind>.<apiVersion>.<metadata.name>.yaml
```

all `apiVersion` slashes (`/`) are replaced by underscores (`_`).

This convention will help you review merge requests.
steeve.chailloux's avatar
steeve.chailloux committed
By default `beaver` will store those files inside `${PWD}/build/<namespace>`, you
can use `-o` or `--output` to specify an output directory.
steeve.chailloux's avatar
steeve.chailloux committed

## sha256 sum variables

steeve.chailloux's avatar
steeve.chailloux committed
Use generated sha256 sum in your chart value files with the following syntax:
steeve.chailloux's avatar
steeve.chailloux committed

```
<[sha.key]>
```

For example:

```yaml
steeve.chailloux's avatar
steeve.chailloux committed
# base/beaver.yaml
steeve.chailloux's avatar
steeve.chailloux committed
sha:
- key: configmap_demo
  resource: ConfigMap.v1.demo.yaml
```
steeve.chailloux's avatar
steeve.chailloux committed
Will generate a sha256 hex sum for `ConfigMap.v1.demo.yaml` compiled file.

Then you can use it in your value file using:

```yaml
steeve.chailloux's avatar
steeve.chailloux committed
# base/postgres.yml
steeve.chailloux's avatar
steeve.chailloux committed
label:
  configmapSha: <[sha.configmap_demo]>
```

## Patch using YTT overlay

You can patch **all** your compiled resources using
[ytt overlays](https://carvel.dev/ytt/docs/v0.39.0/ytt-overlays/) by providing
steeve.chailloux's avatar
steeve.chailloux committed
`ytt.yaml` or `ytt.yml` files or a `ytt` folder inside your `beaver` project(s).

You can use `beaver` variables inside ytt files (outside ytt folder), because
steeve.chailloux's avatar
steeve.chailloux committed
`beaver` considers those as value files.

## Create resources using kubectl create

example:
steeve.chailloux's avatar
steeve.chailloux committed
```yaml
# base/beaver.yaml
# create some resources using `kubectl create`
create:
- type: configmap       # resource kind as passed to kubectl create
  name: xbus-pipelines  # resource name
  args:                 # kubectl create arguments
  - flag: --from-file
    value: pipelines
```

In the current context we have a `pipelines` folder inside `base` folder with
some files inside it.

`beaver` will run the following command **inside** `base` folder:

```sh
kubectl create configmap xbus-pipelines --from-file pipelines
```

## Kustomize

To use `kustomize` create a `kustomize` folder inside your beaver project and
use `kustomize` as usual.

A special beaver variable is available in your `kustomization.yaml` file:
`<[beaver.build]>` which exposes your beaver build temp directory, so you can
kustomize your previous builds (helm, ytt, etc.).

example:

```
# folder structure
.
└── base
    ├── beaver.yml
    └── kustomize
        └── kustomization.yaml
```

```yaml
resources:  # was previously named `bases`
- <[beaver.build]>
# now kustomize as usual.
patches:
- myPatch.yaml
```