# Variables en Bake


Puedes definir y utilizar variables en un archivo de Bake para establecer valores de atributos, interpolarlas dentro de otros valores y realizar operaciones aritméticas. Las variables se pueden definir con valores predeterminados y se pueden sobrescribir mediante variables de entorno.

## Usar variables como valores de atributos

Utiliza el bloque `variable` para definir una variable.

```hcl {title=docker-bake.hcl}
variable "TAG" {
  default = "docker.io/username/webapp:latest"
}
```

El siguiente ejemplo muestra cómo utilizar la variable `TAG` en un objetivo (target).

```hcl {title=docker-bake.hcl}
target "webapp" {
  context = "."
  dockerfile = "Dockerfile"
  tags = [ TAG ]
}
```

## Interpolar variables en valores

Bake admite la interpolación de cadenas de variables dentro de otros valores. Puedes usar la sintaxis `${}` para interpolar una variable. El siguiente ejemplo define una variable `TAG` con el valor `latest`.

```hcl {title=docker-bake.hcl}
variable "TAG" {
  default = "latest"
}
```

Para interpolar la variable `TAG` en el valor de un atributo, utiliza la sintaxis `${TAG}`.

```hcl {title=docker-bake.hcl}
group "default" {
  targets = [ "webapp" ]
}

variable "TAG" {
  default = "latest"
}

target "webapp" {
  context = "."
  dockerfile = "Dockerfile"
  tags = ["docker.io/username/webapp:${TAG}"]
}
```

Imprimir el archivo de Bake con la bandera `--print` muestra el valor interpolado en la configuración de compilación resuelta.

```console
$ docker buildx bake --print
```

```json
{
  "group": {
    "default": {
      "targets": ["webapp"]
    }
  },
  "target": {
    "webapp": {
      "context": ".",
      "dockerfile": "Dockerfile",
      "tags": ["docker.io/username/webapp:latest"]
    }
  }
}
```

## Validar variables

Para verificar que el valor de una variable se ajusta a un tipo esperado, rango de valores u otra condición, puedes definir reglas de validación personalizadas mediante el bloque `validation`.

En el siguiente ejemplo, la validación se utiliza para imponer una restricción numérica a un valor de variable; la variable `PORT` debe ser 1024 o superior.

```hcl {title=docker-bake.hcl}
# Define una variable `PORT` con un valor predeterminado y una regla de validación
variable "PORT" {
  default = 3000  # Valor predeterminado asignado a `PORT`

  # Bloque de validación para garantizar que `PORT` sea un número válido dentro del rango aceptable
  validation {
    condition = PORT >= 1024  # Garantiza que `PORT` sea al menos 1024
    error_message = "La variable 'PORT' debe ser 1024 o superior."  # Mensaje de error para valores no válidos
  }
}
```

Si la expresión `condition` se evalúa como `false`, el valor de la variable se considera no válido, por lo que la invocación de la compilación falla y se emite el mensaje `error_message`. Por ejemplo, si `PORT=443`, la condición se evalúa como `false` y se produce el error.

Los valores se convierten al tipo esperado antes de que se aplique la validación. Esto asegura que cualquier sobrescritura establecida mediante variables de entorno funcione según lo previsto.

### Validar múltiples condiciones

Para evaluar más de una condición, define múltiples bloques `validation` para la variable. Todas las condiciones deben cumplirse (`true`).

Aquí tienes un ejemplo:

```hcl {title=docker-bake.hcl}
# Define una variable `VAR` con múltiples reglas de validación
variable "VAR" {
  # Primer bloque de validación: Asegurar que la variable no esté vacía
  validation {
    condition = VAR != ""
    error_message = "La variable 'VAR' no debe estar vacía."
  }

  # Segundo bloque de validación: Asegurar que el valor contenga solo caracteres alfanuméricos
  validation {
    # VAR y la coincidencia de regex deben ser idénticos:
    condition = VAR == regex("[a-zA-Z0-9]+", VAR)
    error_message = "La variable 'VAR' solo puede contener letras y números."
  }
}
```

