Grafana TankaFlexible, reusable and concise configuration for Kubernetes
Edit page
Writing Jsonnet
Advanced features
Configuration ReferenceDirectory structureEnvironmentsRoot and BaseLibrariesEnvironment variablesCommand-line completionDiff strategiesNamespaces
Frequently asked questionsKnown issues

Directory structure

Tanka uses the following directories and special files:

. # the project (<rootDir>)
├── environments # code defining clusters
│   └── default # <baseDir>
│       ├── main.jsonnet # starting point of the Jsonnet compilation
│       └── spec.json # environment's config
├── jsonnetfile.json # direct dependencies
├── jsonnetfile.lock.json # all dependencies with exact versions
├── lib # libraries for this project only
│   └── k.libsonnet # alias file for vendor/
└── vendor # external libraries installed using jb
    │   ├── grafana
    │   │   └── jsonnet-libs
    │   │       └── ksonnet-util # Grafana Labs' usability extensions to k.libsonnet
    │   │           └── kausal.libsonnet
    │   └── ksonnet
    │       └── ksonnet-lib
    │           └── ksonnet.beta.4 # kubernetes library
    │               ├── k8s.libsonnet
    │               └── k.libsonnet


Tanka organizes configuration in environments. For the rationale behind this, see the section in the tutorial.

An environment consists of at least two files:


This file configures environment properties such as cluster connection (spec.apiServer), default namespace (spec.namespace), etc.

For the full set of options, see the Golang source code.


Like other programming languages, Jsonnet needs an entrypoint into the evaluation, something to begin with. main.jsonnet is exactly this: The very first file being evaluated, importing or directly specifying everything required for this specific environment.

Root and Base

When talking about directories, Tanka uses the following terms:

TermDescriptionIdentifier file
rootDirThe root of your projectjsonnetfile.json or tkrc.yaml
baseDirThe directory of the current environmentmain.jsonnet

Regardless what subdirectory of the project you are in, Tanka will always be able to identify both directories, by searching for the identifier files in the parent directories.
Tanka needs these for correctly setting up the import paths.

This is similar to how git always works, by looking for the .git directory.


Tanka relies heavily on code-reuse, so libraries are a natural thing. Roughly spoken, they can be imported from two paths:

  • /lib: Project local libraries
  • /vendor External libraries

For more details consider the import paths.

jsonnetfile.json and the lock

jb records all external packages installed in a file called jsonnetfile.json. This file is the source of truth about what should be included in vendor/. However, it should only include what is really directly required, all recursive dependencies will be handled just fine.

jsonnetfile.lock.json is generated on every run of jsonnet-bundler, including a list of packages that must be included in vendor/, along with the exact version and a sha256 hash of the package contents.

Both files should be checked into source control: The jsonnetfile.json specifies what you need and the jsonnetfile.lock.json is important to make sure that subsequent jb install invocations always do the exact same thing.

Tip: The vendor/ directory can be safely added to .gitignore to keep your repository size down, as long as jsonnetfile.lock.json is checked in.