Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/l-with/terraform-module-cloud_init


https://github.com/l-with/terraform-module-cloud_init

Last synced: 10 days ago
JSON representation

Awesome Lists containing this project

README

        

# Terraform Modul cloud_init

Terraform module to template cloud-init user data

## Disclaimer

currently only tested with Ubuntu Focal Fossa and Jammy Jellyfish

## Motivation

There is a terraform-provider [cloudinit](https://registry.terraform.io/providers/hashicorp/cloudinit), which can be used to render cloud-init data.

This module is not completely generic like [cloudinit](https://registry.terraform.io/providers/hashicorp/cloudinit). It supports the installation of features.
Some features are simple package installations or downloads of tools.
Other features have more functionality.

For instance

- [docker_container](#docker_container) can be used to configure services that start docker containers.
- [nginx](#nginx) can be used to configure nginx

If you use [docker_container](#docker_container) then [docker](#docker) is activated automatically.

There are more sophisticated features like `vault_init` in [vault](#vault) that automatically installs
the needed features for the logic in the `runcmd` section for `vault_init`.

## Technical aspects

The following cloud-init modules are used

- [Package Update Upgrade Install](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#package-update-upgrade-install)
- [Runcmd](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#runcmd)
- [Write Files](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#write-files)

The execution order in cloud-init for these modules is

- init stage
- write-files
- users-group
- config stage
- runcmd
- final stage
- package-update-upgrade-install

The consequence for the implementation in this module is that tools that are used for configuration are installed by the runcmd module even if there is a package for the tool.

## Features

### b2

s. [B2 Command Line Tool](https://github.com/Backblaze/B2_Command_Line_Tool/releases)

For input variables: s. [b2](#input_b2).

### certbot

s. [certbot](https://eff-certbot.readthedocs.io/en/stable/install.html#installation)

For input variables: s. [certbot](#input_certbot).

### comment

add comments to cloud-init user data

This can be used to change cloud-init user-data to trigger rebuild without changing relevant data.

For input variables: s. [comment](#input_comment).

### containerd

s. [containerd](https://github.com/containerd/containerd/blob/main/docs/getting-started.md)

For input variables: s. [containerd](#input_containerd).

### croc

s. [croc](https://github.com/schollz/croc#install)

For input variables: s. [croc](#input_croc).

### digitalocean

s. [digitalocean](https://www.digitalocean.com)

For input variables: s. [digitalocean](#input_digitalocean).

### docker

s. [docker](https://docs.docker.com/engine/install/ubuntu/)

For input variables: s. [docker](#input_docker).

### docker_container

s. [docker](https://docs.docker.com/engine/reference/run/)

For input variables: s. [docker_container](#input_docker_container).

### duplicacy

s. [duplicacy](https://github.com/gilbertchen/duplicacy)

For input variables: s. [duplicacy](#input_duplicacy).

### encrypted packages

For input variables: s. [encrypted_packages](#input_encrypted_packages).

### fail2ban

s. [fail2ban](https://www.fail2ban.org/wiki/index.php/Downloads)

For input variables: s. [fail2ban](#input_fail2ban).

### gettext_base

s. [gettext-base](https://packages.ubuntu.com/search?suite=default&section=all&arch=any&keywords=gettext-base&searchon=names)

For input variables: s. [gettext_base](#input_gettext_base).

### haproxy

s. [haproxy](http://docs.haproxy.org)

For input variables: s. [haproxy](#input_haproxy).

### jq

s. [jq](https://stedolan.github.io/jq/)

For input variables: s. [jq](#input_jq).

### golang

s. [golang](https://go.dev)

For input variables: s. [golang](#input_golang).

### gpg

s. [gpg](https://www.gnupg.org)

For input variables: s. [gpg](#input_gpg).

### hetzner

s. [hetzner](https://www.hetzner.com)

For input variables: s. [hetzner](#input_hetzner).

### mailcow

s. [mailcow](https://docs.mailcow.email)

For input variables: s. [mailcow](#input_mailcow).

### lineinfile

s. [lineinfile](https://github.com/l-with/lineinfile)

For input variables: s. [lineinfile](#input_lineinfile).

### netcat

s. [netcat](https://sectools.org/tool/netcat/)

For input variables: s. [netcat](#input_netcat).

### network

for network configurations

This is executed first in the cloud-init runcmd module.

For input variables: s. [network](#input_network).

### nginx

s. [nginx](https://nginx.org)

For input variables: s. [nginx](#input_nginx).

### package

s. [package](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#package-update-upgrade-install)

For input variables: s. [package](#input_package).

### rke2

s. [rke2](https://docs.rke2.io/install/ha)

Two different cloud-init userdata can be generated
- for the 1st node
- for the other nodes

The certificates for RKE2 are fetched from a package registry
and decrypted with openssl and thus have to pre pre-built.
The package also has to contain templates for `/etc/rancher/rke2/config.yaml`:

- `/root/config.yaml.node_1st.envtpl` for the first node
- `/root/config.yaml.node_other.envtpl` for the other nodes

The Cloud-init for the 1st node waits for all nodes to become ready
and then puts the created `rke2.yaml` modified
(substitute 127.0.0.1 with the ipv4-address of the 1st node) into Hashicorp Vault.

The [cert-manager](https://github.com/cert-manager/cert-manager) `cert-manager.crds.yaml`
is pre-installed as manifest in the 1st node.

For input variables: s. [rke2](#input_rke2).

### runcmd

generic gereration of runcmd scripts

For input variables: s. [runcmd](#input_runcmd).

### s3cmd

s. [S3cmd](https://github.com/s3tools/s3cmd)

For input variables: s. [s3cmd](#input_s3cmd).

### terraform

s. [terraform](https://developer.hashicorp.com/terraform/downloads)

For input variables: s. [terraform](#input_terraform)

### tool

generic installing of tools

For input variables: s. [tool](#tool).

### unzip

s. [unzip](#unzip)

For input variables: s. [unzip](#unzip).

### users

s. [users](https://cloudinit.readthedocs.io/en/latest/reference/modules.html#users-and-groups)

For input variables: s. [users](#users).

### vault

s. [vault](https://developer.hashicorp.com/vault/downloads)

For input variables: s. [vault](#input_vault).

### wait_until

s. [wait_until](https://github.com/l-with/wait-until)

For input variables: s. [wait_until](#wait_until).

### write_file

generic writing of files

For input variables: s. [write_file](#write_file).

### zypper

s. [zypper](https://en.opensuse.org/Portal:Zypper)

For input variables: s. [zypper](#zypper).

## terraform

#### Requirements

| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.3 |
| [external](#requirement\_external) | ~> 2.3.1 |

#### Providers

No providers.

#### Modules

| Name | Source | Version |
|------|--------|---------|
| [cloud\_init\_part](#module\_cloud\_init\_part) | ./modules/cloud_init_part | n/a |
| [containerd\_install\_method\_binary\_needs\_containerd\_version](#module\_containerd\_install\_method\_binary\_needs\_containerd\_version) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [docker\_install\_method\_binary\_needs\_docker\_version](#module\_docker\_install\_method\_binary\_needs\_docker\_version) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [duplicacy\_script](#module\_duplicacy\_script) | ./modules/duplicacy_script | n/a |
| [duplicacy\_storage\_backend\_one\_of](#module\_duplicacy\_storage\_backend\_one\_of) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [either\_rke2\_node\_1st\_or\_rke2\_node\_other](#module\_either\_rke2\_node\_1st\_or\_rke2\_node\_other) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [gzip\_needs\_base64\_encode](#module\_gzip\_needs\_base64\_encode) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [mailcow\_needs\_mailcow\_hostname](#module\_mailcow\_needs\_mailcow\_hostname) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [not\_mailcow\_dovecot\_master\_auto\_generated\_needs\_mailcow\_dovecot\_master\_user\_and\_mailcow\_dovecot\_master\_password](#module\_not\_mailcow\_dovecot\_master\_auto\_generated\_needs\_mailcow\_dovecot\_master\_user\_and\_mailcow\_dovecot\_master\_password) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_1st\_needs\_rke2\_node\_1st\_rke2\_role\_id](#module\_rke2\_node\_1st\_needs\_rke2\_node\_1st\_rke2\_role\_id) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_1st\_needs\_rke2\_node\_1st\_rke2\_secret\_id](#module\_rke2\_node\_1st\_needs\_rke2\_node\_1st\_rke2\_secret\_id) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_1st\_needs\_vault\_addr](#module\_rke2\_node\_1st\_needs\_vault\_addr) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_needs\_encrypted\_package\_api\_header](#module\_rke2\_node\_needs\_encrypted\_package\_api\_header) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_needs\_rke2\_node\_cert\_package\_url](#module\_rke2\_node\_needs\_rke2\_node\_cert\_package\_url) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_needs\_rke2\_node\_pre\_shared\_secret](#module\_rke2\_node\_needs\_rke2\_node\_pre\_shared\_secret) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_needs\_rke2\_node\_rke2\_node\_cert\_package\_secret](#module\_rke2\_node\_needs\_rke2\_node\_rke2\_node\_cert\_package\_secret) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [rke2\_node\_other\_needs\_rke2\_node\_other\_node\_1st\_ip](#module\_rke2\_node\_other\_needs\_rke2\_node\_other\_node\_1st\_ip) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [terraform\_install\_method\_binary\_needs\_terraform\_version](#module\_terraform\_install\_method\_binary\_needs\_terraform\_version) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_init\_needs\_jq\_install\_method\_binary](#module\_vault\_init\_needs\_jq\_install\_method\_binary) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_init\_needs\_vault\_init\_addr](#module\_vault\_init\_needs\_vault\_init\_addr) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_init\_pgp\_public\_keys\_needs\_vault\_vault\_init\_pgp\_public\_keys\_num\_internal\_unseal\_keys\_plus\_length\_of\_pgp\_external\_public\_keys\_equals\_vault\_key\_shares](#module\_vault\_init\_pgp\_public\_keys\_needs\_vault\_vault\_init\_pgp\_public\_keys\_num\_internal\_unseal\_keys\_plus\_length\_of\_pgp\_external\_public\_keys\_equals\_vault\_key\_shares) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_init\_vault\_key\_threshold\_less\_than\_or\_equal\_vault\_key\_shares](#module\_vault\_init\_vault\_key\_threshold\_less\_than\_or\_equal\_vault\_key\_shares) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_install\_method\_binary\_needs\_vault\_version](#module\_vault\_install\_method\_binary\_needs\_vault\_version) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_secure\_init\_json\_needs\_vault\_init\_public\_key](#module\_vault\_secure\_init\_json\_needs\_vault\_init\_public\_key) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_spread\_vault\_init\_json\_needs\_vault\_spread\_vault\_init\_json\_id\_file](#module\_vault\_spread\_vault\_init\_json\_needs\_vault\_spread\_vault\_init\_json\_id\_file) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_start\_needs\_vault\_api\_addr](#module\_vault\_start\_needs\_vault\_api\_addr) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_tls\_file\_encoding\_either\_text\_plain\_or\_base64](#module\_vault\_tls\_file\_encoding\_either\_text\_plain\_or\_base64) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [vault\_vault\_init\_pgp\_public\_keys\_num\_internal\_unseal\_keys\_less\_than\_or\_equal\_vault\_key\_shares](#module\_vault\_vault\_init\_pgp\_public\_keys\_num\_internal\_unseal\_keys\_less\_than\_or\_equal\_vault\_key\_shares) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |
| [write\_files\_encoding\_either\_text\_plain\_or\_base64](#module\_write\_files\_encoding\_either\_text\_plain\_or\_base64) | rhythmictech/errorcheck/terraform | ~> 1.3.0 |

#### Resources

No resources.

#### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [b2](#input\_b2) | if cloud-init user data for installing the [BlackBlaze CLI](https://www.backblaze.com/b2/docs/quick_command_line.html) should be generated | `bool` | `false` | no |
| [base64\_encode](#input\_base64\_encode) | if the cloud-init user data should be base64 encoded | `bool` | `false` | no |
| [certbot](#input\_certbot) | if cloud-init user data for installing certbot should be generated | `bool` | `false` | no |
| [certbot\_automatic\_renewal\_cron](#input\_certbot\_automatic\_renewal\_cron) | the cron schedule expression for certbot renewal | `string` | `"0 */12 * * *"` | no |
| [certbot\_automatic\_renewal\_cronjob](#input\_certbot\_automatic\_renewal\_cronjob) | the cron job for certbot renewal | `string` | `"test -x /usr/bin/certbot -a \\! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew"` | no |
| [certbot\_automatic\_renewal\_post\_hooks](#input\_certbot\_automatic\_renewal\_post\_hooks) | the certbot automatic renewal post hook scripts |

list(object({
file_name = string
content = string
}))
| `[]` | no |
| [certbot\_dns\_plugins](#input\_certbot\_dns\_plugins) | the list of certbot plugins to be installed | `list(string)` | `[]` | no |
| [comment](#input\_comment) | if cloud-init user data with comments should be generated | `bool` | `false` | no |
| [comments](#input\_comments) | the comments to be added to cloud-init user data
this can be used to change cloud-init user-data to trigger rebuild without changing relevant data | `list(string)` | `[]` | no |
| [containerd](#input\_containerd) | if cloud-init user data for installing containerd should be generated | `bool` | `false` | no |
| [containerd\_install\_method](#input\_containerd\_install\_method) | the install method, supported methods are 'binary'
- 'binary' uses containerd\_version | `string` | `"binary"` | no |
| [containerd\_version](#input\_containerd\_version) | the containerd version to be installed | `string` | `null` | no |
| [croc](#input\_croc) | if cloud-init user data for installing croc should be generated | `bool` | `false` | no |
| [digitalocean](#input\_digitalocean) | if cloud-init user data for making changes on a Digitalocean Droplet should be generated | `bool` | `false` | no |
| [digitalocean\_restart\_journald](#input\_digitalocean\_restart\_journald) | if the journald should be restarted (fixes missing logs) | `bool` | `true` | no |
| [docker](#input\_docker) | if cloud-init user data for installing docker should be generated | `bool` | `false` | no |
| [docker\_container](#input\_docker\_container) | if cloud-init user data for installing docker containers should be generated | `bool` | `false` | no |
| [docker\_container\_list](#input\_docker\_container\_list) | the docker containers the cloud-init user data should be generated for |
list(object({
name = string, // --name
image = string,
ports = optional(string, null), // --publish
command = string,
environment = optional(map(string), {}),
}))
| `[]` | no |
| [docker\_install\_method](#input\_docker\_install\_method) | the install method, supported methods are 'apt', 'binary'
- 'binary' uses docker\_version and activates containerd installation | `string` | `"apt"` | no |
| [docker\_manipulate\_iptables](#input\_docker\_manipulate\_iptables) | if docker manipulate ip-tables should _not_ be generated for cloud-init user data for docker | `bool` | `true` | no |
| [docker\_version](#input\_docker\_version) | the docker version to be installed | `string` | `null` | no |
| [duplicacy](#input\_duplicacy) | if cloud-init user data for installing duplicacy should be generated | `bool` | `false` | no |
| [duplicacy\_configurations](#input\_duplicacy\_configurations) | the duplicacy configurations |
list(object({
working_directory = string, // the working directory for duplicacy which is the default path for the repository to backup
password = string, // the value for `DUPLICACY_PASSWORD`, e.g. the passphrase to encrypt the backups with before they are stored remotely
script_file_directory = string, // the path where the scripts for `duplicacy init`, `duplicacy backup`, `duplicacy restore` and `duplicacy prune` are created

storage_backend = string, // the storage backend, possible values are `Local disk`, `Backblaze B2`, `SSH/SFTP Password`, `SSH/SFTP Keyfile`, `Onedrive`
b2_id = optional(string), // the value for `DUPLICACY_B2_ID`
b2_key = optional(string), // the value for `DUPLICACY_B2_KEY`
ssh_password = optional(string), // the value for `DUPLICACY_SSH_PASSWORD`
ssh_passphrase = optional(string), // the value for `DUPLICACY_SSH_PASSPHRASE`
secret_file_directory = optional(string, "/opt/duplicacy/secret"), // the path where the token and the ssh-key files are created
onedrive_token_file_name = optional(string, "one-token.json"), // the filename for `DUPLICACY_ONE_TOKEN`
ssh_key_file_name = optional(string, "id"), // the filename for `DUPLICACY_SSH_KEY_FILE`
secret_file_content = optional(string), // the content for onedrive_token_file_name or ssh_key_file_name
snapshot_id = string, // the `` for `duplicacy init`
storage_url = string, // the `` for `duplicacy init`, e.g. the [Duplicacy URI](https://github.com/gilbertchen/duplicacy/wiki/Storage-Backends) of where to store the backups
init_script_file_name = optional(string, "init"), // the duplicacy init script file name
backup_script_file_name = optional(string, "backup"), // the duplicacy backup script file name
prune_script_file_name = optional(string, "prune"), // the duplicacy prune script file name
restore_script_file_name = optional(string, "restore"), // the duplicacy restore script file name
init_options = optional(string, "-encrypt"), // the options for `duplicacy init`
backup_options = optional(string, ""), // the options for `duplicacy backup`
prune_options = optional(string, "-keep 365:3650 -keep 30:365 -keep 7:30 -keep 1:7 -a"), // the options for `duplicacy prune`
restore_options = optional(string, "-overwrite"), // the options for `duplicacy restore`
log_file_directory = optional(string, "/opt/mailcow/duplicacy/log"), // the directory for the script log files
backup_log_file_name = optional(string, "backup.log"), // the file name of the backup log file
prune_log_file_name = optional(string, "prune.log"), // the file name of the prune log file
restore_log_file_name = optional(string, "restore.log"), // the file name of the restore log file
pre_backup_script_file_name = optional(string, "pre-backup"), // the file name of the pre backup script
post_backup_script_file_name = optional(string, "post-backup"), // the file name of the post backup script
pre_prune_script_file_name = optional(string, "pre-prune"), // the file name of the pre prune script
post_prune_script_file_name = optional(string, "post-prune"), // the file name of the post prune script
pre_restore_script_file_name = optional(string, "pre-restore"), // the file name of the pre restore script
post_restore_script_file_name = optional(string, "post-restore"), // the file name of the post restore script
pre_backup_script_file_content = optional(string, null), // the content for the pre backup script
post_backup_script_file_content = optional(string, null), // the content for the pre backup script
pre_prune_script_file_content = optional(string, null), // the content for the pre prune script
post_prune_script_file_content = optional(string, null), // the content for the pre prune script
pre_restore_script_file_content = optional(string, null), // the content for the pre restore script
post_restore_script_file_content = optional(string, null), // the content for the pre restore script
}))
| `[]` | no |
| [duplicacy\_path](#input\_duplicacy\_path) | the path to install duplicacy | `string` | `"/opt/duplicacy"` | no |
| [duplicacy\_version](#input\_duplicacy\_version) | the duplicacy version to install | `string` | `"3.1.0"` | no |
| [encrypted\_packages](#input\_encrypted\_packages) | if cloud-init user data for the encrypted packages should be generated | `bool` | `false` | no |
| [encrypted\_packages\_list](#input\_encrypted\_packages\_list) | the encrypted packages the cloud-init user data should be generated for |
list(object({
url = string // the url to get the package from
api_header = string // the header to authorize getting the package
secret = string // the secret to decrypt the package (`openssl enc -aes-256-cbc -pbkdf2`)"
post_cmd = optional(string, null) // the command to be executed after the installing the package
name = optional(string, "encrypted_package") // the name of the encrypted package
}))
| `[]` | no |
| [fail2ban](#input\_fail2ban) | if cloud-init user data for installing fail2ban should be generated | `bool` | `false` | no |
| [fail2ban\_recidive](#input\_fail2ban\_recidive) | if recidive jail install should be generated | `bool` | `true` | no |
| [fail2ban\_sshd](#input\_fail2ban\_sshd) | if sshd jail install should be generated | `bool` | `true` | no |
| [gettext\_base](#input\_gettext\_base) | if cloud-init user data for installing gettext-base should be generated | `bool` | `false` | no |
| [golang](#input\_golang) | if cloud-init user data for installing golang should be generated | `bool` | `false` | no |
| [golang\_tools](#input\_golang\_tools) | the golang tools to be installed used as parameter for `go install` | `list(string)` | `[]` | no |
| [gpg](#input\_gpg) | if cloud-init user data for installing gpg should be generated | `bool` | `false` | no |
| [gzip](#input\_gzip) | if the cloud-init user data should be packed with gzip | `bool` | `false` | no |
| [haproxy](#input\_haproxy) | if cloud-init user data for installing haproxy should be generated | `bool` | `false` | no |
| [haproxy\_configuration](#input\_haproxy\_configuration) | the configuration for [haproxy](https://www.haproxy.com/documentation/hapee/latest/configuration/config-sections/overview/#haproxy-enterprise-configuration-sections)
the string '$ipv4\_public\_address' can be used as placeholder for the public ipv4-address of the server
(ip route get 8.8.8.8 \| grep 8.8.8.8 \| cut -d ' ' -f 7) |
object({
global = optional(
object({
configuration = string,
}),
{
configuration = < log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon

# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

# See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
EOT
}
),
global_additional = optional(
object({
configuration = optional(string)
}),
{}
)
frontend = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
backend = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
defaults = optional(
list(object({
configuration = string,
})
),
[
{
configuration = < log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
EOT
}]
),
listen = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
aggregations = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
cache = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
dynamic-update = optional(list(string), []),
fcgi-app = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
http-errors = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
mailers = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
peers = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
program = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
resolvers = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
ring = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
userlist = optional(
list(object({
label = string,
configuration = string,
})),
[]
),
})
| `null` | no |
| [hetzner](#input\_hetzner) | if cloud-init user data for making changes on a Hetzner Cloud Server should be generated | `bool` | `false` | no |
| [hetzner\_remove\_fqdn\_resolve](#input\_hetzner\_remove\_fqdn\_resolve) | if the FQDN should be removed from the entry `127.0.1.1 ...` in `/etc/hosts` | `bool` | `true` | no |
| [ip\_addresses](#input\_ip\_addresses) | the list of ip address suffixes and the commands to compute them (s. variable ip4\_address\_command) |
list(object({
ip_address_suffix = string
computation_command = string
}))
| `[]` | no |
| [ipv4\_address\_command](#input\_ipv4\_address\_command) | the command to determin the ipv4 address, other possible ways are
- ip route get 8.8.8.8 \| grep 8.8.8.8 \| sed -E 's/.*src (\S*) .*/\1/'
- ip addr show \| grep 'inet ' \| grep 'scope global' \| cut -d ' ' -f6 \| cut -d '/' -f 1 \| head -n 1
- curl https://ifconfig.me | `string` | `"ip addr show | grep 'inet ' | grep 'scope global' | cut -d ' ' -f6 | cut -d '/' -f 1 | head -n 1"` | no |
| [jq](#input\_jq) | if cloud-init user data for installing jq should be generated | `bool` | `false` | no |
| [jq\_install\_method](#input\_jq\_install\_method) | the install method, supported methods are 'binary', 'packages'
- 'binary' uses jq\_version
- 'packages' implies that jq can not be used for configuring inside cloud-init | `string` | `"binary"` | no |
| [jq\_version](#input\_jq\_version) | the jq version to be installed | `string` | `"1.6"` | no |
| [lineinfile](#input\_lineinfile) | if cloud-init user data for installing [lineinfile](https://github.com/l-with/lineinfile) should be generated | `bool` | `false` | no |
| [lnxrouter](#input\_lnxrouter) | if cloud-init user data for installing lnxrouter should be generated | `bool` | `false` | no |
| [lnxrouter\_arguments](#input\_lnxrouter\_arguments) | - ip\_address: specifies the interface ($interface in arguments)
- arguments: specifies the command line arguments to start lnxrouter with, $interface will be substituted by the name of the interface bound to the ip\_address (`ifconfig | grep --before-context=1 10.0.0.20 | grep --only-matching "^\w*"`) |
object({
ip_address = optional(string, null)
arguments = string
})
| `null` | no |
| [lnxrouter\_start](#input\_lnxrouter\_start) | if lnxrouter should be started | `bool` | `false` | no |
| [mailcow](#input\_mailcow) | if cloud-init user data for installing mailcow should be generated | `bool` | `false` | no |
| [mailcow\_acme](#input\_mailcow\_acme) | the way the Let's Encrypt certificate ist obtained:
`out-the-box`: The "acme-mailcow" container will try to obtain a LE certificate.
`certbot`: The certbot cronjob will manage Let's Encrypt certificates
if the Let's Encrypt certificate is obtained out-of-the-box | `string` | `"out-of-the-box"` | no |
| [mailcow\_acme\_staging](#input\_mailcow\_acme\_staging) | if ACME staging should be used (s. https://mailcow.github.io/mailcow-dockerized-docs/firststeps-ssl/#test-against-staging-acme-directory) | `bool` | `false` | no |
| [mailcow\_additional\_san](#input\_mailcow\_additional\_san) | the additional domains (SSL Certificate Subject Alternative Names), for instance autodiscover.*,autoconfig.* | `string` | `null` | no |
| [mailcow\_admin\_password](#input\_mailcow\_admin\_password) | the password for the mailcow administrator | `string` | `null` | no |
| [mailcow\_admin\_user](#input\_mailcow\_admin\_user) | the username of the mailcow administrator | `string` | `null` | no |
| [mailcow\_allow\_admin\_email\_login](#input\_mailcow\_allow\_admin\_email\_login) | allows admins and domain admins to directly log into SOGo as a mailbox user, without knowing the users password | `bool` | `false` | no |
| [mailcow\_api\_allow\_from](#input\_mailcow\_api\_allow\_from) | list of IPs to allow API access from | `list(string)` | `[]` | no |
| [mailcow\_api\_key](#input\_mailcow\_api\_key) | the API key for mailcow read-write access (allowed characters: a-z, A-Z, 0-9, -) | `string` | `null` | no |
| [mailcow\_api\_key\_read\_only](#input\_mailcow\_api\_key\_read\_only) | the API key for mailcow read-only access (allowed characters: a-z, A-Z, 0-9, -) | `string` | `null` | no |
| [mailcow\_backup\_path](#input\_mailcow\_backup\_path) | the path for the mailcow backup | `string` | `"/var/backups/mailcow"` | no |
| [mailcow\_backup\_script](#input\_mailcow\_backup\_script) | the full path for the mailcow backup script | `string` | `"/opt/mailcow/scripts/mailcow-backup.sh"` | no |
| [mailcow\_branch](#input\_mailcow\_branch) | the branch value for mailcow (`MAILCOW_BRANCH`) | `string` | `"master"` | no |
| [mailcow\_certbot\_post\_hook\_script](#input\_mailcow\_certbot\_post\_hook\_script) | the full path for the mailcow certbot post-hook script | `string` | `"/etc/letsencrypt/renewal-hooks/post/mailcow_certbot_post_hook.sh"` | no |
| [mailcow\_configure\_backup](#input\_mailcow\_configure\_backup) | if backup for mailcow should be configured for unattended backup | `bool` | `false` | no |
| [mailcow\_delete\_default\_admin\_script](#input\_mailcow\_delete\_default\_admin\_script) | the full path for the mailcow delete admin script | `string` | `"/root/mailcow_delete_default_admin.sh"` | no |
| [mailcow\_docker\_compose\_project\_name](#input\_mailcow\_docker\_compose\_project\_name) | the name for the mailcow docker compose project | `string` | `null` | no |
| [mailcow\_dovecot\_master\_auto\_generated](#input\_mailcow\_dovecot\_master\_auto\_generated) | if the dovecot master user and password should be auto-generated | `bool` | `true` | no |
| [mailcow\_dovecot\_master\_password](#input\_mailcow\_dovecot\_master\_password) | the password for the dovecot master user (DOVECOT\_MASTER\_PASS) if not auto-generated | `string` | `null` | no |
| [mailcow\_dovecot\_master\_user](#input\_mailcow\_dovecot\_master\_user) | the username of the dovecot master user (DOVECOT\_MASTER\_USER) if not auto-generated | `string` | `null` | no |
| [mailcow\_greylisting](#input\_mailcow\_greylisting) | if greylisting should be active | `bool` | `true` | no |
| [mailcow\_hostname](#input\_mailcow\_hostname) | the host name for mailcow | `string` | `null` | no |
| [mailcow\_install\_path](#input\_mailcow\_install\_path) | the install path for mailcow | `string` | `"/opt/mailcow-dockerized"` | no |
| [mailcow\_mynetworks](#input\_mailcow\_mynetworks) | the list of subnetwork masks to add to `mynetworks` in postfix
if subnetwork masks are provided at the beginning `127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 [fe80::]/10` is added (local) | `list(string)` | `[]` | no |
| [mailcow\_restore\_script](#input\_mailcow\_restore\_script) | the full path for the mailcow restore script | `string` | `"/opt/mailcow/scripts/mailcow-restore.sh"` | no |
| [mailcow\_rspamd\_ip\_whitelist](#input\_mailcow\_rspamd\_ip\_whitelist) | the list of ip adresses to be added to rspamd | `list(string)` | `[]` | no |
| [mailcow\_rspamd\_ui\_password](#input\_mailcow\_rspamd\_ui\_password) | the password for the mailcow Rspamd UI | `string` | `null` | no |
| [mailcow\_set\_admin\_script](#input\_mailcow\_set\_admin\_script) | the full path for the mailcow set admin script | `string` | `"/root/mailcow_set_admin.sh"` | no |
| [mailcow\_set\_rspamd\_ui\_password\_script](#input\_mailcow\_set\_rspamd\_ui\_password\_script) | the full path for the mailcow set Rspamd UI password script | `string` | `"/root/mailcow_set_rspamd_ui_password.sh"` | no |
| [mailcow\_submission\_port](#input\_mailcow\_submission\_port) | the [postfix submission](https://docs.mailcow.email/prerequisite/prerequisite-system/?h=submission#default-ports) port (SUBMISSION\_PORT in mailcow.conf) | `number` | `null` | no |
| [mailcow\_timezone](#input\_mailcow\_timezone) | the time zone value for mailcow (`MAILCOW_TZ`) | `string` | `"Europe/Berlin"` | no |
| [mailcow\_version](#input\_mailcow\_version) | the [version](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec) to checkout
default is [mailcow\_branch](#input\_mailcow\_branch) (coded in terraform) | `string` | `null` | no |
| [netcat](#input\_netcat) | if cloud-init user data for installing netcat should be generated | `bool` | `false` | no |
| [network](#input\_network) | if the network should be configured | `bool` | `false` | no |
| [network\_dispatcher\_script\_path](#input\_network\_dispatcher\_script\_path) | the path where network dispatcher scripts should placed | `string` | `"/etc/network-dispatcher"` | no |
| [network\_dispatcher\_scripts](#input\_network\_dispatcher\_scripts) | the network dispatcher scripts to be placed at network\_dispatcher\_script\_path and executed
the string '$public\_interface' can be used as placeholder for the device for internet access
(ip route get 8.8.8.8 \| grep 8.8.8.8 \| cut -d ' ' -f 5) |
list(object({
script_file_name = string,
script_file_content = string,
}))
| `[]` | no |
| [network\_resolved\_conf\_path](#input\_network\_resolved\_conf\_path) | the path where network resolved configurations should placed | `string` | `"/etc/systemd/resolved.conf.d/"` | no |
| [network\_resolved\_confs](#input\_network\_resolved\_confs) | the resolved configuration files to be placed at network\_resolved\_conf\_path
the service systemd-resolved is restarted |
list(object({
conf_file_name = string,
conf_file_content = string
}))
| `[]` | no |
| [nginx](#input\_nginx) | if cloud-init user data for installing nginx should be generated | `bool` | `false` | no |
| [nginx\_configuration\_home](#input\_nginx\_configuration\_home) | the nginx configuration home | `string` | `"/etc/nginx"` | no |
| [nginx\_confs](#input\_nginx\_confs) | the extra configurations for nginx |
list(object({
port = number // the port for `listen`
server_name = string // the server_name for `server_name`
fqdn = string // the FQDN used for include Let's Encrypt certificates: `/etc/letsencrypt/live/{{ nginx_conf.FQDN }}/...`
conf = string // the configuration to be included in the `sever` stanza
}))
| `[]` | no |
| [nginx\_gnu](#input\_nginx\_gnu) | if the [GNU Terry Pratchett](http://www.gnuterrypratchett.com) header should be inserted | `bool` | `true` | no |
| [nginx\_https\_conf](#input\_nginx\_https\_conf) | the nginx https configuration after `server_name` | `string` | `null` | no |
| [nginx\_https\_map](#input\_nginx\_https\_map) | the map stanza configuration for nginx https configuration | `string` | `null` | no |
| [nginx\_server\_fqdn](#input\_nginx\_server\_fqdn) | the FQDN of the server for nginx server\_name and Let's Encrypt certificates | `string` | `null` | no |
| [package](#input\_package) | if cloud-init user data for package should be generated | `bool` | `true` | no |
| [package\_reboot\_if\_required](#input\_package\_reboot\_if\_required) | if cloud-init user data for package\_reboot\_if\_required should be generated | `bool` | `false` | no |
| [package\_update](#input\_package\_update) | if cloud-init user data for package\_update should be generated | `bool` | `true` | no |
| [package\_upgrade](#input\_package\_upgrade) | if cloud-init user data for package\_upgrade should be generated | `bool` | `true` | no |
| [packages](#input\_packages) | the list of packages to be installed | `list(string)` | `[]` | no |
| [python3\_pip](#input\_python3\_pip) | if cloud-init user data for installing python3-pip should be generated | `bool` | `false` | no |
| [python3\_pip\_modules](#input\_python3\_pip\_modules) | the python modules to be installed | `list(string)` | `[]` | no |
| [rke2](#input\_rke2) | if cloud-init user data for the rke2 should be generated | `bool` | `false` | no |
| [rke2\_node\_1st](#input\_rke2\_node\_1st) | if cloud-init user data for the rke2 1st node should be generated | `bool` | `false` | no |
| [rke2\_node\_1st\_cert\_manager\_crd\_version](#input\_rke2\_node\_1st\_cert\_manager\_crd\_version) | the version of cert-manager CRDs to be installed | `string` | `"1.11.0"` | no |
| [rke2\_node\_1st\_rke2\_role\_id](#input\_rke2\_node\_1st\_rke2\_role\_id) | the role id for the app role in vault to login and get the token to put the `rke2.yaml` as kv into vault | `string` | `null` | no |
| [rke2\_node\_1st\_rke2\_secret\_id](#input\_rke2\_node\_1st\_rke2\_secret\_id) | the role id for the app role in vault to login and get the token to put the `rke2.yaml` as kv into vault | `string` | `null` | no |
| [rke2\_node\_1st\_vault\_addr](#input\_rke2\_node\_1st\_vault\_addr) | the vault address to put the `rke2.yml` as kv into | `string` | `null` | no |
| [rke2\_node\_1st\_vault\_field](#input\_rke2\_node\_1st\_vault\_field) | the vault field used to put the `rke2.yaml` as kv into vault | `string` | `"rke2_yaml"` | no |
| [rke2\_node\_1st\_vault\_mount](#input\_rke2\_node\_1st\_vault\_mount) | the vault mount used to put the `rke2.yaml` as kv into vault | `string` | `"gitlab"` | no |
| [rke2\_node\_1st\_vault\_path](#input\_rke2\_node\_1st\_vault\_path) | the vault path used to put the `rke2.yaml` as kv into vault | `string` | `"rancher/kubeconfig"` | no |
| [rke2\_node\_cert\_package\_api\_header](#input\_rke2\_node\_cert\_package\_api\_header) | the header to authorize getting the cert-package | `string` | `null` | no |
| [rke2\_node\_cert\_package\_secret](#input\_rke2\_node\_cert\_package\_secret) | the secret to decrypt the cert package (`openssl enc -aes-256-cbc -pbkdf2`) | `string` | `null` | no |
| [rke2\_node\_cert\_package\_url](#input\_rke2\_node\_cert\_package\_url) | the url to get the cert-package from | `string` | `null` | no |
| [rke2\_node\_config\_addendum](#input\_rke2\_node\_config\_addendum) | the addendum to the rke2 config after the lines 'token: ...' and optional 'server: ...' | `string` | `"cni: cilium"` | no |
| [rke2\_node\_other](#input\_rke2\_node\_other) | if cloud-init user data for the rke2 other nodes should be generated | `bool` | `false` | no |
| [rke2\_node\_other\_node\_1st\_ip](#input\_rke2\_node\_other\_node\_1st\_ip) | the ip of the 1st node for cloud-init user data for rke2 other nodes | `string` | `null` | no |
| [rke2\_node\_pre\_shared\_secret](#input\_rke2\_node\_pre\_shared\_secret) | the pre shared secret for `/etc/rancher/rke2/config.yaml` | `string` | `null` | no |
| [runcmd](#input\_runcmd) | if runcmd scripts should be configured | `bool` | `false` | no |
| [runcmd\_done\_file](#input\_runcmd\_done\_file) | the file created when runcmd is done | `string` | `"/root/cloud_init_runcmd_done"` | no |
| [runcmd\_scripts](#input\_runcmd\_scripts) | the runcmd scripts to be executed | `list(string)` | `[]` | no |
| [s3cmd](#input\_s3cmd) | if cloud-init user data for installing the [S3cmd](https://github.com/s3tools/s3cmd) should be generated | `bool` | `false` | no |
| [terraform](#input\_terraform) | if cloud-init user data for installing terraform should be generated | `bool` | `false` | no |
| [terraform\_install\_method](#input\_terraform\_install\_method) | the install method, supported methods are 'apt', 'binary'
- 'binary' uses terraform\_version | `string` | `"apt"` | no |
| [terraform\_version](#input\_terraform\_version) | the terraform version to be installed | `string` | `null` | no |
| [tool](#input\_tool) | if cloud-init user data for installing tools should be generated | `bool` | `false` | no |
| [tools](#input\_tools) | the list of tools that should be installed |
list(object({
name = string,
url = string,
dest_path = optional(string, "/usr/local/bin"),
}))
| `[]` | no |
| [unzip](#input\_unzip) | if cloud-init user data for installing unzip should be generated | `bool` | `false` | no |
| [unzip\_install\_method](#input\_unzip\_install\_method) | the install method, supported methods are 'apt', 'zypper' | `string` | `"apt"` | no |
| [user](#input\_user) | if cloud-init user data for users should be generated | `bool` | `true` | no |
| [users](#input\_users) | the list of user configurations |
list(object({
name = string,
groups = optional(string, null),
sudo = optional(string, null),
ssh_authorized_keys = optional(list(string), []),
passwd = optional(string, null),
lock_passwd = optional(bool, true),
}))
| `[]` | no |
| [vault](#input\_vault) | if cloud-init user data for installing vault should be generated | `bool` | `false` | no |
| [vault\_addr](#input\_vault\_addr) | the vault address (can be used as default for other features) | `string` | `null` | no |
| [vault\_api\_addr](#input\_vault\_api\_addr) | the [api\_addr](https://www.vaultproject.io/docs/configuration#api_addr):

Specifies the address (full URL) to advertise to other Vault servers in the cluster for client redirection.
This value is also used for plugin backends.
This can also be provided via the environment variable VAULT\_API\_ADDR.
In general this should be set as a full URL that points to the value of the listener address.

the string '$ipv4\_address' can be used as placeholder for the server ipv4-address | `string` | `null` | no |
| [vault\_bootstrap\_files\_path](#input\_vault\_bootstrap\_files\_path) | the path where the files needed for bootstrapping are saved | `string` | `"/root"` | no |
| [vault\_chown\_files](#input\_vault\_chown\_files) | the list of files to be changed to ownership vault:vault (before starting vault) | `list(string)` | `[]` | no |
| [vault\_cluster\_addr](#input\_vault\_cluster\_addr) | the [cluster\_addr](https://www.vaultproject.io/docs/configuration#cluster_addr)

Specifies the address to advertise to other Vault servers in the cluster for request forwarding.
This is a full URL, like api\_addr, but Vault will ignore the scheme (all cluster members always use TLS with a private key/certificate).

the string '$ipv4\_address' can be used as placeholder for the server ipv4-address (determined by variable ipv4\_address\_command) | `string` | `null` | no |
| [vault\_config\_path](#input\_vault\_config\_path) | the path for the vault configuration files | `string` | `"/etc/vault.d"` | no |
| [vault\_disable\_mlock](#input\_vault\_disable\_mlock) | the value for [disable\_mlock](https://www.vaultproject.io/docs/configuration#disable_mlock) | `bool` | `true` | no |
| [vault\_helper\_cmd\_http\_address](#input\_vault\_helper\_cmd\_http\_address) | the vault address (http) for the helper cmds
(if null the helper cmds are not installed) | `string` | `null` | no |
| [vault\_home\_path](#input\_vault\_home\_path) | the home of the vault specific files and folders | `string` | `"/srv/vault"` | no |
| [vault\_init](#input\_vault\_init) | if vault should be initialized | `bool` | `true` | no |
| [vault\_init\_json\_file\_mode](#input\_vault\_init\_json\_file\_mode) | the file mode for the vault init json result files | `string` | `"640"` | no |
| [vault\_init\_pgp\_public\_keys](#input\_vault\_init\_pgp\_public\_keys) | the definition of the usage of pgp keys for vault init
note: the number of pgp\_external\_public\_keys plus num\_internal\_unseal\_keys has to match vault\_key\_shares |
object({
num_internal_unseal_keys = optional(number, 1),
pgp_external_public_keys = optional(list(object({
content = string,
encoding = optional(string, "text/plain"),
owner = optional(string, "root")
group = optional(string, "root")
mode = optional(string, "640")
})), [])
})
| `null` | no |
| [vault\_init\_public\_key](#input\_vault\_init\_public\_key) | the public RSA key the output of the vault initialization is encoded with (to be decryptable by the corresponding private key with [rsadecrypt](https://developer.hashicorp.com/terraform/language/functions/rsadecrypt) | `string` | `null` | no |
| [vault\_install\_method](#input\_vault\_install\_method) | the install method, supported methods are 'apt', 'binary'
- 'binary' uses vault\_version | `string` | `"apt"` | no |
| [vault\_key\_shares](#input\_vault\_key\_shares) | the number of [key shares](https://developer.hashicorp.com/vault/docs/commands/operator/init#key-shares) | `number` | `1` | no |
| [vault\_key\_threshold](#input\_vault\_key\_threshold) | the number of key shares required to reconstruct the root key (s. https://developer.hashicorp.com/vault/docs/commands/operator/init#key-threshold) | `number` | `1` | no |
| [vault\_listeners](#input\_vault\_listeners) | the list of [listener](https://www.vaultproject.io/docs/configuration/listener/tcp)s
the default for each (coded in terraform)
- tls\_cert\_file is [vault\_tls\_cert\_file](#input\_vault\_tls\_cert\_file)
- tls\_key\_file is [vault\_tls\_key\_file](#input\_vault\_tls\_key\_file)
- tls\_client\_ca\_file [vault\_tls\_client\_ca\_file](#input\_vault\_tls\_client\_ca\_file)
the string '$ipv4\_address' can be used as placeholder for the server ipv4-address in address and cluster\_adrress |
list(object({
address = string,
cluster_address = optional(string, null),
tls_disable = optional(bool, true),
tls_cert_file = optional(string, null),
tls_key_file = optional(string, null),
tls_client_ca_file = optional(string, null),
}))
| `[]` | no |
| [vault\_local\_addr](#input\_vault\_local\_addr) | the vault address used for vault init, vault operator init, vault operator unseal and vault token revoke during cloud init | `string` | `null` | no |
| [vault\_log\_level](#input\_vault\_log\_level) | the [vault log level](https://www.vaultproject.io/docs/configuration#log_level) | `string` | `"info"` | no |
| [vault\_raft\_leader\_tls\_servername](#input\_vault\_raft\_leader\_tls\_servername) | the [leader\_tls\_servername](https://www.vaultproject.io/docs/configuration/storage/raft#leader_tls_servername) | `string` | `null` | no |
| [vault\_raft\_retry\_autojoin](#input\_vault\_raft\_retry\_autojoin) | the auto\_join values for [retry\_join](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#retry_join-stanza)
- [auto\_join](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#auto_join)
- [auto\_join\_scheme](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#auto_join\_scheme)
- [auto\_join\_port](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#auto_join\_port)
- computation\_command\_template: template to compute the node ip matching the ip of another node
[discover](https://github.com/hashicorp/go-discover) has to be installed for vault\_spread\_vault\_init\_json |
object({
auto_join = string,
auto_join_scheme = optional(string, null),
auto_join_port = optional(number, null),
ip_computation_command_template = optional(string, "ip route get $ip | grep $ip | sed -E 's/.*src (\\S*) .*/\\1/'"),
})
| `null` | no |
| [vault\_receive\_vault\_init\_json](#input\_vault\_receive\_vault\_init\_json) | if the vault init json result should be received from spreading | `bool` | `false` | no |
| [vault\_remove\_spread\_vault\_init\_json\_id\_file](#input\_vault\_remove\_spread\_vault\_init\_json\_id\_file) | if the ssh id file used for spreading the vault init json result to the cluster should be removed after used | `bool` | `true` | no |
| [vault\_remove\_vault\_init\_json](#input\_vault\_remove\_vault\_init\_json) | if the output of the vault initialization should removed
ATTENTION: The output of the vault initialization is highly confidential! It is the root of the secret management in vault!" | `bool` | `true` | no |
| [vault\_revoke\_root\_token](#input\_vault\_revoke\_root\_token) | if the initial root token should be revoked | `bool` | `true` | no |
| [vault\_secure\_init\_json](#input\_vault\_secure\_init\_json) | if the output of the vault initialization should secured
ATTENTION: The output of the vault initialization is highly confidential! It is the root of the secret management in vault!" | `bool` | `true` | no |
| [vault\_spread\_vault\_init\_json](#input\_vault\_spread\_vault\_init\_json) | if the vault init json result should be spread to the cluster | `bool` | `false` | no |
| [vault\_spread\_vault\_init\_json\_id\_file](#input\_vault\_spread\_vault\_init\_json\_id\_file) | the ssh id file used for spreading the vault init json result to the cluster | `string` | `null` | no |
| [vault\_start](#input\_vault\_start) | if vault should be started | `bool` | `false` | no |
| [vault\_storage\_raft\_cluster\_member\_this](#input\_vault\_storage\_raft\_cluster\_member\_this) | the actual instance to be excluded for the [retry\_join-stanza](https://www.vaultproject.io/docs/configuration/storage/raft#retry_join-stanza)s | `string` | `null` | no |
| [vault\_storage\_raft\_cluster\_members](#input\_vault\_storage\_raft\_cluster\_members) | the list of cluster members for the [retry\_join-stanza](https://www.vaultproject.io/docs/configuration/storage/raft#retry_join-stanza)s | `list(string)` | `[]` | no |
| [vault\_storage\_raft\_node\_id](#input\_vault\_storage\_raft\_node\_id) | the `node_id` value for `storage "raft"` | `string` | `null` | no |
| [vault\_storage\_raft\_path](#input\_vault\_storage\_raft\_path) | the `path` value for `storage "raft"` | `string` | `"/srv/vault/file/raft"` | no |
| [vault\_storage\_raft\_retry\_join\_api\_port](#input\_vault\_storage\_raft\_retry\_join\_api\_port) | the port number for the [leader\_api\_addr](https://developer.hashicorp.com/vault/docs/configuration/storage/raft#leader_api_addr) in the [retry\_join-stanza](https://www.vaultproject.io/docs/configuration/storage/raft#retry_join-stanza)s | `number` | `8200` | no |
| [vault\_tls\_cert\_file](#input\_vault\_tls\_cert\_file) | the path of the certificate for TLS ([tls\_cert\_file](https://www.vaultproject.io/docs/configuration/listener/tcp#tls_cert_file)
default is [vault\_storage\_raft\_leader\_client\_cert\_file](#input\_vault\_storage\_raft\_leader\_client\_cert\_file) (coded in terraform) | `string` | `null` | no |
| [vault\_tls\_client\_ca\_file](#input\_vault\_tls\_client\_ca\_file) | the [tls\_client\_ca\_file](https://www.vaultproject.io/docs/configuration/listener/tcp#tls_client_ca_file)
default is [vault\_storage\_raft\_leader\_ca\_cert\_file](#input\_vault\_storage\_raft\_leader\_ca\_cert\_file) (coded in terraform) | `string` | `null` | no |
| [vault\_tls\_contents](#input\_vault\_tls\_contents) | the vault tls file contents
tls\_file has to be one of
- cert
- key
- client\_ca
- storage\_raft\_leader\_ca\_cert
- storage\_raft\_leader\_client\_cert
- storage\_raft\_leader\_client\_key
and the corresponding terraform variable is used as file\_name
- encoding of the content can be 'text/plain' (default) or 'base64' |
list(object({
tls_file = optional(string, null),
content = string,
encoding = optional(string, "text/plain")
owner = optional(string, "vault")
group = optional(string, "vault")
mode = optional(string, "640")
}))
| `[]` | no |
| [vault\_tls\_files](#input\_vault\_tls\_files) | DEPRECATED: use vault\_tls\_contents instead
the vault tls files
filename can contain the placeholders
- $vault\_tls\_cert\_file
- $vault\_tls\_key\_file
- $vault\_tls\_client\_ca\_file
which are replace by the corresponding terraform variables
- encoding of the content can be 'text/plain' (default) or 'base64' |
list(object({
file_name = string,
content = string,
encoding = optional(string, "text/plain")
owner = optional(string, "vault")
group = optional(string, "vault")
mode = optional(string, "640")
}))
| `[]` | no |
| [vault\_tls\_key\_file](#input\_vault\_tls\_key\_file) | the path of the private key for the certificate for TLS ([tls\_key\_file](https://www.vaultproject.io/docs/configuration/listener/tcp#tls_key_file))
default is [vault\_storage\_raft\_leader\_client\_key\_file](#input\_vault\_storage\_raft\_leader\_client\_key\_file) (coded in terraform) | `string` | `null` | no |
| [vault\_tls\_storage\_raft\_leader\_ca\_cert\_file](#input\_vault\_tls\_storage\_raft\_leader\_ca\_cert\_file) | the [leader\_ca\_cert\_file](https://www.vaultproject.io/docs/configuration/storage/raft#leader_ca_cert_file)
default is [vault\_home\_path](#input\_vault\_home\_path)/tls/client\_ca.pem (coded in terraform) | `string` | `null` | no |
| [vault\_tls\_storage\_raft\_leader\_client\_cert\_file](#input\_vault\_tls\_storage\_raft\_leader\_client\_cert\_file) | the [leader\_client\_cert\_file](https://www.vaultproject.io/docs/configuration/storage/raft#leader_client_cert_file)
default is [vault\_home\_path](#input\_vault\_home\_path)/tls/cert.pem (coded in terraform) | `string` | `null` | no |
| [vault\_tls\_storage\_raft\_leader\_client\_key\_file](#input\_vault\_tls\_storage\_raft\_leader\_client\_key\_file) | the [leader\_client\_key\_file](https://www.vaultproject.io/docs/configuration/storage/raft#leader_client_key_file)
default is [vault\_home\_path](#input\_vault\_home\_path)/tls/key.pem (coded in terraform) | `string` | `null` | no |
| [vault\_ui](#input\_vault\_ui) | if the vault user interface should be activated | `bool` | `false` | no |
| [vault\_unseal](#input\_vault\_unseal) | if vault should be unsealed | `bool` | `false` | no |
| [vault\_version](#input\_vault\_version) | the vault version to be installed | `string` | `null` | no |
| [vault\_zipped\_binary\_url](#input\_vault\_zipped\_binary\_url) | the download url for vault install method 'binary'
- ${vault\_version} is replaced by the value for vault\_version
- the download has to be a zip file containing the vault binary | `string` | `"https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_linux_amd64.zip"` | no |
| [wait\_until](#input\_wait\_until) | if cloud-init user data for installing [wait\_until](https://github.com/l-with/wait-until) should be generated | `bool` | `false` | no |
| [write\_file](#input\_write\_file) | if files should be written | `bool` | `false` | no |
| [write\_files](#input\_write\_files) | the files to be written
- encoding of the content can be 'text/plain' (default) or 'base64' |
list(object({
file_name = string,
content = string,
encoding = optional(string, "text/plain"),
owner = optional(string, "root"),
group = optional(string, "root"),
mode = optional(string, "644"),
}))
| `[]` | no |
| [zypper](#input\_zypper) | if cloud-init user data for adding zypper repositories should be generated | `bool` | `false` | no |
| [zypper\_repositories](#input\_zypper\_repositories) | the zypper repositories that should be added |
list(object({
uri = string,
alias = string,
}))
|
[
{
"alias": "opensuse-oss-leap-15.5",
"uri": "http://download.opensuse.org/distribution/leap/15.5/repo/oss/"
}
]
| no |

#### Outputs

| Name | Description |
|------|-------------|
| [cloud\_init](#output\_cloud\_init) | the cloud-init user data |
| [ipv4\_address\_command](#output\_ipv4\_address\_command) | the command to determine the ipv4 address |
| [runcmd\_done\_file](#output\_runcmd\_done\_file) | the file created when runcmd is done |
| [vault](#output\_vault) | the relevant results from vault install and init |