Skip to content

Commit

Permalink
docs(jsonnet): add kustomize and update helm (grafana#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
Duologic authored Dec 11, 2020
1 parent c94b9b8 commit ec5e283
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 8 deletions.
14 changes: 8 additions & 6 deletions docs/docs/helm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ resource definition, you can still consume Helm resources, as described below.
## Consuming Helm Charts from Jsonnet

Helm support is provided using the
[`github.com/grafana/jsonnet-libs/helm-util`](https://github.com/grafana/jsonnet-libs/tree/master/helm-util)
[`github.com/grafana/jsonnet-libs/tanka-util`](https://github.com/grafana/jsonnet-libs/tree/master/tanka-util)
library. Install it with:
```bash
jb install github.com/grafana/jsonnet-libs/helm-util
jb install github.com/grafana/jsonnet-libs/tanka-util
```

The following example shows how to extract the individual resources of the
[`grafana`](https://hub.helm.sh/charts/grafana/grafana) Helm Chart:

```jsonnet
local helm = (import "github.com/grafana/jsonnet-libs/helm-util/helm.libsonnet").new(std.thisFile);
local tanka = import "github.com/grafana/jsonnet-libs/tanka-util/main.libsonnet";
local helm = tanka.helm.new(std.thisFile);
{
grafana: helm.template("grafana", "./charts/grafana", {
Expand Down Expand Up @@ -165,11 +166,12 @@ using [`TANKA_HELM_PATH`](/env-vars#tanka_helm_path)
### opts.calledFrom unset

This occurs, when Tanka was not told where it `helm.template()` was invoked
from. This most likely means you didn't call `new(std.thisFile)` when importing `helm-util`:
from. This most likely means you didn't call `new(std.thisFile)` when importing `tanka-util`:

```jsonnet
local helm = (import "github.com/grafana/jsonnet-libs/helm-util/helm.libsonnet").new(std.thisFile);
↑ This is important
local tanka = import "github.com/grafana/jsonnet-libs/tanka-util/main.libsonnet";
local helm = tanka.helm.new(std.thisFile);
↑ This is important
```

### Failed to find Chart
Expand Down
126 changes: 126 additions & 0 deletions docs/docs/kustomize.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
name: "Kustomize support"
route: "/kustomize"
menu: Advanced features
---

# Kustomize Support

[Kustomize](https://kustomize.io) provides a solution for customizing Kubernetes
manifests in YAML.

Even though Grafana Tanka uses the [Jsonnet language](/jsonnet/overview) for
resource definition, you can still consume kustomizations, as described below.

> **Warning:** Keep in mind this feature is considered EXPERIMENTAL
## Consuming a Kustomization from Jsonnet

Kustomize support is provided using the
[`github.com/grafana/jsonnet-libs/tanka-util`](https://github.com/grafana/jsonnet-libs/tree/master/tanka-util)
library. Install it with:

```bash
jb install github.com/grafana/jsonnet-libs/tanka-util
```

The following example shows how to extract the individual resources of the
[`flux2/source-controller`](https://github.com/fluxcd/flux2/tree/main/manifests/bases/source-controller)
kustomization:

```jsonnet
local tanka = import 'github.com/grafana/jsonnet-libs/tanka-util/main.libsonnet';
local kustomize = tanka.kustomize.new(std.thisFile);
{
source_controller: kustomize.build(path='flux2')
}
```

Kustomize takes a kustomization manifest as input. Go on an create this file
`flux2/kustomization.yaml` relative to above jsonnet:

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/flux2/archive/v0.4.3.zip//flux2-0.4.3/manifests/bases/source-controller
```
> **Important:** You MUST include the `.new(std.thisFile)` part in the import.
> This is what tells Tanka where you actually call `kustomize.build()` from, so
> it can find your kustomization manifest.

<br />

Once invoked, the `$.source_controller` key holds the individual resources of
the kustomization as a regular Jsonnet object that looks roughly like so:

```jsonnet
{
'custom_resource_definition_buckets.source.toolkit.fluxcd.io': {/* ... */ },
'custom_resource_definition_gitrepositories.source.toolkit.fluxcd.io': {/* ... */ },
'custom_resource_definition_helmcharts.source.toolkit.fluxcd.io': {/* ... */ },
'custom_resource_definition_helmrepositories.source.toolkit.fluxcd.io': {/* ... */ },
deployment_source_controller: {/* ... */ },
service_source_controller: {/* ... */ },
}
```

Above can be [manipulated](/tutorial/environments#patching) in the same way as
any other Jsonnet data.

## Working with Kustomize

Tanka, like Jsonnet, is hermetic. It **always yields the same resources** when
the project is strictly self-contained.

Kustomize however has the ability to pull
[resources](https://kubectl.docs.kubernetes.io/references/kustomize/resource/)
from different sources at runtime, which violates above requirement. This is
also apparent in the example above.

> **Important:** Due to the nature of Kustomize, it is not feasible to ensure
> hermetic and reproducible kustomize builds from within Tanka. Beware of that
> when using Kustomize.

## Troubleshooting

### Kustomize executable missing

Kustomize support in Tanka requires the `kustomize` binary installed on your
system and available on the `$PATH`. If Kustomize is not installed, you will see
this error message:

```
evaluating jsonnet: RUNTIME ERROR: Expanding Kustomize: exec: "kustomize": executable file not found in $PATH
```

To solve this, you need to
[install Kustomize](https://kubectl.docs.kubernetes.io/installation/kustomize/).
If you cannot install it system-wide, you can point Tanka at your executable
using [`TANKA_KUSTOMIZE_PATH`](/env-vars#tanka_kustomize_path)

### opts.calledFrom unset

This occurs, when Tanka was not told where it `kustomize.build()` was invoked
from. This most likely means you didn't call `new(std.thisFile)` when importing `tanka-util`:

```jsonnet
local tanka = import "github.com/grafana/jsonnet-libs/tanka-util/main.libsonnet";
local helm = tanka.helm.new(std.thisFile);
↑ This is important
```

### Failed to find kustomization

```
helmTemplate: Failed to find a kustomization at 'flux2': No such file or directory.
helmTemplate: Failed to find a kustomization at '/home/user/stuff/tanka/environments/default/flux2': No such file or directory.
```
Tanka failed to locate your kustomization on the filesystem. It looked at the
relative path you provided in `kustomize.build()`, starting from the directory
of the file you called `kustomize.build()` from.
Please check there is actually a valid kustomization at this place.
1 change: 1 addition & 0 deletions docs/doczrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export default {
menu: [
"Garbage collection",
"Helm support",
"Kustomize support",
"Output filtering",
"Exporting as YAML",
],
Expand Down
4 changes: 2 additions & 2 deletions pkg/kustomize/jsonnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NativeFunc(k Kustomize) *jsonnet.NativeFunction {
callerDir := filepath.Dir(opts.CalledFrom)
actual_path := filepath.Join(callerDir, path)
if _, err := os.Stat(actual_path); err != nil {
return nil, fmt.Errorf("kustomizeBuild: Failed to find kustomize at '%s': %s.", actual_path, err)
return nil, fmt.Errorf("kustomizeBuild: Failed to find kustomization at '%s': %s. See https://tanka.dev/kustomize#failed-to-find-kustomization", actual_path, err)
}

// render resources
Expand Down Expand Up @@ -79,7 +79,7 @@ func parseOpts(data interface{}) (*JsonnetOpts, error) {

// Kustomize paths are only allowed at relative paths. Use conf.CalledFrom to find the callers directory
if opts.CalledFrom == "" {
return nil, fmt.Errorf("kustomizeBuild: 'opts.calledFrom' is unset or empty.\nTanka needs this to find your Kustomize.\n")
return nil, fmt.Errorf("kustomizeBuild: 'opts.calledFrom' is unset or empty.\nTanka needs this to find your Kustomize. See https://tanka.dev/kustomize#optscalledfrom-unset\n")
}

return &opts, nil
Expand Down

0 comments on commit ec5e283

Please sign in to comment.