Metadata-Version: 2.4
Name: rougail.output_hcl
Version: 0.1.0
Summary: Rougail output hcl
Author-email: Emmanuel Garette <gnunux@gnunux.info>
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Natural Language :: English
Classifier: Natural Language :: French
License-File: LICENSE
Requires-Dist: rougail-base >= 1.2.0,<2
Requires-Dist: python-hcl2 >= 8.1.2,<9
Project-URL: Home, https://forge.cloud.silique.fr/stove/rougail-output-hcl

---
gitea: none
include_toc: true
---

# HCL

The HashiCorp Configuration Language (HCL) is a specialized configuration language developed by HashiCorp, primarily designed for use with its suite of tools, including Terraform, Vault, and Nomad.

Since Rougail is designed to centralize the variables from your various projects, it may be useful to export the variables and values defined in Rougail to an HCL file.

Please note that the goal here is not to manage all your HCL files, but to export the variables and values to them.

## Attributes

Attributes assigns a value to a particular name.

An attribute is therefore the name of a variable or a family to which a value is assigned.

### Primitive Types

Value has those primitive types: `string`, `integer`, `bool` or `null`

```hcl
a_string = "a value"
an_integer = 1
a_boolean = true
null_value = null
```

Nothing particular in Rougail:

```yaml
%YAML 1.2
---
version: 1.1

a_string: a value  # An attribute with a string

an_integer: 1  # An attribute with a integer

a_boolean: true  # A boolean attribute

null_value:
  description: A nullable value
  mandatory: false
...
```

### Complex Types

Value could be `list`, `set`, `tuple`, `map` or `object`.

#### `list`, `set` or `tuple`

The `set` type is an unordered `list` (the elements are all of the same type) with no duplicates. Rougail lists also do not allow duplicates by default (though this can be enabled), but their values are ordered.

The type `tuple` (where each element has its own type) is not allowed in Rougail, so hasn't equivalent for now.

Syntactically, there is no difference between a list, a set, and a tuple.

In Rougail, you must therefore declare a variable of a specific type and set the “multi” parameter to True.

```hcl
a_list = [
  "value 1",
  "value 2",
]
an_integer_list = [
  1,
  2,
]
```

```yaml
%YAML 1.2
---
version: 1.1

a_list: ["value 1", "value 2"]  # An attribute with a list of strings

an_integer_list: [1, 2]  # An attribute with a list of integer
...
```

#### `map` or `object`

The difference between `map` and `object` in HCL is analogous to that between `list` and `tuple`: the values in a `map` are all of the same type, whereas the values in an `object` can be of different. 

In Rougail, this corresponds to a family.

```hcl
a_map = {
  key_1 = "value 1"
  key_2 = "value 2"
  key_3 = "value 3"
}
an_object = {
  a_string   = "a value"
  an_integer = 1
  a_boolean  = true
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_map:  # A map is simply a collection of variables of the same type

  key_1: value 1  # A first attribute

  key_2: value 2  # A second attribute

  key_3: value 3  # A third attribute

an_object:  # A object is just a family

  a_string: a value  # An attribute with a string

  an_integer: 1  # An attribute with a integer

  a_boolean: true  # A boolean attribute
...
```

### Variable

```hcl
a_first_string: "a value"
a_second_string: a_first_string
```

A string, for now, must be enclosed in quotes. But a variable must not be enclosed in quotes.

You need to calculate the value directly in Rougail.

```yaml
%YAML 1.2
---
version: 1.1

a_first_string: "a value"  # Take a first value

a_second_string:
  description: An expressions is just a string
  default:
    variable: _.a_first_string
...
```

Or use basic expression (see after).

### Expressions

Expressions allow for dynamic configuration.

#### Basic

```hcl
a_first_string = "a value"
a_second_string = a_first_string
a_third_string = "combine ${a_first_string}"
```

A string, for now, must be enclosed in quotes. But a variable must not be enclosed in quotes (see below).

You have tu use basic expression in this case:

```yaml
%YAML 1.2
---
version: 1.1

a_first_string: "a value"  # Take a first value

a_second_string:
  description: A variable could also use expression to get value
  hcl_quoted_string: false
  default: a_first_string

a_third_string: combine ${a_first_string}  # An expressions is just a string
...
```

#### Conditional Expressions

```hcl
a_first_string = "a value"
a_second_string = a_first_string == "a value" ? 2 : 1
```