Este ejemplo impone que:

- La variable no debe estar vacía.
- La variable debe coincidir con un conjunto de caracteres específico.

Para entradas no válidas como `VAR="hello@world"`, la validación fallará.

### Validar dependencias de variables

Puedes hacer referencia a otras variables de Bake en tu expresión de condición, lo que permite validaciones que impongan dependencias entre variables. Esto garantiza que las variables dependientes se configuren correctamente antes de continuar.

Aquí tienes un ejemplo:

```hcl {title=docker-bake.hcl}
# Define una variable `FOO`
variable "FOO" {}

# Define una variable `BAR` con una regla de validación que hace referencia a `FOO`
variable "BAR" {
  # Bloque de validación para garantizar que `FOO` esté configurada si se utiliza `BAR`
  validation {
    condition = FOO != ""  # Comprueba si `FOO` no es una cadena vacía
    error_message = "La variable 'BAR' requiere que 'FOO' esté configurada."
  }
}
```

Esta configuración garantiza que la variable `BAR` solo se pueda utilizar si a `FOO` se le ha asignado un valor no vacío. Intentar compilar sin configurar `FOO` activará el error de validación.

## Escapar la interpolación de variables

Si deseas omitir la interpolación de variables al analizar la definición de Bake, utiliza el signo de dólar doble (`$${VARIABLE}`).

```hcl {title=docker-bake.hcl}
target "webapp" {
  dockerfile-inline = <<EOF
  FROM alpine
  ARG TARGETARCH
  RUN echo "Building for $${TARGETARCH/amd64/x64}"
  EOF
  platforms = ["linux/amd64", "linux/arm64"]
}
```

```console
$ docker buildx bake --progress=plain
...
#8 [linux/arm64 2/2] RUN echo "Building for arm64"
#8 0.036 Building for arm64
#8 DONE 0.0s

#9 [linux/amd64 2/2] RUN echo "Building for x64"
#9 0.046 Building for x64
#9 DONE 0.1s
...
```

## Usar variables dentro de variables a través de archivos

Cuando se especifican múltiples archivos, un archivo puede utilizar variables definidas en otro. En el siguiente ejemplo, el archivo `vars.hcl` define una variable `BASE_IMAGE` con un valor predeterminado de `docker.io/library/alpine`.

```hcl {title=vars.hcl}
variable "BASE_IMAGE" {
  default = "docker.io/library/alpine"
}
```

El siguiente archivo `docker-bake.hcl` define una variable `BASE_LATEST` que hace referencia a la variable `BASE_IMAGE`.

```hcl {title=docker-bake.hcl}
variable "BASE_LATEST" {
  default = "${BASE_IMAGE}:latest"
}

target "webapp" {
  contexts = {
    base = BASE_LATEST
  }
}
```

Al imprimir la configuración de compilación resuelta, utilizando la bandera `-f` para especificar los archivos `vars.hcl` y `docker-bake.hcl`, verás que la variable `BASE_LATEST` se resuelve como `docker.io/library/alpine:latest`.

```console
$ docker buildx bake -f vars.hcl -f docker-bake.hcl --print app
```

```json
{
  "target": {
    "webapp": {
      "context": ".",
      "contexts": {
        "base": "docker.io/library/alpine:latest"
      },
      "dockerfile": "Dockerfile"
    }
  }
}
```

## Recursos adicionales

Aquí tienes algunos recursos adicionales que muestran cómo puedes utilizar variables en Bake:

- Puedes sobrescribir los valores de las variables (`variable`) mediante variables de entorno. Consulta [Sobrescribir configuraciones](/build/bake/overrides/#variables-de-entorno) para obtener más información.
- Puedes hacer referencia y utilizar variables globales en las funciones. Consulta [Funciones HCL](/build/bake/funcs/#variables-en-funciones).
- Puedes utilizar valores de variables al evaluar expresiones. Consulta [Evaluación de expresiones](/build/bake/expressions/#expresiones-con-variables).

