Skip to content

Commit

Permalink
docs: add guide for variables and templating
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Sep 11, 2019
1 parent 502ae97 commit 545b469
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 202 deletions.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* [Remote Kubernetes](./using-garden/remote-kubernetes.md)
* [Remote Sources](./using-garden/using-remote-sources.md)
* [Terraform](./using-garden/terraform.md)
* [Variables and templating](./using-garden/variables-and-templating.md)
* [Example Projects](./examples/README.md)
* [Demo Project](./examples/demo-project.md)
* [TLS Project](./examples/tls-project.md)
Expand Down
4 changes: 3 additions & 1 deletion docs/reference/template-strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Note that there are three sections below, since Project configs and Module confi
them, and since additional keys are available under `providers` in Project configs.
Please make sure to refer to the correct section.

Modules can reference `outputs` defined by other modules, via the `${modules.<module-name>.outputs}` key.
Modules can reference `outputs` defined by other modules, via the `${modules.<module-name>.outputs}` key, as well
as service and task outputs via the `${runtime.services.<service-name>.outputs}` and
`${runtime.tasks.<task-name>.outputs}`.
For details on which outputs are available for a given module type, please refer to the
[reference](https://docs.garden.io/reference/module-types) docs for the module type in question, and look for the
_Outputs_ section.
Expand Down
205 changes: 5 additions & 200 deletions docs/using-garden/configuration-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,207 +399,12 @@ name: my-project
dotIgnoreFiles: [.gardenignore]
```

### Template strings

String configuration values in `garden.yml` can be templated to inject variables,
information about the user's environment, references to other modules/services etc.

The syntax for templated strings is `${some.key}`. The key is looked up from the context available when
resolving the string. The context depends on which top-level key the configuration value belongs to (`project`
or `module`).

For example, for one service you might want to reference something from another module and expose it as an
environment variable:

```yaml
kind: Module
name: some-module
services:
- name: some-service
...
env:
OTHER_MODULE_VERSION: ${modules.other-module.version}
```

You can also inject a template variable into a string. For instance, you might need to include a module's
version as part of a URI:

```yaml
...
env:
OTHER_MODULE_ENDPOINT: http://other-module/api/${modules.other-module.version}
```

Note that while this syntax looks similar to template strings in Javascript, currently, only simple lookups by key
and conditionals are supported, whereas arbitrary JS expressions are not.

Another common use case is to define `variables` in the project/environment configuration, and to use template strings
to propagate values to modules in the project:

```yaml
kind: Project
...
variables:
log-level: "info"
---
kind: Module
...
services:
- name: my-service
...
env:
LOG_LEVEL: ${var.log-level}
```

For a full reference of the keys available in template strings, please look at the
[Template Strings Reference](../reference/template-strings.md).

#### Runtime outputs

Template keys prefixed with `runtime.` have some special semantics. They are used to expose runtime outputs from services and tasks, and therefore are resolved later than other template strings. _This means that you cannot use them for some fields, such as most identifiers, because those need to be resolved before validating the configuration._

That caveat aside, they can be very handy when passing information between services and tasks. For example, you can pass log outputs from one task to another:

```yaml
kind: Module
type: exec
name: module-a
tasks:
- name: prep-task
command: [echo, "output from my preparation task"]
---
kind: Module
type: container
name: my-container
services:
- name: my-service
dependencies: [task-a]
env:
PREP_TASK_OUTPUT: ${runtime.tasks.prep-task.outputs.log}
```

Here the output from `prep-task` is copied to an environment variable for `my-service`. _Note that you currently need to explicitly declare `task-a` as a dependency for this to work._

For a practical use case, you might for example make a task that provisions some infrastructure or prepares some data, and then passes information about it to services.

Different module types expose different output keys for their services and tasks. Please refer to the [module type reference docs](https://docs.garden.io/reference/module-types) for details.

#### Operators

You can use a variety of operators in template string expressions:

* Arithmetic: `*`, `/`, `%`, `+`, `-`
* Numeric comparison: `>=`, `<=`, `>`, `<`
* Equality: `==`, `!=`
* Logical: `&&`, `||`, ternary (`<test> ? <value if true> : <value if false>`)
* Unary: `!` (negation), `typeof` (returns the type of the following value as a string, e.g. `"boolean"` or `"number"`)

The arithmetic and numeric comparison operators can only be used for numeric literals and keys that resolve to numbers. The equality and logical operators work with any term.

Clauses are evaluated in standard precedence order, but you can also use parentheses to control evaluation order (e.g. `${(1 + 2) * (3 + 4)}` evaluates to 21).

These operators can be very handy, and allow you to tailor your configuration depending on different environments and other contextual variables.

Here are some examples of usage:

The `||` operator allows you to set default values:

```yaml
# ...
variables:
log-level: ${local.env.LOG_LEVEL || "info"}
namespace: ${local.env.CI_BRANCH || local.username || "default"}
```

The `==` and `!=` operators allow you to set boolean flags based on other variables:

```yaml
kind: Module
...
skipDeploy: ${environment.name == 'prod'}
...
```

```yaml
kind: Module
...
allowPublish: ${environment.name != 'prod'}
...
```

Ternary expressions, combined with comparison operators, can be good when provisioning resources:

```yaml
kind: Module
type: container
...
services:
replicas: "${environment.name == 'prod' ? 3 : 1}"
...
```

And the arithmetic operators can also be handy when provisioning resources:

```yaml
kind: Module
type: container
...
services:
replicas: ${var.default-replicas * 2}
...
```

#### Numbers, booleans and null values

When a template string resolves to a number, boolean or null, its output is handled in one of two different ways,
depending on whether the template string is part of a surrounding string or not.

If the template string is the whole string being interpolated, we assign the number, boolean or null directly to the
key:

```yaml
kind: Project
...
variables:
default-replicas: 3
---
kind: Module
...
services:
- name: my-service
...
replicas: ${var.default-replicas} # <- resolves to a number, as opposed to the string "3"
```

If, however, the template string is not the whole string being interpolated, but a component of it, the value is
formatted into the string, as you would expect:

```yaml
kind: Project
...
variables:
project-id: 123
some-key: null
---
kind: Module
...
services:
- name: my-service
...
env:
CONTEXT: project-${project-id} # <- resolves to "project-123"
SOME_VAR: foo-${var.some-key} # <- resolves to "foo-null"
```

## Next steps

We highly recommend browsing through the [Example projects](../examples/README.md) to see different examples of how projects and modules can be configured.
We highly recommend reading the [Variables and Templating guide](./variables-and-templating.md) to understand how you can reference across different providers and modules, as well as to understand how to supply secret values to your configuration.

We suggest browsing through the [Example projects](../examples/README.md) as well, to see different examples of how projects and modules can be configured.

Also, be sure to look at the [Config Files Reference](../reference/config.md) for more details on each of the available
configuration fields, and the [Template Strings Reference](../reference/template-strings.md) for the keys available in
template strings.
Also, be sure to look at the [Config Files Reference](../reference/config.md) for more details on each of the available configuration fields, and the [Template Strings Reference](../reference/template-strings.md) for the keys available in template strings.

For deep-dives into specific use cases, you may want to look at the [Hot reload](./hot-reload.md) and
[Using Helm charts](./using-helm-charts.md) guides.
For deep-dives into specific use cases, you may want to look at the [Hot reload](./hot-reload.md) and [Using Helm charts](./using-helm-charts.md) guides.
Loading

0 comments on commit 545b469

Please sign in to comment.