A string, for now, must be enclosed in quotes. But a conditional expression must not be enclosed in quotes.

You need to calculate the value directly in Rougail.

```yaml
%YAML 1.2
---
version: 1.1

a_first_string: "a value"  # Take a first value

a_second_string:
  description: An expressions is just a string
  hcl_quoted_string: false
  default: "a_first_string == \"a value\" ? 2 : 1"
...
```

#### Function

HCL includes a variety of built-in functions that you can use to manipulate data and perform calculations.

```hcl
content = file("config.json")
```

A string, for now, must be enclosed in quotes. But a conditional expression must not be enclosed in quotes.

## Block

A `block` is a container for configuration.

### A basic block

There is no equivalent to a `block` in Rougail. To define a `block`, you must define a family and add an `hcl_type` parameter set to `block`.

[!NOTE] The `hcl` structural module must be loaded for this type to be recognized.

```hcl
a_block {
  an_attribute = "a value"
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  an_attribute: a value  # An attribute in a block
...
```

### A block in a block

Blocks can have a tree-like structure, like family in Rougail.

```hcl
a_block {
  a_second_block {
    an_attribute = "a value"
  }
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_second_block:
    description: We can add a block inside a block
    hcl_type: block

    an_attribute: a value  # An attribute in a block
...
```

### A block with a label

Blocks have a block type and can have zero or more labels.

There is no equivalent to a `label` in Rougail. To define a `label`, you must define a family and add an `hcl_type` parameter set to `label`. A `label` must be defined within a `block`.

[!NOTE] The `hcl` structural module must be loaded for this type to be recognized.

```hcl
a_block "a_label" {
  an_attribute = "a value"
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_label:
    description: A label is also a family with hcl_type attribute
    hcl_type: label

    an_attribute: a value  # An attribute in a block
...
```

### A block with some labels

```hcl
a_block "a_first_label" "a_second_label" {
  an_attribute = "a value"
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_first_label:
    description: A label is also a family with hcl_type attribute
    hcl_type: label

    a_second_label:
      description: A label is also a family with hcl_type attribute
      hcl_type: label

      an_attribute: a value  # An attribute in a block
...
```

### Block inside a label block

A `block` could be in a `label` block.

```hcl
a_block "a_first_label" "a_second_label" {
  a_sub_block {
    a_string = "a value"
  }
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_first_label:
    description: A label is also a family with hcl_type attribute
    hcl_type: label

    a_second_label:
      description: A label is also a family with hcl_type attribute
      hcl_type: label

      a_sub_block:
        description: A block insible label block
        hcl_type: block

        a_string: a value  # An attribute in a block
...
```

### Block with a label inside a block

And a `label` block could be in a `block`.

```hcl
a_block {
  a_sub_block "a_first_label" "a_second_label" {
    a_string = "a value"
  }
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_sub_block:
    description: A label block insible block
    hcl_type: block

    a_first_label:
      description: A label is also a family with hcl_type attribute
      hcl_type: label
  
      a_second_label:
        description: A label is also a family with hcl_type attribute
        hcl_type: label
  
        a_string: a value  # An attribute in a block
...
```

### Duplicate block name

In Rougail, it's not possible to have two families with the same name.

```hcl
a_block {
  a_sub_block "a_label" {
    an_attribut = [
      "value 1",
      "value2",
    ]
  }
  

  a_sub_block "a_label" {
    an_attribut = [
      "value 3",
    ]
  }
}
```

```yaml
%YAML 1.2
---
version: 1.1

a_block:
  description: A block is a family with hcl_type attribute
  hcl_type: block

  a_sub_block_1:
    description: A label block insible block
    hcl_type: block
    hcl_name: a_sub_block

    a_label:
      description: Add a label
      hcl_type: label

      an_attribut:  # An attribute
        - value 1
        - value2

  a_sub_block_2:
    description: Add a label
    hcl_type: block
    hcl_name: a_sub_block

    a_label:
      hcl_type: label

      an_attribut:  # An attribute
        - value 3
...
```

### Variable block

The variable block define variables within your HCL configuration.

```hcl
variable "environment" {
  description = "The deployment environment"
  type        = string
}
```

```yaml
%YAML 1.2
---
version: 1.1

variable:
  description: Variable block
  hcl_type: block

  environment:
    description: The deployment environment
    hcl_type: label

    description: The deployment environment  # The environment description
  
    type:
      description: The type description
      hcl_quoted_string: false
      default: string
...
```

