From e70449124f61598f2df4efe2639e19b3f47cd194 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:35:25 +0200 Subject: [PATCH] build(bake): add expressions and functions descriptions Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- content/build/bake/advanced.md | 348 ------------------------------ content/build/bake/expressions.md | 144 +++++++++++++ content/build/bake/funcs.md | 152 +++++++++++++ data/toc.yaml | 6 +- 4 files changed, 300 insertions(+), 350 deletions(-) delete mode 100644 content/build/bake/advanced.md create mode 100644 content/build/bake/expressions.md create mode 100644 content/build/bake/funcs.md diff --git a/content/build/bake/advanced.md b/content/build/bake/advanced.md deleted file mode 100644 index 09ba09befc..0000000000 --- a/content/build/bake/advanced.md +++ /dev/null @@ -1,348 +0,0 @@ ---- -title: Advanced Bake patterns and functions -description: Learn about advanced Bake features, like user-defined functions -keywords: build, buildx, bake, buildkit, hcl -aliases: - - /build/customize/bake/hcl-funcs/ - - /build/bake/hcl-funcs/ ---- - -HCL functions are great for when you need to manipulate values in more complex ways than just concatenating or appending values. - -The following sections contain some examples on custom functions and other -advanced use cases: - -- [Interpolate environment variables](#interpolate-environment-variables) -- [Built-in functions](#built-in-functions) -- [User-defined functions](#user-defined-functions) -- [Ternary operators](#ternary-operators) -- [Variables in functions](#variables-in-functions) -- [Typed variables](#typed-variables) - -## Interpolate environment variables - -As shown in the [Bake file reference](reference.md#variable) page, Bake -supports variable blocks which are assigned to matching environment variables -or default values. - -The following example shows how you can interpolate a `TAG` environment -variable to populate a variable in the Bake configuration. - -{{< tabs >}} -{{< tab name="HCL" >}} - -```hcl -# docker-bake.hcl -variable "TAG" { - default = "latest" -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - tags = ["docker.io/username/webapp:${TAG}"] -} -``` - -{{< /tab >}} -{{< tab name="JSON" >}} - -```json -{ - "variable": { - "TAG": { - "default": "latest" - } - }, - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "tags": ["docker.io/username/webapp:${TAG}"] - } - } -} -``` - -{{< /tab >}} -{{< /tabs >}} - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["docker.io/username/webapp:latest"] - } - } -} -``` - -```console -$ TAG=$(git rev-parse --short HEAD) docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["docker.io/username/webapp:985e9e9"] - } - } -} -``` - -## Built-in functions - -You can use [`go-cty` standard library functions](https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib). -The following example shows the `add` function. - -```hcl -# docker-bake.hcl -variable "TAG" { - default = "latest" -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - args = { - buildno = "${add(123, 1)}" - } -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "buildno": "124" - } - } - } -} -``` - -## User-defined functions - -You can create [user-defined functions](https://github.com/hashicorp/hcl/tree/main/ext/userfunc) -that do just what you want, if the built-in standard library functions don't -meet your needs. - -The following example defines an `increment` function. - -```hcl -# docker-bake.hcl -function "increment" { - params = [number] - result = number + 1 -} - -group "default" { - targets = ["webapp"] -} - -target "webapp" { - args = { - buildno = "${increment(123)}" - } -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "buildno": "124" - } - } - } -} -``` - -## Ternary operators - -You can use ternary operators to conditionally register a value. - -The following example adds a tag only when a variable is not empty, using the -`notequal` function. - -```hcl -# docker-bake.hcl -variable "TAG" {default="" } - -group "default" { - targets = [ - "webapp", - ] -} - -target "webapp" { - context="." - dockerfile="Dockerfile" - tags = [ - "my-image:latest", - notequal("",TAG) ? "my-image:${TAG}": "", - ] -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["my-image:latest"] - } - } -} -``` - -## Variables in functions - -You can make references to variables and standard library functions inside your -functions. - -You can't reference user-defined functions from other functions. - -```hcl -# docker-bake.hcl -variable "REPO" { - default = "user/repo" -} - -function "tag" { - params = [tag] - result = ["${REPO}:${tag}"] -} - -target "webapp" { - tags = tag("v1") -} -``` - -```console -$ docker buildx bake --print webapp -``` - -```json -{ - "group": { - "default": { - "targets": ["webapp"] - } - }, - "target": { - "webapp": { - "context": ".", - "dockerfile": "Dockerfile", - "tags": ["user/repo:v1"] - } - } -} -``` - -## Typed variables - -Non-string variables are supported. Values passed as environment variables are -coerced into suitable types first. - -```hcl -# docker-bake.hcl -variable "FOO" { - default = 3 -} - -variable "IS_FOO" { - default = true -} - -target "app" { - args = { - v1 = FOO > 5 ? "higher" : "lower" - v2 = IS_FOO ? "yes" : "no" - } -} -``` - -```console -$ docker buildx bake --print app -``` - -```json -{ - "group": { - "default": { - "targets": ["app"] - } - }, - "target": { - "app": { - "context": ".", - "dockerfile": "Dockerfile", - "args": { - "v1": "lower", - "v2": "yes" - } - } - } -} -``` diff --git a/content/build/bake/expressions.md b/content/build/bake/expressions.md new file mode 100644 index 0000000000..b486d5b36a --- /dev/null +++ b/content/build/bake/expressions.md @@ -0,0 +1,144 @@ +--- +title: Expression evaluation in Bake +description: Learn about advanced Bake features, like user-defined functions +keywords: build, buildx, bake, buildkit, hcl, expressions, evaluation, math, arithmetic, conditionals +aliases: + - /build/bake/advanced/ +--- + +Bake files in the HCL format support expression evaluation, which lets you +perform arithmetic operations, conditionally set values, and more. + +## Arithmetic operations + +You can perform arithmetic operations in expressions. The following example +shows how to multiply two numbers. + +```hcl {title=docker-bake.hcl} +sum = 7*6 + +target "default" { + args = { + answer = sum + } +} +``` + +Printing the Bake file with the `--print` flag shows the evaluated value for +the `answer` build argument. + +```console +$ docker buildx bake --print app +``` + +```json +{ + "target": { + "default": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "answer": "42" + } + } + } +} +``` + +## Ternary operators + +You can use ternary operators to conditionally register a value. + +The following example adds a tag only when a variable is not empty, using the +built-in `notequal` [function](./funcs.md). + +```hcl {title=docker-bake.hcl} +variable "TAG" {} + +target "default" { + context="." + dockerfile="Dockerfile" + tags = [ + "my-image:latest", + notequal("",TAG) ? "my-image:${TAG}": "", + ] +} +``` + +In this case, `TAG` is an empty string, so the resulting build configuration +only contains the hard-coded `my-image:latest` tag. + +```console +$ docker buildx bake --print +``` + +```json +{ + "group": { + "default": { + "targets": ["default"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["my-image:latest"] + } + } +} +``` + +## Expressions with variables + +You can use expressions with [variables](./variables.md) to conditionally set +values, or to perform arithmetic operations. + +The following example uses expressions to set values based on the value of +variables. The `v1` build argument is set to "higher" if the variable `FOO` is +greater than 5, otherwise it is set to "lower". The `v2` build argument is set +to "yes" if the `IS_FOO` variable is true, otherwise it is set to "no". + +```hcl {title=docker-bake.hcl} +variable "FOO" { + default = 3 +} + +variable "IS_FOO" { + default = true +} + +target "app" { + args = { + v1 = FOO > 5 ? "higher" : "lower" + v2 = IS_FOO ? "yes" : "no" + } +} +``` + +Printing the Bake file with the `--print` flag shows the evaluated values for +the `v1` and `v2` build arguments. + +```console +$ docker buildx bake --print app +``` + +```json +{ + "group": { + "default": { + "targets": ["app"] + } + }, + "target": { + "app": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "v1": "lower", + "v2": "yes" + } + } + } +} +``` diff --git a/content/build/bake/funcs.md b/content/build/bake/funcs.md new file mode 100644 index 0000000000..737db98671 --- /dev/null +++ b/content/build/bake/funcs.md @@ -0,0 +1,152 @@ +--- +title: HCL functions +description: Learn about built-in and user-defined HCL functions with Bake +keywords: build, buildx, bake, buildkit, hcl, functions, user-defined, built-in, custom, gocty +aliases: + - /build/customize/bake/hcl-funcs/ + - /build/bake/hcl-funcs/ +--- + +HCL functions are great for when you need to manipulate values in your build +configuration in more complex ways than just concatenation or interpolation. + +## Standard library + +Bake ships with built-in support for the [`go-cty` standard library functions](https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib). +The following example shows the `add` function. + +```hcl {title=docker-bake.hcl} +variable "TAG" { + default = "latest" +} + +group "default" { + targets = ["webapp"] +} + +target "webapp" { + args = { + buildno = "${add(123, 1)}" + } +} +``` + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "buildno": "124" + } + } + } +} +``` + +## User-defined functions + +You can create [user-defined functions](https://github.com/hashicorp/hcl/tree/main/ext/userfunc) +that do just what you want, if the built-in standard library functions don't +meet your needs. + +The following example defines an `increment` function. + +```hcl {title=docker-bake.hcl} +function "increment" { + params = [number] + result = number + 1 +} + +group "default" { + targets = ["webapp"] +} + +target "webapp" { + args = { + buildno = "${increment(123)}" + } +} +``` + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "args": { + "buildno": "124" + } + } + } +} +``` + +## Variables in functions + +You can make references to [variables](./variables) and standard library +functions inside your functions. + +You can't reference user-defined functions from other functions. + +The following example uses a global variable (`REPO`) in a custom function. + +```hcl {title=docker-bake.hcl} +# docker-bake.hcl +variable "REPO" { + default = "user/repo" +} + +function "tag" { + params = [tag] + result = ["${REPO}:${tag}"] +} + +target "webapp" { + tags = tag("v1") +} +``` + +Printing the Bake file with the `--print` flag shows that the `tag` function +uses the value of `REPO` to set the prefix of the tag. + +```console +$ docker buildx bake --print webapp +``` + +```json +{ + "group": { + "default": { + "targets": ["webapp"] + } + }, + "target": { + "webapp": { + "context": ".", + "dockerfile": "Dockerfile", + "tags": ["user/repo:v1"] + } + } +} +``` diff --git a/data/toc.yaml b/data/toc.yaml index becf110fef..f939fc051b 100644 --- a/data/toc.yaml +++ b/data/toc.yaml @@ -1959,12 +1959,14 @@ Manuals: title: Inheritance - path: /build/bake/variables/ title: Variables + - path: /build/bake/expressions/ + title: Expressions + - path: /build/bake/funcs/ + title: Functions - path: /build/bake/overrides/ title: Overriding configuration - path: /build/bake/reference/ title: Bake file reference - - path: /build/bake/advanced/ - title: Advanced patterns - path: /build/bake/build-contexts/ title: Build contexts and linking targets - path: /build/bake/compose-file/