Compare commits

...

7 Commits

Author SHA1 Message Date
500a0df93d Merge pull request 'feat/haproxy' (#12) from feat/haproxy into main
All checks were successful
build-deploy / Bump version and create changelog with commitizen (push) Successful in 12s
Reviewed-on: #12
2024-08-29 18:15:26 +00:00
dc096e497d
feat: redirect to wiki and add assets
All checks were successful
development / Check commit compliance (push) Successful in 32s
pull-requests-open / Check commit compliance (pull_request) Successful in 33s
2024-08-29 20:13:45 +02:00
367d5481f6
feat: rename playbooks for certificates and credentials
All checks were successful
development / Check commit compliance (push) Successful in 5s
pull-requests-open / Check commit compliance (pull_request) Successful in 7s
2024-08-28 23:22:22 +02:00
41d8254fa8
feat: initial cool readme
All checks were successful
development / Check commit compliance (push) Successful in 37s
pull-requests-open / Check commit compliance (pull_request) Successful in 39s
2024-08-28 21:18:06 +02:00
23c99407ba
feat: add some templating for nomad haproxy job
All checks were successful
development / Check commit compliance (push) Successful in 29s
2024-08-27 22:30:10 +02:00
bb77c38d3d
fix: remove duplicate tags for nomad tasks
All checks were successful
development / Check commit compliance (push) Successful in 4s
2024-08-26 23:14:35 +02:00
54a86d7af3
feat: new tls_multi_node test for molecule with some adjustment to tags
All checks were successful
development / Check commit compliance (push) Successful in 25s
2024-08-26 23:10:04 +02:00
73 changed files with 2107 additions and 787 deletions

View File

@ -42,7 +42,7 @@
- do not use run_once instructions as it is wildly unreliable - do not use run_once instructions as it is wildly unreliable
- typo in credentials template preventing from generating the initial credential file - typo in credentials template preventing from generating the initial credential file
## 0.4.0 (2024-07-10) ## v0.4.0 (2024-07-10)
### Feat ### Feat
@ -57,14 +57,14 @@
- implement longer wait to stabilize consul cluster before bootstrapping to avoid timeout errors - implement longer wait to stabilize consul cluster before bootstrapping to avoid timeout errors
## 0.3.0 (2024-05-13) ## v0.3.0 (2024-05-13)
### Feat ### Feat
- **generate_credentials**: generate new accesor ids and vault token credentials - **generate_credentials**: generate new accesor ids and vault token credentials
- **vault**: enable consul service registration automatically if consul is also enabled - **vault**: enable consul service registration automatically if consul is also enabled
## 0.2.0 (2024-05-05) ## v0.2.0 (2024-05-05)
### Feat ### Feat
@ -75,7 +75,7 @@
- **globals**: restore default globals.yml file, move changes to test directory - **globals**: restore default globals.yml file, move changes to test directory
- **vault/consul**: ensure idempotence of extra_volumes list to avoid restarting on each run due to slightly different service files - **vault/consul**: ensure idempotence of extra_volumes list to avoid restarting on each run due to slightly different service files
## 0.1.0 (2024-05-03) ## v0.1.0 (2024-05-03)
### Feat ### Feat

View File

@ -1,3 +1,46 @@
# Ansible Collection - ednz_cloud.hashistack # 🚀 hashistack-ansible Collection
THIS REPOSITORY IS A WORK IN PROGRESS, IT IS NOWHERE NEAR FIT FOR PRODUCTION. ![Ansible Badge](https://img.shields.io/badge/Ansible-E00?logo=ansible&logoColor=fff&style=for-the-badge)
![HashiCorp Badge](https://img.shields.io/badge/HashiCorp-000?logo=hashicorp&logoColor=fff&style=for-the-badge)
![Nomad Badge](https://img.shields.io/badge/Nomad-00CA8E?logo=nomad&logoColor=fff&style=for-the-badge)
![Vault Badge](https://img.shields.io/badge/Vault-FFEC6E?logo=vault&logoColor=000&style=for-the-badge)
![Consul Badge](https://img.shields.io/badge/Consul-F24C53?logo=consul&logoColor=fff&style=for-the-badge)
Welcome to hashistack-ansible! This Ansible collection is your one-stop solution for deploying and managing HashiCorp product clusters with ease. Whether you're setting up Vault, Consul, or Nomad, this collection automates the entire process, allowing you to focus on building and scaling your infrastructure without the hassle. Let's dive into what this collection offers! 🌟
## 🎯 Features
### 🔧 Deploy from Scratch
Set up a fully integrated HashiStack environment with Vault, Consul, and Nomad from the ground up. Our playbooks ensure seamless integration between these services, enabling you to hit the ground running without manual setup.
### 🎯 Targeted and Global Updates
Update specific parts of your infrastructure using tags to target individual components or perform global updates to keep your entire stack in sync. This flexibility ensures minimal downtime and smooth rollouts.
### 🔐 Comprehensive Certificate Authority Management
Easily manage your cluster's certificates with playbooks that handle the creation, renewal, and distribution of certificates across your infrastructure. This includes Root CAs, intermediates, and service-specific leaf certificates, ensuring secure communication throughout your environment.
### 🔄 Rolling Updates for High Availability
Perform control plane upgrades with rolling updates, ensuring that your services stay online and available during the upgrade process. This minimizes risk and maximizes uptime.
## 🛠️ How to Get Started
1. Head to the [Quick-Start Guide](https://git.ednz.fr/ansible-collections/hashistack/wiki/02-quick-start)
This should give you a good idea of how the collection works, and what it can do.
2. From there, you can follow the rest of the [Documentation](https://git.ednz.fr/ansible-collections/hashistack/wiki/01-introduction)
This will allow you to customize your deployment to your exact needs !
## 🧑‍💻 Contributions & Feedback
We welcome contributions and feedback! If you encounter any issues or have suggestions for improvement, feel free to open an issue or submit a pull request. Let's make hashistack-ansible even better together! 🤝
## 📄 License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

BIN
assets/boundary_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/boundary_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/consul_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
assets/consul_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/hashicorp_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
assets/nomad_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/nomad_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/packer_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/packer_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/terraform_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/vagrant_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
assets/vagrant_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/vault_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
assets/vault_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
assets/waypoint_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
assets/waypoint_white_500x500.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

1
docs/README.md Normal file
View File

@ -0,0 +1 @@
You can find the documentation for this project in the [Wiki](https://git.ednz.fr/ansible-collections/hashistack/wiki)

View File

@ -1,97 +0,0 @@
# Architecture Guide
Hashistack-Ansible allows you to deploy a number of architecture, wether you want to deploy a dev, testing, or production environment. These different architectures are described in this section.
## Dev deployment
If you only want to deploy a test environment, you can simply add a simgle host to each service that you want to deploy.
```ini
[haproxy_servers]
[vault_servers]
test01
[consul_servers]
test01
[nomad_servers]
test01
```
In this example, you will end end with each service running on a single host, with no clustering, and no redundancy. This setup *IS NOT RECOMMENDED** for anything but testing purposes, as it provides zero resiliency, and will break if anything goes down.
For this setup, the only requirement is for the target host to have a network interface that you can ssh into from the deployment host.
The architecture would like something like this:
```mermaid
graph LR;
client[Client] -->|http| server{
Vault Server
Consul Server
Nomad Server
};
```
## Testing/Preprod deployment
For testing, of pre-production deployments, running all services on the same nodes might be a good way to cut cost and/or save resources.
## Production deployment
For production use, it is recommended to separate concerns as much as possible. This means that consul, vault and nomad, as well as the haproxy services, should be on different nodes altogether. The **client-facing** and **cluster-facing** interfaces should also be separated.
Ideally, you would need:
- an odd number (3 to 5) of consul servers
- an odd number (3 to 5) of vault servers
- an odd number (3 to 5) of nomad servers
- multiple (2 to 3) haproxy servers
The **nomad**, **vault** and **consul** servers should have **two network interfaces**, and one of them should be reachable from the haproxy nodes.
The architecture for this infrastructure would look like:
```mermaid
graph TD
client[Client] -->|https :443| keepalived
keepalived[VIP] --> haproxy1[HAProxy] & haproxy2[HAProxy]
subgraph frontends
direction LR
haproxy1[HAProxy]
haproxy2[HAProxy]
end
haproxy1[HAProxy] & haproxy2[HAProxy] -->|http :8500| consul
subgraph consul
direction LR
consul1[Consul 01] <--> consul2[Consul 02] & consul3[Consul 03] & consul4[Consul 04] & consul5[Consul 05]
consul2[Consul 02] <--> consul3[Consul 03] & consul4[Consul 04] & consul5[Consul 05]
consul3[Consul 03] <--> consul4[Consul 04] & consul5[Consul 05]
consul4[Consul 04] <--> consul5[Consul 05]
end
haproxy1[HAProxy] & haproxy2[HAProxy] -->|http :8200| vault
subgraph vault
direction LR
vault1[Vault 01] <--> vault2[Vault 02]
vault2[Vault 02] <--> vault3[Vault 03]
vault3[Vault 03] <--> vault1[Vault 01]
end
vault -->|Service registration| consul
haproxy1[HAProxy] & haproxy2[HAProxy] -->|http :4646| nomad
subgraph nomad
direction LR
nomad1[Nomad 01] <--> nomad2[Nomad 02]
nomad2[Nomad 02] <--> nomad3[Nomad 03]
nomad3[Nomad 03] <--> nomad1[Nomad 01]
end
nomad -->|Service registration| consul
```
> **Note**: you can substract the haproxy part if using an external load-balancing solution, like AWS ALB,or any other LB technology, for connecting to your platform.

View File

@ -1,3 +0,0 @@
# Deploying a Consul cluster
This documentation explains each steps necessary to successfully deploy a Consul cluster using the ednz_cloud.hashistack ansible collection.

View File

@ -1 +0,0 @@
# Adding extra configuration options

View File

@ -1,103 +0,0 @@
# General documentation
## Configuration directory
### Main configuration directory
Hashistack Ansible uses a configuration directory to store all the configuration files and other artifacts.
This directory is defined with the variable `hashistack_configuration_directory`. By default, it will look at `{{ lookup('env', 'PWD') }}/etc/hashistack`, which equals `$(pwd)/etc/hashistack`.
Under this directory, you are expected to place the `globals.yml` file, with your configuration.
### Sub configuration directories
#### Group configuration directories
Additionally, subdirectories can be used to tailor the configuration further.
Each group within the `inventory` will look at a directory named after itself:
- nomad_servers group will look for `{{ hashistack_configuration_directory }}/nomad_servers`
- vault_servers group will look for `{{ hashistack_configuration_directory }}/vault_servers`
- consul_servers group will look for `{{ hashistack_configuration_directory }}/consul_servers`
Within each of these directories, you can place an additional `globals.yml file`, that will superseed the file at the root of the configuration directory.
- **Example**:
If `etc/hashistack/globals.yml` looks like:
```yaml
---
enable_vault: "no"
enable_consul: "no"
enable_nomad: "no"
```
And `etc/hashistack/nomad_servers/globals.yml` looks like:
```yaml
---
enable_nomad: "yes"
```
Servers in the `nomad_servers` group will end up with the following configuration:
```yaml
---
enable_vault: "no"
enable_consul: "no"
enable_nomad: "yes"
```
This approach lets you customize your deployment for your exact needs.
#### Host configuration directories
Additionally, within each `group configuration directory`, you can add `host configuration directory`, that will be named after the hosts defined in your `inventory`. These host directories can also be populated with a `globals.yml` file, that will superseed the `group` and `deployment` configuration files.
- **Example**
If `etc/hashistack/globals.yml` looks like:
```yaml
---
enable_vault: "no"
enable_consul: "no"
enable_nomad: "no"
api_interface: "eth0"
```
And `etc/hashistack/nomad_servers/globals.yml` looks like:
```yaml
---
enable_nomad: "yes"
api_interface: "eth1"
```
And `etc/hashistack/nomad_servers/nomad-master-01/globals.yml` looks like:
```yaml
api_interface: "eth0.vlan40"
```
Servers in the `nomad_servers` group will end up with the following configuration:
```yaml
---
enable_vault: "no"
enable_consul: "no"
enable_nomad: "yes"
api_interface: "eth1"
```
Except for host `nomad-master-01`, who will have the following:
```yaml
---
enable_vault: "no"
enable_consul: "no"
enable_nomad: "yes"
api_interface: "eth0.vlan40"
```

View File

@ -1,104 +0,0 @@
# Deploying HAProxy frontends
This documentation explains each steps necessary to successfully deploy HAProxy frontends for your deployment, using the ednz_cloud.hashistack ansible collection.
## Prerequisites
You should, before attempting any deployment, have read through the [Quick Start Guide](./quick_start.md). These steps are necessary in order to ensure smooth operations going forward.
## Variables
### Basics
First, in order to deploy the HAproxy frontends, you need to enable the deployment.
```yaml
enable_haproxy: "yes"
```
You can also configure the version of haproxy you would like to use. This has very little impact, and should most likely be left untouched to whatever the collection version is defaulting to (which is the version that it is tested against).
```yaml
haproxy_version: "2.8"
```
This version can either be `latest`, or any `X`, `X.Y`, `X.Y.Z` tag of the [haproxytech/haproxy-debian](https://hub.docker.com/r/haproxytech/haproxy-debian) docker image.
For production deployment, it is recommended to use the `X.Y.Z` syntax.
The `deployment_method` variable will define how to install vault on the nodes.
By default, it runs haproxy inside a docker container, but this can be changed to `host` to install haproxy from the package manager.
Note that not all versions of haproxy are available as a package on all supported distributions. Please refer to the documentation of [ednz_cloud.deploy_haproxy](https://github.com/ednz-cloud/deploy_haproxy) for details about supported versions when installing from the package manager.
```yaml
deployment_method: "docker"
```
### General settings
There aren't many settings that you can configure to deploy the HAProxy frontends. First you'll need to configure a Virtual IP, and pass it in the `globals.yml` configuration file.
```yaml
hashistack_external_vip_interface: "eth0"
hashistack_external_vip_addr: "192.168.121.100"
```
This is used to configure keepalived to automatically configure this VIP on one of the frontend, and handle failover.
You also need to configure the names that will resolve to your different applications (consul, nomad, vault). These names should resolve to your Virtual IP, and will be used to handle host-based routing on haproxy.
```yaml
consul_fqdn: consul.ednz.lab
vault_fqdn: vault.ednz.lab
nomad_fqdn: nomad.ednz.lab
```
With this configuration, querying `http://consul.ednz.lab` will give you the consul UI and API, through haproxy.
> Note: subpaths are not yet supported, so you cannot set the fqdn to `generic.domain.tld/consul`. This feature will be added in a future release.
### Enabling external TLS
To enable external TLS for your APIs and UIs, you will need to set the following variable.
```yaml
enable_tls_external: true
```
This will enable the https listener for haproxy and configure the http listener to be a https redirect only.
## Managing external TLS certificates
### Generating certificates with hashistack-ansible
If you don't care about having trusted certificates (e.g. for developement or testing purposes), you can generate some self-signed certificates for your applications using the `generate_certs.yml` playbook.
```bash
ansible-playbook -i multinode.ini ednz_cloud.hashistack.generate_certs.yml
```
This will generate self-signed certificates for each applications that has been enabled in your `globals.yml`, and for then respective fqdn (also configured in `globals.yml`).
These certificates are going to be placed in `etc/hashistack/certificates/external/`, and will be named after each fqdn. These files should be encrypted using something like ansible-vault, as they are sensitive.
### Managing your own TLS certificates
Similarly, you can manage your own TLS certificates, signed by your own CA. Your certificates should be placed in the `etc/hashistack/certificates/external/` directory, similar to the self-signed ones, and be named like:
`<your_fqdn>.pem` and `<your_fqdn>.pem.key`, for each application.
At the moment, setting all certificates in a single file is not supported, but will be added in a later release.
These certificates will be copied over to the `haproxy_servers` hosts, in `/var/lib/haproxy/certs/`.
### Managing certificates externally
In case you already have systems in place to deploy and renew your certificates, you can simply enable the options in `globals.yml` to not manage certificates directly in hashistack-ansible.
```yaml
external_tls_externally_managed_certs: true
```
Enabling this option will prevents the playbooks from trying to copy certificates over, but the HAProxy nodes will still expect them to be present. It is up to you to copy them over.

View File

@ -1,82 +0,0 @@
# Deploying a Nomad cluster
This documentation explains each steps necessary to successfully deploy a Nomad cluster using the ednz_cloud.hashistack ansible collection.
## Prerequisites
You should, before attempting any deployment, have read through the [Quick Start Guide](./quick_start.md). These steps are necessary in order to ensure smooth operations going forward.
## Variables
### Basics
First, in order to deploy a nomad cluster, you need to enable it.
```yaml
enable_nomad: "yes"
```
Selecting the nomad version to install is done with the `nomad_version` variable.
```yaml
nomad_version: latest
```
The vault version can either be `latest` or `X.Y.Z`.
For production deployment, it is recommended to use the `X.Y.Z` syntax.
### General settings
First, you can change some general settings for nomad, like the dc and region options.
```yaml
nomad_datacenter: dc1
nomad_region: global
```
### ACLs settings
By default, ACLs are enabled on nomad, and automatically bootstrapped.
You can change this by editing the `nomad_acl_configuration` variable:
```yaml
nomad_acl_configuration:
enabled: true
token_ttl: 30s
policy_ttl: 60s
role_ttl: 60s
```
### Consul integration settings
By default, if consul if also enabled, nomad will use it to register itself as a consul service and also use consul to automatically join the cluster.
```yaml
nomad_enable_consul_integration: "{{ enable_consul | bool }}"
nomad_consul_integration_configuration:
address: "127.0.0.1:{{ hashicorp_consul_configuration.ports.https if consul_enable_tls else hashicorp_consul_configuration.ports.http }}"
auto_advertise: true
ssl: "{{ consul_enable_tls | bool }}"
token: "{{ _credentials.consul.tokens.nomad.server.secret_id if nomad_enable_server else _credentials.consul.tokens.nomad.client.secret_id}}"
tags: []
```
Optionally, you can add tags to you nomad services, or disable the consul integration if you don't plan on using it.
### Vault integration settings
Vault integration for nomad is by default disabled, as it requires some vault configuration that is out of the scope of this collection.
You can, once you have deployed and configured vault (or if you are using an external vault not managed by the collection), enable the integration
```yaml
nomad_enable_vault_integration: false
nomad_vault_integration_configuration: {}
```
For configuration options, please refer to the [Official Documentation](https://developer.hashicorp.com/nomad/docs/configuration/vault)
### Drivers settings
### Internal TLS

View File

@ -1,154 +0,0 @@
# Quick Start Guide
This documentation will show you the preparation steps necessary to ensure that you environment is ready to deploy cluster(s).
## Prerequisites
### Recommended readings
Its beneficial to learn basics of both [Ansible](https://docs.ansible.com/) and [Docker](https://docs.docker.com/)(for docker deployments) before running Hashistack Ansible.
### Operating
The only supported operating systems currently are:
- Debian
- 11, Bullseye
- 12, Bookworm
- Ubuntu
- 20.04, Focal
- 22.04, Jammy
Other Debian-based distributions might work, but **are not tested**, and may break at any given update.
### Target Hosts
Target hosts are the hosts you are planning on deploying cluster(s) to.
These hosts must satisfy the following minimum requirements:
- Be reachable via ssh by the deployment node (the machine running the ansible playbooks), with a user that has the ability to escalate privileges.
- Be able to comunicate with each other, according to your cluster topology (vault hosts must all be able to reach each other, etc...)
- Be synced to a common time
- Have less than 10ms of latency to reach each other (raft consensus algorithm requirement)
- Be using systemd as their init system.
Ideally, hosts are recommended to satisfy the following recommendations:
- Have 2 network interfaces:
- One that is public facing for client-to-server traffic
- One that is not public facing for server-to-server and deployment-to-server communications
- Have a minimum of 8GB of memory (less will work, but the larger the scale, the higher the RAM requirements will be)
- Have a minimum of 40GB of free disk space
## Prepare the deployment host
1. Install the virtual environment dependencies.
```bash
sudo apt update
sudo apt install git python3-dev libffi-dev gcc libssl-dev python3-venv
```
2. Create a python virtual environment and activate it.
```bash
python3 -m venv /path/to/venv
source /path/to/venv/bin/activate
```
3. Ensure the latest version of pip is installed
```bash
pip install -U pip
```
4. Install [Ansible](http://www.ansible.com/). Hashistack-Ansible requires at least Ansible **7**(or ansible-core **2.15**)
```bash
pip install 'ansible-core>=2.15'
```
5. Create the directory structure. This is not required but **heavily** recommended.
```bash
mkdir -p etc/hashistack collections inventory roles
touch ansible.cfg
```
Your directory structure should look like this
```bash
.
├── ansible.cfg
├── collections
├── etc
│   └── hashistack
├── inventory
└── roles
```
6. Edit the `ansible.cfg` file with the minimum requirements.
```bash
[defaults]
roles_path = ./roles/
collections_path = ./collections/
inventory = ./inventory/
```
7. Install the `ednz_cloud.hashistack` ansible collection
```bash
ansible-galaxy collection install ednz_cloud.hashistack:==<version>
```
You should now have a directory under `./collections/ansible_collections/ednz_cloud/hashistack`
8. Install the other dependencies required by `ednz_cloud.hashistack`
```bash
ansible-galaxy install -r ./collections/ansible_collections/ednz_cloud/hashistack/roles/requirements.yml
```
This will install roles that are not packaged with the collection, but are still required in order to run the playbooks.
You should now have some roles inside `./roles/`.
9. Copy `inventory` file and `globals.yml `file locally
```bash
cp collections/ansible_collections/ednz_cloud/hashistack/playbooks/inventory/multinode.ini inventory/
```
```bash
cp collections/ansible_collections/ednz_cloud/hashistack/playbooks/group_vars/all/globals.yml etc/hashistack/globals.yml
```
## Generate Credentials
Before deploying your infrastructure with Hashistack-Ansible, you need to generate credentials that will be used to bootstrap the various clusters.
This can be done by running the `generate_credentials.yml` playbook.
```bash
ansible-playbook -i inventory/inventory.ini ednz_cloud.hashistack.generate_credentials.yml
```
This will create and populate `etc/hashistack/secrets/credentials.yml`
> [!WARNING]
> This file is VERY SENSITIVE, as it holds the root tokens and other credentials for consul and nomad clusters.
This does not generate vault credentials, as it is not possible to generate those in advance. These credentials will be generated, if you enable the vault deployment, during the bootstrap process of the vault cluster, and stored in `etc/hashistack/secrets/vault.yml`
> [!WARNING]
> It is HIGHLY recommended to encrypt these two files before enventually commiting them to source control. You can do so using tools like [ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html) or [sops](https://github.com/getsops/sops).
## Running preflight checks and bootstrap playbooks
Before running the main deployment playbook, you might want to run the `bootstrap` and `preflight` playbooks, which do a number of checks to ensure all hosts are setup correctly for deployment.
```bash
ansible-playbook -i inventory/inventory.ini ednz_cloud.hashistack.bootstrap.yml
ansible-playbook -i inventory/inventory.ini ednz_cloud.hashistack.preflight.yml
```
These playbooks will run a number of checks, and installations, in order to ensure the target hosts, as well as your deployment environment are correctly setup in order to install all the components.

View File

@ -1,6 +0,0 @@
# TLS Guide
create certificate/ca directory
`ansible-playbook -i inventory/multinode.ini ednz_cloud.hashistack.generate_certs.yml`

View File

@ -1,107 +0,0 @@
# Deploying a Vault cluster
This documentation explains each steps necessary to successfully deploy a Vault cluster using the ednz_cloud.hashistack ansible collection.
## Prerequisites
You should, before attempting any deployment, have read through the [Quick Start Guide](./quick_start.md). These steps are necessary in order to ensure smooth operations going forward.
## Variables
### Basics
First, in order to deploy a Vault cluster, you need to enable it.
```yaml
enable_vault: "yes"
```
Selecting the vault version to install is done with the `vault_version` variable.
```yaml
vault_version: latest
```
The vault version can either be `latest` or `X.Y.Z`.
For production deployment, it is recommended to use the `X.Y.Z` syntax.
### General settings
First, you can change some general settings for vault.
```yaml
vault_cluster_name: vault
vault_enable_ui: true
vault_seal_configuration:
key_shares: 3
key_threshold: 2
```
### Storage settings
The storage configuration for vault can be edited as well. By default, vault will be configured to setup `raft` storage between all declared vault servers (in the `vault_servers` group).
```yaml
vault_storage_configuration:
raft:
path: "{{ hashicorp_vault_data_dir }}/data"
node_id: "{{ ansible_hostname }}"
retry_join: |
[
{% for host in groups['vault_servers'] %}
{
'leader_api_addr': 'http://{{ hostvars[host].api_interface_address }}:8200'
}{% if not loop.last %},{% endif %}
{% endfor %}
]
```
While this is the [recommended](https://developer.hashicorp.com/vault/docs/configuration/storage#integrated-storage-vs-external-storage) way to configure storage for vault, you can edit this variable to enable any storage you want. Refer to the [vault documentation](https://developer.hashicorp.com/vault/docs/configuration/storage) for compatibility and syntax details about this variable.
Example:
```yaml
# MySQL storage configuration
vault_storage_configuration:
mysql:
address: "10.1.10.10:3006"
username: "vault"
password: "vault"
database: "vault"
```
### Listener settings
#### TCP listeners
By default, TLS is **disabled** for vault. This goes against the Hashicorp recommendations on the matter, but there is no simple way to force the use of TLS (yet), without adding a lot of complexity to the deployment.
The listener configuration settings can be modified in `vault_listener_configuration` variable.
```yaml
vault_listener_configuration:
tcp:
address: "0.0.0.0:8200"
tls_disable: true
```
By default, vault will listen on all interfaces, on port 8200. you can change it by modifying the `tcp.address` property, and adding you own listener preferences.
#### Enabling TLS for Vault
In order to enable TLS for Vault, you simply need to set the `vault_enable_tls` variable to `true`.
At the moment, hashistack-Ansible does nothing to help you generate the certificates and renew them. All it does is look inside the `etc/hashistack/vault_servers/tls` directory on the deployment node, and copy the files to the destination hosts in `/etc/vault.d/config/tls`. The listener expect **2 files** by default, a `cert.pem`, and a `key.pem` file.
Please refer to the [vault documentation](https://developer.hashicorp.com/vault/docs/configuration/listener/tcp) for details bout enabling TLS on vault listeners.
In case you want to add more configuration to the vault listeners, you can add it to the `vault_extra_listener_configuration` variable, which by default is empty. This variable will be merge with the rest ofthe listener configuration variables, and takes precedence over all the others.
> **Waring**
> At the moment, hashistack-ansible does not support setting up multiple TCP listeners. Only one can be set.
### Plugins for Vault
To enable plugin support for Vault, you can set the `vault_enable_plugins` variable to true. This variable will add the necessary configuration options in the vault.json file to enable support. Once enabled, you can simply place your compiled plugin files into the `etc/hashistack/vault_servers/plugin` directory. They will be copied over to the `/etc/vault.d/config/plugin` directory on the target nodes.
Refer to the [vault documentation](https://developer.hashicorp.com/vault/docs/plugins/plugin-management) for details about enabling and using plugins.

View File

@ -21,7 +21,8 @@ issues: http://example.com/issue/tracker
# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This # artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This
# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', # uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry',
# and '.git' are always filtered. Mutually exclusive with 'manifest' # and '.git' are always filtered. Mutually exclusive with 'manifest'
build_ignore: [] build_ignore:
- assets/*
# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a # A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a
# list of MANIFEST.in style # list of MANIFEST.in style
# L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key # L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key

View File

@ -1,12 +1,6 @@
--- ---
# Molecule specific variables # Molecule specific variables
hashistack_ca_action: "root_ca,int_ca,leaf_cert,renew_root,"
hashistack_ca_directory: "{{ hashistack_sub_configuration_directories['certificates'] }}"
hashistack_ca_directory_owner: "{{ lookup('env', 'USER') }}"
hashistack_ca_domain: ednz.lab
hashistack_ca_intermediate_name_constraints_critical: false
########################## ##########################
# General options ######## # General options ########
########################## ##########################
@ -37,14 +31,14 @@ api_interface: "eth1"
# external tls options # # external tls options #
######################## ########################
enable_tls_external: true # enable_tls_external: false
# external_tls_externally_managed_certs: false # external_tls_externally_managed_certs: false
######################## ########################
# internal tls options # # internal tls options #
######################## ########################
enable_tls_internal: true # enable_tls_internal: false
# internal_tls_externally_managed_certs: false # internal_tls_externally_managed_certs: false
##################################################### #####################################################

View File

@ -1,8 +0,0 @@
---
nomad_client_configuration:
enabled: "{{ nomad_enable_client }}"
state_dir: "{{ nomad_data_dir }}/client"
cni_path: "{{ cni_plugins_install_path | default('/opt/cni/bin') }}"
bridge_network_name: nomad
bridge_network_subnet: "172.26.64.0/20"
node_pool: ingress

View File

@ -1,6 +1,6 @@
--- ---
- name: Include certificate generation playbook - name: Include certificate generation playbook
ansible.builtin.import_playbook: ednz_cloud.hashistack.generate_certs.yml ansible.builtin.import_playbook: ednz_cloud.hashistack.certificates.yml
- name: Include bootstrap playbook - name: Include bootstrap playbook
ansible.builtin.import_playbook: ednz_cloud.hashistack.bootstrap.yml ansible.builtin.import_playbook: ednz_cloud.hashistack.bootstrap.yml

View File

@ -0,0 +1,3 @@
---
- name: Include a playbook from a collection
ansible.builtin.import_playbook: ednz_cloud.hashistack.deploy.yml

View File

@ -0,0 +1,299 @@
---
# Molecule specific variables
hashistack_ca_action: "root_ca,int_ca,leaf_cert,renew_root"
hashistack_ca_directory: "{{ hashistack_sub_configuration_directories['certificates'] }}"
hashistack_ca_directory_owner: "{{ lookup('env', 'USER') }}"
hashistack_ca_domain: ednz.lab
hashistack_ca_intermediate_name_constraints_critical: false
##########################
# General options ########
##########################
# enable_haproxy: "yes"
# enable_vault: "yes"
# enable_consul: "yes"
# enable_nomad: "yes"
# haproxy_version: "2.8"
nomad_version: "1.8.3"
# consul_version: "1.18.1"
vault_version: "1.17.2"
# consul_fqdn: consul.ednz.lab
# vault_fqdn: vault.ednz.lab
# nomad_fqdn: nomad.ednz.lab
# hashistack_external_vip_interface: "eth0"
# hashistack_external_vip_addr: "192.168.121.100"
# hashistack_internal_vip_interface: "{{ hashistack_external_vip_interface }}"
# hashistack_internal_vip_addr: "{{ hashistack_external_vip_addr }}"
api_interface: "eth1"
# api_interface_address: "{{ ansible_facts[api_interface]['ipv4']['address'] }}"
########################
# external tls options #
########################
enable_tls_external: true
# external_tls_externally_managed_certs: false
########################
# internal tls options #
########################
enable_tls_internal: true
# internal_tls_externally_managed_certs: false
#####################################################
# #
# Consul #
# #
#####################################################
# consul_domain: consul
# consul_datacenter: dc1
# consul_primary_datacenter: dc1
# consul_leave_on_terminate: true
# consul_rejoin_after_leave: true
# consul_enable_script_checks: true
# consul_gossip_encryption_key: "{{ 'mysupersecretgossipencryptionkey'|b64encode }}"
################################
# consul address configuration #
################################
# consul_address_configuration:
# # The address to which Consul will bind client interfaces,
# # including the HTTP and DNS servers.
# client_addr: "0.0.0.0"
# # The address that should be bound to for internal cluster communications.
# bind_addr: "{{ api_interface_address }}"
# # The advertise address is used to change the address that we advertise to other nodes in the cluster.
# advertise_addr: "{{ api_interface_address }}"
############################
# consul ACL configuration #
############################
# consul_acl_configuration:
# enabled: true
# default_policy: "deny" # can be allow or deny
# enable_token_persistence: true
############################
# consul DNS configuration #
############################
# consul_dns_configuration:
# allow_stale: true
# enable_truncate: true
# only_passing: true
###########################
# consul ui configuration #
###########################
# consul_ui_configuration:
# enabled: "{{ 'consul_servers' in group_names }}"
#####################################
# consul service mesh configuration #
#####################################
# consul_mesh_configuration:
# enabled: true
############################
# consul tls configuration #
############################
# consul_enable_tls: "{{ enable_tls_internal }}"
# consul_tls_configuration:
# defaults:
# ca_file: "/etc/ssl/certs/ca-certificates.crt"
# cert_file: "{{ consul_certificates_directory }}/cert.pem"
# key_file: "{{ consul_certificates_directory }}/key.pem"
# verify_incoming: false
# verify_outgoing: true
# internal_rpc:
# verify_server_hostname: true
############################
# consul container volumes #
############################
# extra_consul_container_volumes: []
##############################
# consul extra configuration #
##############################
# consul_extra_configuration: {}
# consul_extra_files_list: []
#####################################################
# #
# Vault #
# #
#####################################################
# vault_cluster_name: vault
# vault_enable_ui: true
# vault_seal_configuration:
# key_shares: 3
# key_threshold: 2
#################
# vault storage #
#################
# vault_storage_configuration:
# raft:
# path: "{{ hashicorp_vault_data_dir }}/data"
# node_id: "{{ ansible_hostname }}"
# retry_join: |
# [
# {% for host in groups['vault_servers'] %}
# {
# 'leader_api_addr': '{{ "https" if vault_enable_tls else "http"}}://{{ hostvars[host].api_interface_address }}:8200'
# }{% if not loop.last %},{% endif %}
# {% endfor %}
# ]
##################
# vault listener #
##################
# vault_enable_tls: "{{ enable_tls_internal }}"
# vault_tls_verify: false
# vault_listener_configuration:
# tcp:
# address: "0.0.0.0:8200"
# tls_disable: true
# vault_tls_listener_configuration:
# tcp:
# tls_disable: false
# tls_cert_file: "{{ vault_certificates_directory }}/cert.pem"
# tls_key_file: "{{ vault_certificates_directory }}/key.pem"
# tls_disable_client_certs: true
# vault_extra_listener_configuration: {}
########################
# service registration #
########################
# vault_enable_service_registration: false
# vault_service_registration_configuration:
# consul:
# address: "127.0.0.1:8500"
# scheme: "http"
# token: ""
#################
# vault plugins #
#################
# vault_enable_plugins: false
###########
# logging #
###########
# vault_enable_log_to_file: false
# vault_logging_configuration:
# log_level: info
# log_format: standard
# log_rotate_duration: 24h
# log_rotate_max_files: 30
###########################
# vault container volumes #
###########################
# extra_vault_container_volumes: []
#############################
# vault extra configuration #
#############################
# vault_extra_configuration: {}
# vault_extra_files_list: []
#####################################################
# #
# Nomad #
# #
#####################################################
# nomad_datacenter: dc1
# nomad_region: global
###########################
# nomad ACL configuration #
###########################
# nomad_acl_configuration:
# enabled: true
# token_ttl: 30s
# policy_ttl: 60s
# role_ttl: 60s
############################
# nomad consul integration #
############################
# nomad_enable_consul_integration: "{{ enable_consul | bool }}"
# nomad_consul_integration_configuration:
# address: "127.0.0.1:{{ hashicorp_consul_configuration.ports.https if consul_enable_tls else hashicorp_consul_configuration.ports.http }}"
# auto_advertise: true
# ssl: "{{ consul_enable_tls | bool }}"
# token: "{{ _credentials.consul.tokens.nomad.server.secret_id if nomad_enable_server else _credentials.consul.tokens.nomad.client.secret_id}}"
# tags: []
############################
# nomad vault integration #
############################
# nomad_enable_vault_integration: false
# nomad_vault_integration_configuration: {}
###############################
# nomad drivers configuration #
###############################
# nomad_driver_enable_docker: yes
# nomad_driver_enable_podman: no
# nomad_driver_enable_raw_exec: no
# nomad_driver_enable_java: no
# nomad_driver_enable_qemu: no
# nomad_driver_extra_configuration: {}
######################
# nomad internal tls #
######################
# nomad_enable_tls: "{{ enable_tls_internal }}"
# nomad_tls_configuration:
# http: true
# rpc: true
# ca_file: "/etc/ssl/certs/ca-certificates.crt"
# cert_file: "{{ nomad_certificates_directory }}/cert.pem"
# key_file: "{{ nomad_certificates_directory }}/key.pem"
# verify_server_hostname: true
# nomad_certificates_directory: "{{ hashicorp_nomad_config_dir }}/tls"
# nomad_certificates_extra_files_dir:
# - src: "{{ hashistack_sub_configuration_directories['certificates'] }}/nomad/{{ inventory_hostname }}"
# dest: "{{ nomad_certificates_directory }}"
#############################
# nomad extra configuration #
#############################
# nomad_extra_configuration: {}
# nomad_extra_files_list: []

View File

@ -0,0 +1,116 @@
---
dependency:
name: galaxy
options:
requirements-file: ./requirements.yml
driver:
name: vagrant
provider:
name: libvirt
platforms:
- name: proxy01.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 2
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.91
auto_config: true
type: static
groups:
- common
- haproxy_servers
- nomad_clients
- consul_agents
- name: proxy02.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 2
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.92
auto_config: true
type: static
groups:
- common
- haproxy_servers
- nomad_clients
- consul_agents
- name: hashistack01.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 4
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.101
auto_config: true
type: static
groups:
- common
- vault_servers
- consul_servers
- nomad_servers
- nomad_clients
- name: hashistack02.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 4
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.102
auto_config: true
type: static
groups:
- common
- vault_servers
- consul_servers
- nomad_servers
- nomad_clients
- name: hashistack03.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 4
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.103
auto_config: true
type: static
groups:
- common
- vault_servers
- consul_servers
- nomad_servers
- nomad_clients
- name: hashistack04.ednz.lab
box: generic/${MOLECULE_TEST_OS}
cpus: 4
memory: 2048
interfaces:
- network_name: private_network
ip: 192.168.100.104
auto_config: true
type: static
groups:
- common
- nomad_clients
- consul_agents
provisioner:
name: ansible
config_options:
defaults:
remote_tmp: /tmp/.ansible
verifier:
name: ansible
scenario:
name: tls_multi_node
test_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- idempotence
- verify
- cleanup
- destroy

View File

@ -0,0 +1,9 @@
---
- name: Include certificate generation playbook
ansible.builtin.import_playbook: ednz_cloud.hashistack.certificates.yml
- name: Include bootstrap playbook
ansible.builtin.import_playbook: ednz_cloud.hashistack.bootstrap.yml
- name: Include preflight playbook
ansible.builtin.import_playbook: ednz_cloud.hashistack.preflight.yml

View File

@ -0,0 +1,10 @@
---
# requirements file for molecule
roles:
- name: ednz_cloud.manage_repositories
- name: ednz_cloud.manage_apt_packages
- name: ednz_cloud.manage_pip_packages
- name: ednz_cloud.install_docker
collections:
- name: ednz_cloud.hashistack

View File

@ -0,0 +1,6 @@
---
- name: Verify
hosts: all
gather_facts: true
become: true
tasks: []

View File

@ -10,6 +10,9 @@
- name: "Import variables" - name: "Import variables"
ansible.builtin.include_role: ansible.builtin.include_role:
name: ednz_cloud.hashistack.hashistack name: ednz_cloud.hashistack.hashistack
apply:
tags:
- always
tags: tags:
- always - always
@ -17,39 +20,39 @@
- name: "Deploy Consul" - name: "Deploy Consul"
tags: tags:
- consul - consul
- consul_servers
- consul_agents
when: when:
- enable_consul | bool - enable_consul | bool
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
file: tasks/consul/consul_deploy.yml file: tasks/consul/consul_deploy.yml
apply:
tags:
- consul
# Vault nodes deployment # Vault nodes deployment
- name: "Deploy Vault" - name: "Deploy Vault"
tags: tags:
- vault - vault
- vault_servers
when: when:
- enable_vault | bool - enable_vault | bool
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
file: tasks/vault/vault_deploy.yml file: tasks/vault/vault_deploy.yml
apply:
tags:
- vault
# Nomad nodes deployment # Nomad nodes deployment
- name: "Deploy Nomad" - name: "Deploy Nomad"
tags: tags:
- nomad - nomad
- nomad_servers
- nomad_clients
when: when:
- enable_nomad | bool - enable_nomad | bool
ansible.builtin.include_tasks: ansible.builtin.include_tasks:
file: tasks/nomad/nomad_deploy.yml file: tasks/nomad/nomad_deploy.yml
apply:
# - fail: tags:
# Haproxy nodes deployment - nomad
# - name: "Deploy Proxies"
# tags:
# - haproxy
# when:
# - enable_haproxy | bool
# block:
# - name: "Deploy Haproxy & Keepalived"
# ansible.builtin.import_tasks:
# file: tasks/haproxy/haproxy_deploy.yml
# when:
# - "'haproxy_servers' in group_names"

View File

@ -42,3 +42,36 @@ consul_required_ports: [8300, 8301, 8302, 8500, 8501, 8502, 8503, 8600]
nomad_required_ports: [4646, 4647, 4648] nomad_required_ports: [4646, 4647, 4648]
target: all, !deployment target: all, !deployment
#############################################################
# consul -- DO NOT TWEAK UNLESS YOU KNOW WHAT YOU ARE DOING #
#############################################################
consul_init_server: "{{ (inventory_hostname == groups['consul_servers'][0]) | bool }}"
consul_api_addr: "{{ consul_api_scheme }}://{{ api_interface_address }}:{{ consul_api_port[consul_api_scheme] }}"
consul_api_scheme: "{{ 'https' if consul_enable_tls else 'http' }}"
consul_api_port:
http: 8500
https: 8501
consul_grpc_port:
http: 8502
https: 8503
############################################################
# nomad -- DO NOT TWEAK UNLESS YOU KNOW WHAT YOU ARE DOING #
############################################################
nomad_init_server: "{{ (inventory_hostname == groups['nomad_servers'][0]) | bool }}"
nomad_api_addr: "{{ nomad_api_scheme }}://{{ api_interface_address }}:{{ nomad_api_port[nomad_api_scheme] }}"
nomad_api_scheme: "{{ 'https' if nomad_enable_tls else 'http' }}"
nomad_api_port:
http: "{{ nomad_address_configuration.ports.http }}"
https: "{{ nomad_address_configuration.ports.http }}"
############################################################
# vault -- DO NOT TWEAK UNLESS YOU KNOW WHAT YOU ARE DOING #
############################################################
vault_init_server: "{{ (inventory_hostname == groups['vault_servers'][0]) | bool }}"

View File

@ -1,19 +1,4 @@
--- ---
consul_init_server: "{{ (inventory_hostname == groups['consul_servers'][0]) | bool }}"
#####################
# consul api config #
#####################
consul_api_addr: "{{ consul_api_scheme }}://{{ api_interface_address }}:{{ consul_api_port[consul_api_scheme] }}"
consul_api_scheme: "{{ 'https' if consul_enable_tls else 'http' }}"
consul_api_port:
http: 8500
https: 8501
consul_grpc_port:
http: 8502
https: 8503
########## ##########
# Consul # # Consul #
########## ##########

View File

@ -3,7 +3,6 @@
# General options # # General options #
################### ###################
enable_ingress: "yes"
enable_vault: "yes" enable_vault: "yes"
enable_consul: "yes" enable_consul: "yes"
enable_nomad: "yes" enable_nomad: "yes"
@ -16,11 +15,6 @@ consul_fqdn: consul.ednz.lab
vault_fqdn: vault.ednz.lab vault_fqdn: vault.ednz.lab
nomad_fqdn: nomad.ednz.lab nomad_fqdn: nomad.ednz.lab
# hashistack_external_vip_interface: "eth0"
# hashistack_external_vip_addr: "192.168.121.100"
# hashistack_internal_vip_interface: "{{ hashistack_external_vip_interface }}"
# hashistack_internal_vip_addr: "{{ hashistack_external_vip_addr }}"
api_interface: "eth0" api_interface: "eth0"
api_interface_address: "{{ ansible_facts[api_interface]['ipv4']['address'] }}" api_interface_address: "{{ ansible_facts[api_interface]['ipv4']['address'] }}"

View File

@ -1,16 +1,4 @@
--- ---
nomad_init_server: "{{ (inventory_hostname == groups['nomad_servers'][0]) | bool }}"
####################
# nomad api config #
####################
nomad_api_addr: "{{ nomad_api_scheme }}://{{ api_interface_address }}:{{ nomad_api_port[nomad_api_scheme] }}"
nomad_api_scheme: "{{ 'https' if nomad_enable_tls else 'http' }}"
nomad_api_port:
http: "{{ nomad_address_configuration.ports.http }}"
https: "{{ nomad_address_configuration.ports.http }}"
######### #########
# Nomad # # Nomad #
######### #########
@ -99,6 +87,12 @@ nomad_client_configuration:
cni_path: "{{ cni_plugins_install_path | default('/opt/cni/bin') }}" cni_path: "{{ cni_plugins_install_path | default('/opt/cni/bin') }}"
bridge_network_name: nomad bridge_network_name: nomad
bridge_network_subnet: "172.26.64.0/20" bridge_network_subnet: "172.26.64.0/20"
node_pool: >-
{{
'ingress' if 'nomad_ingress' in group_names else
'controller' if 'nomad_servers' in group_names else
omit
}}
#################### ####################
# ui configuration # # ui configuration #
@ -148,7 +142,7 @@ nomad_acl_configuration:
# internal tls # # internal tls #
################ ################
nomad_enable_tls: false # nomad_enable_tls: false
nomad_tls_configuration: nomad_tls_configuration:
http: true http: true
rpc: true rpc: true

View File

@ -1,6 +1,4 @@
--- ---
vault_init_server: "{{ (inventory_hostname == groups['vault_servers'][0]) | bool }}"
######### #########
# Vault # # Vault #
######### #########

View File

@ -1,7 +1,3 @@
[haproxy_servers]
haproxy01
haproxy02
[vault_servers] [vault_servers]
vault01 vault01
vault02 vault02
@ -25,7 +21,6 @@ nomad-client03
[consul_agents] [consul_agents]
[consul_agents:children] [consul_agents:children]
haproxy_servers
vault_servers vault_servers
nomad_servers nomad_servers
nomad_clients nomad_clients
@ -45,7 +40,6 @@ nomad_clients
vault_servers vault_servers
[common:children] [common:children]
haproxy_servers
vault_servers vault_servers
consul_servers consul_servers
nomad_servers nomad_servers

View File

@ -57,27 +57,6 @@
path: "{{ hashistack_configuration_directory }}" path: "{{ hashistack_configuration_directory }}"
register: _stat_config_dir register: _stat_config_dir
- name: "Stat nomad_servers config directory"
ansible.builtin.stat:
path: "{{ hashistack_sub_configuration_directories.nomad_servers }}"
register: _stat_config_dir_nomad_servers
when:
- enable_nomad | bool
- name: "Stat consul_servers config directory"
ansible.builtin.stat:
path: "{{ hashistack_sub_configuration_directories.consul_servers }}"
register: _stat_config_dir_consul_servers
when:
- enable_consul | bool
- name: "Stat vault_servers config directory"
ansible.builtin.stat:
path: "{{ hashistack_sub_configuration_directories.vault_servers }}"
register: _stat_config_dir_vault_servers
when:
- enable_vault | bool
- name: "Make sure directory exists: {{ hashistack_configuration_directory }}" - name: "Make sure directory exists: {{ hashistack_configuration_directory }}"
ansible.builtin.assert: ansible.builtin.assert:
that: that:
@ -85,33 +64,6 @@
- _stat_config_dir.stat.isdir - _stat_config_dir.stat.isdir
- _stat_config_dir.stat.writeable - _stat_config_dir.stat.writeable
- name: "Make sure directory exists: {{ hashistack_sub_configuration_directories.nomad_servers }}"
ansible.builtin.assert:
that:
- _stat_config_dir_nomad_servers.stat.exists
- _stat_config_dir_nomad_servers.stat.isdir
- _stat_config_dir_nomad_servers.stat.writeable
when:
- enable_nomad | bool
- name: "Make sure directory exists: {{ hashistack_sub_configuration_directories.consul_servers }}"
ansible.builtin.assert:
that:
- _stat_config_dir_consul_servers.stat.exists
- _stat_config_dir_consul_servers.stat.isdir
- _stat_config_dir_consul_servers.stat.writeable
when:
- enable_consul | bool
- name: "Make sure directory exists: {{ hashistack_sub_configuration_directories.vault_servers }}"
ansible.builtin.assert:
that:
- _stat_config_dir_vault_servers.stat.exists
- _stat_config_dir_vault_servers.stat.isdir
- _stat_config_dir_vault_servers.stat.writeable
when:
- enable_vault | bool
- name: "Checking host OS distribution" - name: "Checking host OS distribution"
# TODO: This needs to work with debian and ubuntu, major version works for debian but not ubuntu, simple version works the other way around... # TODO: This needs to work with debian and ubuntu, major version works for debian but not ubuntu, simple version works the other way around...
# ? seems to work # ? seems to work

View File

@ -67,15 +67,29 @@
state: present state: present
when: _consul_nomad_client_policy.changed when: _consul_nomad_client_policy.changed
- name: "Include ednz_cloud.hashistack.cni" - name: "Nomad | Include ednz_cloud.hashistack.cni"
ansible.builtin.include_role: ansible.builtin.include_role:
name: ednz_cloud.hashistack.cni name: ednz_cloud.hashistack.cni
when: nomad_enable_client when: nomad_enable_client
- name: "Include ednz_cloud.hashistack.nomad" - name: "Nomad | Include ednz_cloud.hashistack.nomad"
ansible.builtin.include_role: ansible.builtin.include_role:
name: ednz_cloud.hashistack.nomad name: ednz_cloud.hashistack.nomad
- name: "Nomad | Wait for nomad cluster to initialize"
ansible.builtin.uri:
url: "{{ nomad_api_addr }}/v1/status/leader"
return_content: true
validate_certs: false
status_code:
- 200
until: nomad_api_response.status == 200
retries: 24
delay: 5
register: nomad_api_response
when:
- nomad_init_server
- name: "Nomad | Initialize nomad cluster" # noqa: run-once[task] - name: "Nomad | Initialize nomad cluster" # noqa: run-once[task]
ednz_cloud.hashistack.nomad_acl_bootstrap: ednz_cloud.hashistack.nomad_acl_bootstrap:
bootstrap_secret: "{{ _credentials.nomad.root_token.secret_id }}" bootstrap_secret: "{{ _credentials.nomad.root_token.secret_id }}"

13
roles/consul/.docsible Normal file
View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

227
roles/consul/README.md Normal file
View File

@ -0,0 +1,227 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## consul
Description: Install and configure hashicorp consul for debian-based distros.
| Field | Value |
|--------------------- |-----------------|
| Readme update | 26/08/2024 |
### Defaults
**These are static variables with lower priority**
#### File: defaults/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [consul_version](defaults/main.yml#L4) | str | `latest` | n/a | n/a |
| [consul_start_service](defaults/main.yml#L5) | bool | `True` | n/a | n/a |
| [consul_config_dir](defaults/main.yml#L6) | str | `/etc/consul.d` | n/a | n/a |
| [consul_data_dir](defaults/main.yml#L7) | str | `/opt/consul` | n/a | n/a |
| [consul_certs_dir](defaults/main.yml#L8) | str | `{{ consul_config_dir }}/tls` | n/a | n/a |
| [consul_logs_dir](defaults/main.yml#L9) | str | `/var/log/consul` | n/a | n/a |
| [consul_envoy_install](defaults/main.yml#L11) | bool | `False` | n/a | n/a |
| [consul_envoy_version](defaults/main.yml#L12) | str | `latest` | n/a | n/a |
| [consul_extra_files](defaults/main.yml#L14) | bool | `False` | n/a | n/a |
| [consul_extra_files_list](defaults/main.yml#L15) | list | `[]` | n/a | n/a |
| [consul_env_variables](defaults/main.yml#L17) | dict | `{}` | n/a | n/a |
| [consul_extra_configuration](defaults/main.yml#L28) | dict | `{}` | n/a | n/a |
| [consul_domain](defaults/main.yml#L34) | str | `consul` | n/a | n/a |
| [consul_datacenter](defaults/main.yml#L35) | str | `dc1` | n/a | n/a |
| [consul_primary_datacenter](defaults/main.yml#L36) | str | `{{ consul_datacenter }}` | n/a | n/a |
| [consul_gossip_encryption_key](defaults/main.yml#L37) | str | `{{ 'mysupersecretgossipencryptionkey'\|b64encode }}` | n/a | n/a |
| [consul_enable_script_checks](defaults/main.yml#L38) | bool | `False` | n/a | n/a |
| [consul_leave_on_terminate](defaults/main.yml#L44) | bool | `True` | n/a | n/a |
| [consul_rejoin_after_leave](defaults/main.yml#L45) | bool | `True` | n/a | n/a |
| [consul_join_configuration](defaults/main.yml#L51) | dict | `{'retry_join': ['{{ ansible_default_ipv4.address }}'], 'retry_interval': '30s', 'retry_max': 0}` | n/a | n/a |
| [consul_enable_server](defaults/main.yml#L61) | bool | `True` | n/a | n/a |
| [consul_bootstrap_expect](defaults/main.yml#L62) | int | `1` | n/a | n/a |
| [consul_ui_configuration](defaults/main.yml#L68) | dict | `{'enabled': '{{ consul_enable_server }}'}` | n/a | n/a |
| [consul_bind_addr](defaults/main.yml#L75) | str | `0.0.0.0` | n/a | n/a |
| [consul_advertise_addr](defaults/main.yml#L76) | str | `{{ ansible_default_ipv4.address }}` | n/a | n/a |
| [consul_address_configuration](defaults/main.yml#L77) | dict | `{'client_addr': '{{ consul_bind_addr }}', 'bind_addr': '{{ consul_advertise_addr }}', 'advertise_addr': '{{ consul_advertise_addr }}'}` | n/a | n/a |
| [consul_acl_configuration](defaults/main.yml#L86) | dict | `{'enabled': False, 'default_policy': 'deny', 'enable_token_persistence': True}` | n/a | n/a |
| [consul_mesh_configuration](defaults/main.yml#L97) | dict | `{'enabled': False}` | n/a | n/a |
| [consul_dns_configuration](defaults/main.yml#L104) | dict | `{'allow_stale': True, 'enable_truncate': True, 'only_passing': True}` | n/a | n/a |
| [consul_enable_tls](defaults/main.yml#L113) | bool | `False` | n/a | n/a |
| [consul_tls_configuration](defaults/main.yml#L114) | dict | `{'defaults': {'ca_file': '/etc/ssl/certs/ca-certificates.crt', 'cert_file': '{{ consul_certs_dir }}/cert.pem', 'key_file': '{{ consul_certs_dir }}/key.pem', 'verify_incoming': False, 'verify_outgoing': True}, 'internal_rpc': {'verify_server_hostname': True}}` | n/a | n/a |
| [consul_certificates_extra_files_dir](defaults/main.yml#L124) | list | `[]` | n/a | n/a |
| [consul_enable_prometheus_metrics](defaults/main.yml#L133) | bool | `False` | n/a | n/a |
| [consul_prometheus_retention_time](defaults/main.yml#L134) | str | `60s` | n/a | n/a |
| [consul_telemetry_configuration](defaults/main.yml#L135) | dict | `{}` | n/a | n/a |
| [consul_log_level](defaults/main.yml#L141) | str | `info` | n/a | n/a |
| [consul_enable_log_to_file](defaults/main.yml#L142) | bool | `False` | n/a | n/a |
| [consul_log_to_file_configuration](defaults/main.yml#L143) | dict | `{'log_file': '{{ consul_logs_dir }}/consul.log', 'log_rotate_duration': '24h', 'log_rotate_max_files': 30}` | n/a | n/a |
### Vars
**These are variables with higher priority**
#### File: vars/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [consul_user](vars/main.yml#L3) | str | `consul` | n/a | n/a |
| [consul_group](vars/main.yml#L4) | str | `consul` | n/a | n/a |
| [consul_binary_path](vars/main.yml#L5) | str | `/usr/local/bin/consul` | n/a | n/a |
| [consul_envoy_binary_path](vars/main.yml#L6) | str | `/usr/local/bin/envoy` | n/a | n/a |
| [consul_deb_architecture_map](vars/main.yml#L7) | dict | `{'x86_64': 'amd64', 'aarch64': 'arm64', 'armv7l': 'arm', 'armv6l': 'arm'}` | n/a | n/a |
| [consul_envoy_architecture_map](vars/main.yml#L12) | dict | `{'x86_64': 'x86_64', 'aarch64': 'aarch64'}` | n/a | n/a |
| [consul_architecture](vars/main.yml#L15) | str | `{{ consul_deb_architecture_map[ansible_architecture] \| default(ansible_architecture) }}` | n/a | n/a |
| [consul_envoy_architecture](vars/main.yml#L16) | str | `{{ consul_envoy_architecture_map[ansible_architecture] \| default(ansible_architecture) }}` | n/a | n/a |
| [consul_service_name](vars/main.yml#L17) | str | `consul` | n/a | n/a |
| [consul_github_api](vars/main.yml#L18) | str | `https://api.github.com/repos` | n/a | n/a |
| [consul_envoy_github_project](vars/main.yml#L19) | str | `envoyproxy/envoy` | n/a | n/a |
| [consul_github_project](vars/main.yml#L20) | str | `hashicorp/consul` | n/a | n/a |
| [consul_github_url](vars/main.yml#L21) | str | `https://github.com` | n/a | n/a |
| [consul_repository_url](vars/main.yml#L22) | str | `https://releases.hashicorp.com/consul` | n/a | n/a |
| [consul_configuration](vars/main.yml#L24) | dict | `{'domain': '{{ consul_domain }}', 'datacenter': '{{ consul_datacenter }}', 'primary_datacenter': '{{ consul_primary_datacenter }}', 'data_dir': '{{ consul_data_dir }}', 'encrypt': '{{ consul_gossip_encryption_key }}', 'server': '{{ consul_enable_server }}', 'ui_config': '{{ consul_ui_configuration }}', 'connect': '{{ consul_mesh_configuration }}', 'leave_on_terminate': '{{ consul_leave_on_terminate }}', 'rejoin_after_leave': '{{ consul_rejoin_after_leave }}', 'enable_script_checks': '{{ consul_enable_script_checks }}', 'enable_syslog': True, 'acl': '{{ consul_acl_configuration }}', 'dns_config': '{{ consul_dns_configuration }}', 'log_level': '{{ consul_log_level }}', 'ports': {'dns': 8600, 'server': 8300, 'serf_lan': 8301, 'serf_wan': 8302, 'sidecar_min_port': 21000, 'sidecar_max_port': 21255, 'expose_min_port': 21500, 'expose_max_port': 21755}}` | n/a | n/a |
| [consul_configuration_string](vars/main.yml#L50) | str | `<multiline value>` | n/a | n/a |
| [consul_server_configuration_string](vars/main.yml#L57) | str | `<multiline value>` | n/a | n/a |
### Tasks
#### File: tasks/recursive_copy_extra_dirs.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Ensure destination directory exists | ansible.builtin.file | False |
| Consul \| Create extra directory sources | ansible.builtin.file | True |
| Consul \| Template extra directory sources | ansible.builtin.template | True |
#### File: tasks/merge_variables.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Merge stringified configuration | vars | False |
| Consul \| Merge server specific stringified configuration | vars | True |
| Consul \| Merge join configuration | vars | False |
| Consul \| Merge addresses configuration | vars | False |
| Consul \| Merge TLS configuration | block | True |
| Consul \| Merge TLS configuration | vars | False |
| Consul \| Add certificates directory to extra_files_dir | ansible.builtin.set_fact | False |
| Consul \| Merge extra configuration settings | vars | False |
| Consul \| Merge log to file configuration | vars | True |
| Consul \| Merge telemetry configuration | block | False |
| Consul \| Merge prometheus metrics configuration | vars | True |
| Consul \| Merge telemtry configuration | vars | False |
#### File: tasks/main.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Set reload-check & restart-check variable | ansible.builtin.set_fact | False |
| Consul \| Import merge_variables.yml | ansible.builtin.include_tasks | False |
| Consul \| Import prerequisites.yml | ansible.builtin.include_tasks | False |
| Consul \| Import install_envoy.yml | ansible.builtin.include_tasks | True |
| Consul \| Import install.yml | ansible.builtin.include_tasks | False |
| Consul \| Import configure.yml | ansible.builtin.include_tasks | False |
| Consul \| Populate service facts | ansible.builtin.service_facts | False |
| Consul \| Set restart-check variable | ansible.builtin.set_fact | True |
| Consul \| Enable service: {{ consul_service_name }} | ansible.builtin.service | False |
| Consul \| Reload systemd daemon | ansible.builtin.systemd | True |
| Consul \| Start service: {{ consul_service_name }} | ansible.builtin.service | True |
#### File: tasks/install.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Get latest release of consul | block | True |
| Consul \| Get latest consul release from github api | ansible.builtin.uri | False |
| Consul \| Set wanted consul version to latest tag | ansible.builtin.set_fact | False |
| Consul \| Set wanted consul version to {{ consul_version }} | ansible.builtin.set_fact | True |
| Consul \| Get current consul version | block | False |
| Consul \| Stat consul version file | ansible.builtin.stat | False |
| Consul \| Get current consul version | ansible.builtin.slurp | True |
| Consul \| Download and install consul binary | block | True |
| Consul \| Set consul package name to download | ansible.builtin.set_fact | False |
| Consul \| Download checksum file for consul archive | ansible.builtin.get_url | False |
| Consul \| Extract correct checksum from checksum file | ansible.builtin.command | False |
| Consul \| Parse the expected checksum | ansible.builtin.set_fact | False |
| Consul \| Download consul binary archive | ansible.builtin.get_url | False |
| Consul \| Create temporary directory for archive decompression | ansible.builtin.file | False |
| Consul \| Unpack consul archive | ansible.builtin.unarchive | False |
| Consul \| Copy consul binary to {{ consul_binary_path }} | ansible.builtin.copy | False |
| Consul \| Update consul version file | ansible.builtin.copy | False |
| Consul \| Set restart-check variable | ansible.builtin.set_fact | False |
| Consul \| Cleanup temporary directory | ansible.builtin.file | False |
| Consul \| Copy systemd service file for consul | ansible.builtin.template | False |
| Consul \| Set reload-check & restart-check variable | ansible.builtin.set_fact | True |
#### File: tasks/install_envoy.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Get release for envoy:{{ consul_envoy_version }} | vars | False |
| Consul \| Check if envoy is already installed | ansible.builtin.stat | False |
| Consul \| Check current envoy version | ansible.builtin.command | True |
| Consul \| Set facts for wanted envoy release | ansible.builtin.set_fact | True |
| Consul \| Set facts for current envoy release | ansible.builtin.set_fact | True |
| Consul \| Create envoy directory | ansible.builtin.file | False |
| Consul \| Install envoy | block | True |
| Consul \| Remove old compose binary if different | ansible.builtin.file | False |
| Consul \| Download and install envoy version:{{ consul_envoy_version }} | ansible.builtin.get_url | False |
| Consul \| Update version file | ansible.builtin.copy | False |
#### File: tasks/prerequisites.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Create group {{ consul_group }} | ansible.builtin.group | False |
| Consul \| Create user {{ consul_user }} | ansible.builtin.user | False |
| Consul \| Create directory {{ consul_config_dir }} | ansible.builtin.file | False |
| Consul \| Create directory {{ consul_data_dir}} | ansible.builtin.file | False |
| Consul \| Create directory {{ consul_certs_dir }} | ansible.builtin.file | False |
| Consul \| Create directory {{ consul_logs_dir }} | ansible.builtin.file | True |
#### File: tasks/configure.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul \| Create consul.env | ansible.builtin.template | False |
| Consul \| Copy consul.json template | ansible.builtin.template | False |
| Consul \| Set restart-check variable | ansible.builtin.set_fact | True |
| Consul \| Copy extra configuration files | block | True |
| Consul \| Get extra file types | ansible.builtin.stat | False |
| Consul \| Set list for file sources | vars | True |
| Consul \| Set list for directory sources | vars | True |
| Consul \| Template extra file sources | ansible.builtin.template | True |
| Consul \| Template extra directory sources | ansible.builtin.include_tasks | True |
## Author Information
Bertrand Lanson
#### License
license (BSD, MIT)
#### Minimum Ansible Version
2.10
#### Platforms
- **Ubuntu**: ['focal', 'jammy', 'noble']
- **Debian**: ['bullseye', 'bookworm']
<!-- DOCSIBLE END -->

View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

123
roles/hashistack/README.md Normal file
View File

@ -0,0 +1,123 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## hashistack
Description: Merge variables for the playbooks contained in ednz_cloud.hashistack collection
| Field | Value |
|--------------------- |-----------------|
| Readme update | 26/08/2024 |
### Defaults
**These are static variables with lower priority**
#### File: defaults/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [hashistack_configuration_directory](defaults/main.yml#L3) | str | `{{ lookup('env', 'PWD') }}/etc/hashistack` | n/a | n/a |
| [hashistack_sub_configuration_directories](defaults/main.yml#L4) | dict | `{'secrets': '{{ hashistack_configuration_directory }}/secrets', 'certificates': '{{ hashistack_configuration_directory }}/certificates', 'nomad_servers': '{{ hashistack_configuration_directory }}/nomad_servers', 'vault_servers': '{{ hashistack_configuration_directory }}/vault_servers', 'consul_servers': '{{ hashistack_configuration_directory }}/consul_servers'}` | n/a | n/a |
| [hashistack_configuration_global_vars_file](defaults/main.yml#L11) | str | `globals.yml` | n/a | n/a |
| [hashistack_configuration_credentials_vars_file](defaults/main.yml#L12) | str | `credentials.yml` | n/a | n/a |
| [hashistack_remote_config_dir](defaults/main.yml#L14) | str | `/etc/hashistack` | n/a | n/a |
| [hashistack_remote_log_dir](defaults/main.yml#L15) | str | `/var/log/hashistack` | n/a | n/a |
| [hashistack_only_load_credentials](defaults/main.yml#L17) | bool | `False` | n/a | n/a |
### Tasks
#### File: tasks/load_group_vars.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Variables \| Stat group specific config file | ansible.builtin.stat | False |
| Variables \| Load group specific variables | ansible.builtin.include_vars | True |
#### File: tasks/load_credentials_vars.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Variables \| Stat credentials file | ansible.builtin.stat | False |
| Variables \| Stat vault credentials file | ansible.builtin.stat | False |
| Variables \| Make sure credentials file exists | ansible.builtin.assert | False |
| Variables \| Load credentials variables | ansible.builtin.include_vars | False |
| Variables \| Load vault credentials if vault.yml exists | ansible.builtin.include_vars | True |
| Variables \| Merge vault credentials into _credentials | vars | True |
#### File: tasks/load_host_vars.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Variables \| Stat host specific config file | ansible.builtin.stat | False |
| Variables \| Load host specific variables | ansible.builtin.include_vars | True |
#### File: tasks/main.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Variables \| Load global variables | ansible.builtin.include_tasks | True |
| Variables \| Load credentials variables | ansible.builtin.include_tasks | False |
| Variables \| Load group specific variables | ansible.builtin.include_tasks | True |
| Variables \| Load host specific variables | ansible.builtin.include_tasks | True |
| Ensure remote directories exists | ansible.builtin.file | True |
| Variables \| Load custom CA certificates | ansible.builtin.include_tasks | True |
#### File: tasks/load_ca_certificates.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Check if CA directory exists | ansible.builtin.stat | False |
| Find custom ca certificates to copy | ansible.builtin.find | True |
| Ensure remote ca directory exists | ansible.builtin.file | False |
| Copy custom ca certificates | ansible.builtin.copy | True |
| Copy and update trust store | block | True |
| Copy ca certificates to /usr/local/share/ca-certificates | ansible.builtin.file | False |
| Update the trust store | ansible.builtin.command | True |
#### File: tasks/load_global_vars.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Variables \| Include all default variables | ansible.builtin.include_vars | False |
| Variables \| Stat global configuration file | ansible.builtin.stat | False |
| Variables \| Make sure global configuration file exists | ansible.builtin.assert | False |
| Variables \| Load global variables | ansible.builtin.include_vars | False |
## Author Information
Bertrand Lanson
#### License
license (BSD, MIT)
#### Minimum Ansible Version
2.10
#### Platforms
- **Ubuntu**: ['focal', 'jammy', 'noble']
- **Debian**: ['bullseye', 'bookworm']
<!-- DOCSIBLE END -->

View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

View File

@ -0,0 +1,313 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## hashistack_ca
Description: Not available.
| Field | Value |
|--------------------- |-----------------|
| Readme update | 26/08/2024 |
### Defaults
**These are static variables with lower priority**
#### File: defaults/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [hashistack_ca_directory](defaults/main.yml#L3) | str | `/etc/hashistack/certificates` | n/a | n/a |
| [hashistack_ca_use_cryptography](defaults/main.yml#L4) | bool | `False` | n/a | n/a |
| [hashistack_ca_action](defaults/main.yml#L5) | str | `noop` | n/a | n/a |
| [hashistack_ca_domain](defaults/main.yml#L6) | str | `example.com` | n/a | n/a |
| [hashistack_ca_directory_owner](defaults/main.yml#L7) | str | `root` | n/a | n/a |
| [hashistack_ca_root_org_name](defaults/main.yml#L12) | str | `EDNZ Cloud` | n/a | n/a |
| [hashistack_ca_root_country](defaults/main.yml#L13) | str | `FR` | n/a | n/a |
| [hashistack_ca_root_locality](defaults/main.yml#L14) | str | `Paris` | n/a | n/a |
| [hashistack_ca_root_common_name](defaults/main.yml#L15) | str | `{{ hashistack_ca_domain }} Root CA` | n/a | n/a |
| [hashistack_ca_root_email](defaults/main.yml#L16) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_root_key_usage](defaults/main.yml#L17) | list | `['keyCertSign', 'cRLSign']` | n/a | n/a |
| [hashistack_ca_root_key_usage_critical](defaults/main.yml#L20) | bool | `True` | n/a | n/a |
| [hashistack_ca_root_basic_constraints](defaults/main.yml#L21) | list | `['CA:TRUE']` | n/a | n/a |
| [hashistack_ca_root_basic_constraints_critical](defaults/main.yml#L23) | bool | `True` | n/a | n/a |
| [hashistack_ca_root_state_or_province_name](defaults/main.yml#L26) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_root_email_address](defaults/main.yml#L27) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_root_valid_for](defaults/main.yml#L30) | str | `1825d` | n/a | n/a |
| [hashistack_ca_root_renew_threshold](defaults/main.yml#L31) | str | `180d` | n/a | n/a |
| [hashistack_ca_intermediate_org_name](defaults/main.yml#L36) | str | `EDNZ Cloud Intermediate` | n/a | n/a |
| [hashistack_ca_intermediate_country](defaults/main.yml#L37) | str | `FR` | n/a | n/a |
| [hashistack_ca_intermediate_locality](defaults/main.yml#L38) | str | `Paris` | n/a | n/a |
| [hashistack_ca_intermediate_common_name](defaults/main.yml#L39) | str | `{{ hashistack_ca_domain }} Intermediate CA` | n/a | n/a |
| [hashistack_ca_intermediate_email](defaults/main.yml#L40) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_intermediate_key_usage](defaults/main.yml#L41) | list | `['keyCertSign', 'cRLSign']` | n/a | n/a |
| [hashistack_ca_intermediate_key_usage_critical](defaults/main.yml#L44) | bool | `True` | n/a | n/a |
| [hashistack_ca_intermediate_basic_constraints](defaults/main.yml#L45) | list | `['CA:TRUE', 'pathlen:0']` | n/a | n/a |
| [hashistack_ca_intermediate_basic_constraints_critical](defaults/main.yml#L48) | bool | `True` | n/a | n/a |
| [hashistack_ca_intermediate_state_or_province_name](defaults/main.yml#L51) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_intermediate_email_address](defaults/main.yml#L52) | NoneType | `None` | n/a | n/a |
| [hashistack_ca_intermediate_valid_for](defaults/main.yml#L55) | str | `365d` | n/a | n/a |
| [hashistack_ca_intermediate_renew_threshold](defaults/main.yml#L56) | str | `90d` | n/a | n/a |
| [hashistack_ca_intermediate_name_constraints_permitted](defaults/main.yml#L59) | list | `['DNS:.{{ hashistack_ca_domain }}', 'DNS:.nomad', 'DNS:.consul', 'DNS:localhost', 'IP:192.168.0.0/16', 'IP:172.16.0.0/16', 'IP:10.0.0.0/8', 'IP:127.0.0.0/8']` | n/a | n/a |
| [hashistack_ca_intermediate_name_constraints_critical](defaults/main.yml#L68) | str | `{{ (hashistack_ca_intermediate_name_constraints_permitted is defined and hashistack_ca_intermediate_name_constraints_permitted \| length > 0) }}` | n/a | n/a |
| [hashistack_ca_leaf_valid_for](defaults/main.yml#L74) | str | `90d` | n/a | n/a |
| [hashistack_ca_leaf_renew_threshold](defaults/main.yml#L75) | str | `30d` | n/a | n/a |
| [hashistack_ca_consul_org_name](defaults/main.yml#L80) | str | `{{ hashistack_ca_root_org_name }}` | n/a | n/a |
| [hashistack_ca_consul_common_name](defaults/main.yml#L81) | str | `{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_consul_csr_sans](defaults/main.yml#L82) | list | `['DNS:consul.service.consul', 'DNS:localhost', 'IP:127.0.0.1']` | n/a | n/a |
| [hashistack_ca_nomad_org_name](defaults/main.yml#L90) | str | `{{ hashistack_ca_root_org_name }}` | n/a | n/a |
| [hashistack_ca_nomad_common_name](defaults/main.yml#L91) | str | `{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_nomad_csr_sans](defaults/main.yml#L92) | list | `['DNS:server.global.nomad', 'DNS:client.global.nomad', 'DNS:nomad.service.consul', 'DNS:localhost', 'IP:127.0.0.1']` | n/a | n/a |
| [hashistack_ca_vault_org_name](defaults/main.yml#L102) | str | `{{ hashistack_ca_root_org_name }}` | n/a | n/a |
| [hashistack_ca_vault_common_name](defaults/main.yml#L103) | str | `{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_vault_csr_sans](defaults/main.yml#L104) | list | `['DNS:vault.service.consul', 'DNS:active.vault.service.consul', 'DNS:standby.vault.service.consul', 'DNS:localhost', 'IP:127.0.0.1']` | n/a | n/a |
### Vars
**These are variables with higher priority**
#### File: vars/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [hashistack_ca_action_list](vars/main.yml#L3) | str | `{{ hashistack_ca_action.split(',') }}` | n/a | n/a |
| [hashistack_ca_generate_root](vars/main.yml#L6) | str | `{{ 'root_ca' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_generate_intermediate](vars/main.yml#L7) | str | `{{ 'int_ca' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_generate_leaf](vars/main.yml#L8) | str | `{{ 'leaf_cert' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_renew_root](vars/main.yml#L9) | str | `{{ 'renew_root' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_renew_intermediate](vars/main.yml#L10) | str | `{{ 'renew_int' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_renew_leaf](vars/main.yml#L11) | str | `{{ 'renew_leaf' in hashistack_ca_action_list }}` | n/a | n/a |
| [hashistack_ca_public_dir](vars/main.yml#L13) | str | `{{ hashistack_ca_directory }}/ca` | n/a | n/a |
| [hashistack_ca_root_dir](vars/main.yml#L15) | str | `{{ hashistack_ca_directory }}/root` | n/a | n/a |
| [hashistack_ca_root_backup_dir](vars/main.yml#L16) | str | `{{ hashistack_ca_root_dir }}/backup` | n/a | n/a |
| [hashistack_ca_root_key_path](vars/main.yml#L17) | str | `{{ hashistack_ca_root_dir }}/ca.key` | n/a | n/a |
| [hashistack_ca_root_cert_path](vars/main.yml#L18) | str | `{{ hashistack_ca_root_dir }}/ca.crt` | n/a | n/a |
| [hashistack_ca_intermediate_dir](vars/main.yml#L20) | str | `{{ hashistack_ca_directory }}/intermediate` | n/a | n/a |
| [hashistack_ca_intermediate_backup_dir](vars/main.yml#L21) | str | `{{ hashistack_ca_intermediate_dir }}/backup` | n/a | n/a |
| [hashistack_ca_intermediate_key_path](vars/main.yml#L22) | str | `{{ hashistack_ca_intermediate_dir }}/ca.key` | n/a | n/a |
| [hashistack_ca_intermediate_csr_path](vars/main.yml#L23) | str | `{{ hashistack_ca_intermediate_dir }}/ca.csr` | n/a | n/a |
| [hashistack_ca_intermediate_cert_path](vars/main.yml#L24) | str | `{{ hashistack_ca_intermediate_dir }}/ca.crt` | n/a | n/a |
| [hashistack_ca_consul_dir](vars/main.yml#L26) | str | `{{ hashistack_ca_directory }}/consul/{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_consul_key_path](vars/main.yml#L27) | str | `{{ hashistack_ca_consul_dir }}/cert.key` | n/a | n/a |
| [hashistack_ca_consul_cert_path](vars/main.yml#L28) | str | `{{ hashistack_ca_consul_dir }}/cert.crt` | n/a | n/a |
| [hashistack_ca_consul_fullchain_path](vars/main.yml#L29) | str | `{{ hashistack_ca_consul_dir }}/fullchain.crt` | n/a | n/a |
| [hashistack_ca_nomad_dir](vars/main.yml#L31) | str | `{{ hashistack_ca_directory }}/nomad/{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_nomad_key_path](vars/main.yml#L32) | str | `{{ hashistack_ca_nomad_dir }}/cert.key` | n/a | n/a |
| [hashistack_ca_nomad_cert_path](vars/main.yml#L33) | str | `{{ hashistack_ca_nomad_dir }}/cert.crt` | n/a | n/a |
| [hashistack_ca_nomad_fullchain_path](vars/main.yml#L34) | str | `{{ hashistack_ca_nomad_dir }}/fullchain.crt` | n/a | n/a |
| [hashistack_ca_vault_dir](vars/main.yml#L36) | str | `{{ hashistack_ca_directory }}/vault/{{ inventory_hostname }}` | n/a | n/a |
| [hashistack_ca_vault_key_path](vars/main.yml#L37) | str | `{{ hashistack_ca_vault_dir }}/cert.key` | n/a | n/a |
| [hashistack_ca_vault_cert_path](vars/main.yml#L38) | str | `{{ hashistack_ca_vault_dir }}/cert.crt` | n/a | n/a |
| [hashistack_ca_vault_fullchain_path](vars/main.yml#L39) | str | `{{ hashistack_ca_vault_dir }}/fullchain.crt` | n/a | n/a |
### Tasks
#### File: tasks/prepare_ca_to_copy.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| CA \| Check if CA directory exists | ansible.builtin.stat | False |
| CA \| Find custom CA certificates to copy | ansible.builtin.find | True |
| CA \| Ensure public CA directory exists | ansible.builtin.file | False |
| CA \| Copy root CA certificates | ansible.builtin.copy | True |
#### File: tasks/main.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| CA \| Import generate_root.yml | ansible.builtin.include_tasks | True |
| CA \| Import generate_intermediate.yml | ansible.builtin.include_tasks | True |
| CA \| Import renew_root.yml | ansible.builtin.include_tasks | True |
| CA \| Import renew_intermediate.yml | ansible.builtin.include_tasks | True |
| CA \| Import prepare_ca_to_copy.yml | ansible.builtin.include_tasks | False |
| CA \| Import cleanup_backups.yml | ansible.builtin.include_tasks | False |
| Consul leaf certificates \| Import generate/generate_consul.yml | ansible.builtin.include_tasks | True |
| Nomad leaf certificates \| Import generate/generate_nomad.yml | ansible.builtin.include_tasks | True |
| Vault leaf certificates \| Import generate/generate_vault.yml | ansible.builtin.include_tasks | True |
| Consul leaf certificates \| Import renew_consul.yml | ansible.builtin.include_tasks | True |
#### File: tasks/cleanup_backups.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Cleanup \| Check if root CA backup directory exists | ansible.builtin.stat | False |
| Cleanup \| Check if intermediate CA backup directory exists | ansible.builtin.stat | False |
| Cleanup \| Root CA backups | block | True |
| Root CA \| Find root CA backup certificates | ansible.builtin.find | False |
| Root CA \| Check expiration for root CA backup certificates | when | True |
| Root CA \| Remove expired root CA backup certificates | when | True |
| Cleanup \| Intermediate CA backups | block | True |
| Intermediate CA \| Find intermediate CA backup certificates | ansible.builtin.find | False |
| Intermediate CA \| Check expiration for intermediate CA backup certificates | when | True |
| Intermediate CA \| Remove expired intermediate CA backup certificates | when | True |
#### File: tasks/generate/generate_consul.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul leaf certificates \| Create certificate directory in for consul servers | ansible.builtin.file | False |
| Consul leaf certificates \| Create Consul certificates | block | False |
| Consul leaf certificates \| Create Consul certificate keys | community.crypto.openssl_privatekey | False |
| Consul leaf certificates \| Create CSRs for Consul servers | community.crypto.openssl_csr_pipe | False |
| Consul leaf certificates \| Sign certificates with internal CA | community.crypto.x509_certificate | False |
| Consul leaf certificates \| Generate fullchain certificate | block | False |
| Consul leaf certificates \| Read content of root ca certificate | ansible.builtin.slurp | False |
| Consul leaf certificates \| Read content of intermediate ca certificate | ansible.builtin.slurp | False |
| Consul leaf certificates \| Read content of leaf certificate | ansible.builtin.slurp | False |
| Consul leaf certificates \| Concatenate certificates | ansible.builtin.copy | False |
#### File: tasks/generate/generate_intermediate.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Intermediate CA \| Create temporary cert directory in {{ hashistack_ca_directory }}/intermediate | ansible.builtin.file | False |
| Intermediate CA \| Generate internal certificates | block | False |
| Intermediate CA \| Create intermediate CA private key | community.crypto.openssl_privatekey | False |
| Intermediate CA \| Create intermediate CA signing request | community.crypto.openssl_csr_pipe | False |
| Intermediate CA \| Create signed intermediate CA certificate from CSR | community.crypto.x509_certificate | False |
#### File: tasks/generate/generate_nomad.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad leaf certificates \| Create certificate directory in for nomad servers | ansible.builtin.file | False |
| Nomad leaf certificates \| Create Nomad certificates | block | False |
| Nomad leaf certificates \| Create Nomad certificate keys | community.crypto.openssl_privatekey | False |
| Nomad leaf certificates \| Create CSRs for Nomad servers | community.crypto.openssl_csr_pipe | False |
| Nomad leaf certificates \| Sign certificates with internal CA | community.crypto.x509_certificate | False |
| Nomad leaf certificates \| Generate fullchain certificate | block | False |
| Nomad leaf certificates \| Read content of root ca certificate | ansible.builtin.slurp | False |
| Nomad leaf certificates \| Read content of intermediate ca certificate | ansible.builtin.slurp | False |
| Nomad leaf certificates \| Read content of leaf certificate | ansible.builtin.slurp | False |
| Nomad leaf certificates \| Concatenate certificates | ansible.builtin.copy | False |
#### File: tasks/generate/generate_vault.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault leaf certificates \| Create certificate directory in for vault servers | ansible.builtin.file | False |
| Vault leaf certificates \| Create Vault certificates | block | False |
| Vault leaf certificates \| Create Vault certificate keys | community.crypto.openssl_privatekey | False |
| Vault leaf certificates \| Create CSRs for Vault servers | community.crypto.openssl_csr_pipe | False |
| Vault leaf certificates \| Sign certificates with internal CA | community.crypto.x509_certificate | False |
| Vault leaf certificates \| Generate fullchain certificate | block | False |
| Vault leaf certificates \| Read content of root ca certificate | ansible.builtin.slurp | False |
| Vault leaf certificates \| Read content of intermediate ca certificate | ansible.builtin.slurp | False |
| Vault leaf certificates \| Read content of leaf certificate | ansible.builtin.slurp | False |
| Vault leaf certificates \| Concatenate certificates | ansible.builtin.copy | False |
#### File: tasks/generate/generate_root.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Root CA \| Create temporary cert directory in {{ hashistack_ca_directory }} | ansible.builtin.file | False |
| Root CA \| Generate root Authority | block | False |
| Root CA \| Create CA private key | community.crypto.openssl_privatekey | False |
| Root CA \| Create CA signing request | community.crypto.openssl_csr_pipe | False |
| Root CA \| Create self-signed CA certificate from CSR | community.crypto.x509_certificate | False |
| Root CA \| Create self-signed CA certificate from CSR | community.crypto.x509_certificate | False |
#### File: tasks/renew/renew_root.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Root CA \| Check if root CA certificate exists | ansible.builtin.stat | False |
| Root CA \| Check CA for renewal | block | True |
| Root CA \| Get root CA certificate expiration date | community.crypto.x509_certificate_info | False |
| Root CA \| Check if root CA certificate is expiring within the threshold | ansible.builtin.set_fact | False |
| Root CA \| Renew CA if expiring soon | block | True |
| Root CA \| Create backup directory for root CA | ansible.builtin.file | False |
| Root CA \| Format expiration date for backup | ansible.builtin.set_fact | False |
| Root CA \| Rename existing root CA certificate | ansible.builtin.command | False |
| Root CA \| Remove existing root CA key | ansible.builtin.file | False |
| Root CA \| Generate new root CA if renaming was successful | ansible.builtin.include_tasks | False |
| Root CA \| Generate new intermediate CA | ansible.builtin.include_tasks | False |
#### File: tasks/renew/renew_consul.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Consul leaf certificates \| Check if certificate exists | ansible.builtin.stat | False |
| Consul leaf certificates \| Check if intermediate CA certificate exists | ansible.builtin.stat | False |
| Consul leaf certificates \| Check certificate for renewal | block | True |
| Consul leaf certificates \| Get certificate expiration date | community.crypto.x509_certificate_info | False |
| Intermediate CA \| Get intermediate CA certificate info | community.crypto.x509_certificate_info | False |
| Consul leaf certificates \| Check if certificate is expiring within the threshold | ansible.builtin.set_fact | False |
| Consul leaf certificates \| Check if intermediate CA has been renewed | ansible.builtin.set_fact | False |
| Consul leaf certificates \| Renew certificate if expiring soon or intermediate CA has been renewed | block | True |
| Consul leaf certificates \| Remove old certificate before renewal | ansible.builtin.file | False |
| Consul leaf certificates \| Remove old certificate key before renewal | ansible.builtin.file | False |
| Consul leaf certificates \| Generate new consul leaf certificate | ansible.builtin.include_tasks | False |
#### File: tasks/renew/renew_nomad.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad leaf certificates \| Check if certificate exists | ansible.builtin.stat | False |
| Nomad leaf certificates \| Check if intermediate CA certificate exists | ansible.builtin.stat | False |
| Nomad leaf certificates \| Check certificate for renewal | block | True |
| Nomad leaf certificates \| Get certificate expiration date | community.crypto.x509_certificate_info | False |
| Intermediate CA \| Get intermediate CA certificate info | community.crypto.x509_certificate_info | False |
| Nomad leaf certificates \| Check if certificate is expiring within the threshold | ansible.builtin.set_fact | False |
| Nomad leaf certificates \| Check if intermediate CA has been renewed | ansible.builtin.set_fact | False |
| Nomad leaf certificates \| Renew certificate if expiring soon or intermediate CA has been renewed | block | True |
| Nomad leaf certificates \| Remove old certificate before renewal | ansible.builtin.file | False |
| Nomad leaf certificates \| Remove old certificate key before renewal | ansible.builtin.file | False |
| Nomad leaf certificates \| Generate new nomad leaf certificate | ansible.builtin.include_tasks | False |
#### File: tasks/renew/renew_intermediate.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Intermediate CA \| Check if intermediate CA certificate exists | ansible.builtin.stat | False |
| Intermediate CA \| Check if root CA certificate exists | ansible.builtin.stat | False |
| Intermediate CA \| Check CA for renewal | block | True |
| Intermediate CA \| Get intermediate CA certificate expiration date | community.crypto.x509_certificate_info | False |
| Root CA \| Get root CA certificate info | community.crypto.x509_certificate_info | False |
| Intermediate CA \| Check if intermediate CA certificate is expiring within the threshold | ansible.builtin.set_fact | False |
| Intermediate CA \| Check if root CA has been renewed | ansible.builtin.set_fact | False |
| Intermediate CA \| Renew CA if expiring soon or root CA has been renewed | block | True |
| Intermediate CA \| Create backup directory for intermediate CA | ansible.builtin.file | False |
| Intermediate CA \| Format expiration date for backup | ansible.builtin.set_fact | False |
| Intermediate CA \| Backup existing intermediate CA certificate | ansible.builtin.command | False |
| Intermediate CA \| Backup existing intermediate CA key | ansible.builtin.command | False |
| Intermediate CA \| Generate new intermediate CA if backups were successful | ansible.builtin.include_tasks | False |
| Intermediate CA \| Generate new consul leaf certificates | ansible.builtin.include_tasks | False |
| Intermediate CA \| Generate new nomad leaf certificates | ansible.builtin.include_tasks | False |
| Intermediate CA \| Generate new vault leaf certificates | ansible.builtin.include_tasks | False |
#### File: tasks/renew/renew_vault.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault leaf certificates \| Check if certificate exists | ansible.builtin.stat | False |
| Vault leaf certificates \| Check if intermediate CA certificate exists | ansible.builtin.stat | False |
| Vault leaf certificates \| Check certificate for renewal | block | True |
| Vault leaf certificates \| Get certificate expiration date | community.crypto.x509_certificate_info | False |
| Intermediate CA \| Get intermediate CA certificate info | community.crypto.x509_certificate_info | False |
| Vault leaf certificates \| Check if certificate is expiring within the threshold | ansible.builtin.set_fact | False |
| Vault leaf certificates \| Check if intermediate CA has been renewed | ansible.builtin.set_fact | False |
| Vault leaf certificates \| Renew certificate if expiring soon or intermediate CA has been renewed | block | True |
| Vault leaf certificates \| Remove old certificate before renewal | ansible.builtin.file | False |
| Vault leaf certificates \| Remove old certificate key before renewal | ansible.builtin.file | False |
| Vault leaf certificates \| Generate new vault leaf certificate | ansible.builtin.include_tasks | False |
<!-- DOCSIBLE END -->

View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

View File

@ -0,0 +1,52 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## hashistack_ingress
Description: Deploys an ingress reverse-proxy on a hashistack-ansible managed nomad cluster
| Field | Value |
|---------------|------------|
| Readme update | 26/08/2024 |
### Tasks
## Author Information
Bertrand Lanson
#### License
license (BSD, MIT)
#### Minimum Ansible Version
2.10
#### Platforms
- **Ubuntu**: ['focal', 'jammy', 'noble']
- **Debian**: ['bullseye', 'bookworm']
<!-- DOCSIBLE END -->

View File

@ -0,0 +1,45 @@
---
# defaults file for hashistack_ingress
hashistack_ingress_nomad_api_addr: "http://127.0.0.1:4646"
hashistack_ingress_nomad_api_token:
hashistack_ingress_job_name: HashistackHAProxyIngress
hashistack_ingress_datacenters: []
hashistack_ingress_namespace: default
hashistack_ingress_replicas: 1
hashistack_ingress_enable_consul_service: true
hashistack_ingress_virtual_ip_keepalived_version: latest
hashistack_ingress_virtual_ip_addr: "192.168.1.1"
hashistack_ingress_virtual_ip_interface: eth0
hashistack_ingress_virtual_ip_vrrp_interface: "{{ hashistack_ingress_virtual_ip_interface }}"
hashistack_ingress_virtual_ip_vrrp_router_id: 50
hashistack_ingress_virtual_ip_vrrp_priority: 100
hashistack_ingress_virtual_ip_vrrp_advertise_interval: 1
hashistack_ingress_virtual_ip_vrrp_password: password
hashistack_ingress_enable_http: true
hashistack_ingress_enable_https: false
hashistack_ingress_enable_prometheus_metrics: false
hashistack_ingress_enable_admin_interface: false
hashistack_ingress_admin_interface_password: password
hashistack_ingress_virtual_ip_haproxy_version: latest
hashistack_ingress_haproxy_global:
- log /dev/log local0
- log /dev/log local1 notice
- stats socket {{ deploy_haproxy_socket }} level admin
- chroot {{ deploy_haproxy_chroot }}
- daemon
- description hashistack haproxy
hashistack_ingress_haproxy_defaults:
- log global
- mode http
- option httplog
- option dontlognull
- timeout connect 5000
- timeout client 5000
- timeout server 5000
hashistack_ingress_haproxy_frontends: []
hashistack_ingress_haproxy_backends: []
hashistack_ingress_haproxy_listen: []

View File

@ -0,0 +1,2 @@
---
# handlers file for hashistack_ingress

View File

@ -0,0 +1,28 @@
---
# meta file for hashistack_ingress
galaxy_info:
namespace: "ednz_cloud"
role_name: "hashistack_ingress"
author: "Bertrand Lanson"
description: "Deploys an ingress reverse-proxy on a hashistack-ansible managed nomad cluster"
license: "license (BSD, MIT)"
min_ansible_version: "2.10"
platforms:
- name: Ubuntu
versions:
- focal
- jammy
- noble
- name: Debian
versions:
- bullseye
- bookworm
galaxy_tags:
- "ubuntu"
- "debian"
- "hashicorp"
- "nomad"
- "haproxy"
- "ingress"
dependencies: []

View File

@ -0,0 +1,2 @@
---
# task/main file for hashistack_ingress

View File

@ -0,0 +1 @@
#! /bin/sh

View File

@ -0,0 +1,31 @@
# {{ ansible_managed }}
global
{% for option in hashistack_ingress_haproxy_global %}
{{ option }}
{% endfor %}
defaults
{% for option in hashistack_ingress_haproxy_defaults %}
{{ option }}
{% endfor %}
{% for frontend in hashistack_ingress_haproxy_frontends + hashistack_ingress_mandatory_frontends %}
frontend {{ frontend.name }}
{% for option in frontend.options %}
{{ option }}
{% endfor %}
{% endfor %}
{% for backend in hashistack_ingress_haproxy_backends %}
backend {{ backend.name }}
{% for option in backend.options%}
{{ option }}
{% endfor %}
{% endfor %}
{% for listen in hashistack_ingress_haproxy_listen %}
listen {{ listen.name }}
{% for option in listen.options %}
{{ option }}
{% endfor %}
{% endfor %}

View File

@ -0,0 +1,155 @@
job "{{ hashistack_ingress_job_name }}" {
datacenters = {{ hashistack_ingress_datacenters }}
type = "service"
priority = 85
namespace = {{ hashistack_ingress_namespace }}
group "haproxy" {
network {
mode = "bridge"
port "http" {
to = 80
static = 80
}
port "https" {
to = 443
static = 443
}
port "stats" {
to = 9000
}
}
{% if hashistack_ingress_enable_http %}
service {
name = "haproxy-http"
provider = "{{ "consul" if hashistack_ingress_enable_consul_service else "nomad"}}"
port = "http"
task = "loadbalancer"
check {
type = "http"
port = "stats"
path = "/health"
interval = "10s"
timeout = "2s"
}
tags = []
}
{% endif %}
{% if hashistack_ingress_enable_https %}
service {
name = "haproxy-https"
provider = "{{ "consul" if hashistack_ingress_enable_consul_service else "nomad"}}"
port = "https"
task = "loadbalancer"
check {
type = "http"
port = "stats"
path = "/health"
interval = "10s"
timeout = "2s"
}
tags = []
}
{% endif %}
service {
name = "haproxy-stats"
provider = "{{ "consul" if hashistack_ingress_enable_consul_service else "nomad"}}"
port = "stats"
task = "loadbalancer"
check {
type = "http"
port = "stats"
path = "/health"
interval = "10s"
timeout = "2s"
}
tags = []
}
{% if hashistack_ingress_enable_prometheus_metrics %}
service {
name = "loadbalancer-exporter"
port = "prometheus-exporter"
task = "loadbalancer"
tags = []
}
{% endif %}
task "keepalived" {
driver = "docker"
lifecycle {
hook = "poststart"
sidecar = true
}
config {
image = "{{ hashistack_ingress_keepalived_image }}:{{ hashistack_ingress_virtual_ip_keepalived_version }}"
network_mode = "host"
cap_add = [
"NET_ADMIN",
"NET_BROADCAST",
"NET_RAW"
]
mount {
type = "bind"
source = "secrets/keepalived.conf"
target = "/etc/keepalived/keepalived.conf"
}
mount {
type = "bind"
source = "secrets/chk_haproxy.sh"
target = "/etc/keepalived/scripts.d/chk_haproxy.sh"
}
mount {
type = "bind"
target = "/var/run/docker.sock"
source = "/var/run/docker.sock"
readonly = true
}
}
template {
data = <<-EOT
{% include "keepalived.conf.j2" %}
EOT
destination = "secrets/keepalived.conf"
}
template {
data = <<-EOT
{% include "chk_haproxy.sh.j2" %}
EOT
destination = "secrets/chk_haproxy.sh"
perms = "755"
}
resources {
cpu = 50
memory = 10
}
}
task "loadbalancer" {
driver = "docker"
config {
image = "{{ hashistack_ingress_haproxy_image }}:{{ hashistack_ingress_virtual_ip_haproxy_version }}"
mount {
type = "bind"
source = "secrets/haproxy.cfg"
target = "/usr/local/etc/haproxy/haproxy.cfg"
}
}
template {
data = <<-EOT
{% include "haproxy.cfg.j2" %}
EOT
destination = "secrets/haproxy.cfg"
}
resources {
cpu = 128
memory = 256
}
}
}
}

View File

@ -0,0 +1,37 @@
global_defs {
script_user root
enable_script_security
}
vrrp_script chk_haproxy {
script "/etc/keepalived/scripts.d/chk_haproxy.sh"
user root
interval 3
weight 0
rise 6
fall 1
}
vrrp_instance haproxy {
interface {{ hashistack_ingress_virtual_ip_vrrp_interface }}
state {{ hashistack_ingress_keepalived_init_state }}
virtual_router_id {{ hashistack_ingress_virtual_ip_vrrp_router_id }}
priority {{ hashistack_ingress_virtual_ip_vrrp_priority }}
advert_int {{ hashistack_ingress_virtual_ip_vrrp_advertise_interval }}
authentication {
auth_type PASS
auth_pass {{ hashistack_ingress_virtual_ip_vrrp_password }}
}
virtual_ipaddress {
{{ hashistack_ingress_virtual_ip_addr }}/32 dev {{ hashistack_ingress_virtual_ip_interface }}
}
track_script {
chk_haproxy
}
notify /etc/keepalived/scripts.d/notify.sh
}

View File

@ -0,0 +1,28 @@
---
# vars file for hashistack_ingress
hashistack_ingress_keepalived_image: ednxzu/keepalived
hashistack_ingress_haproxy_image: haproxytech/haproxy-debian
hashistack_ingress_keepalived_init_state: BACKUP
hashistack_ingress_template_haproxy_cfg: "{{ lookup('ansible.builtin.template', 'haproxy.cfg.j2') }}"
hashistack_ingress_template_keepalived_conf: "{{ lookup('ansible.builtin.template', 'keepalived.conf.j2') }}"
hashistack_ingress_template_chk_haproxy_sh: "{{ lookup('ansible.builtin.template', 'chk_haproxy.sh.j2') }}"
hashistack_ingress_mandatory_frontends:
- name: monitoring
options:
- bind :9000
- mode http
- option httpchk
- "{{'stats enable' if hashistack_ingress_enable_admin_interface else omit }}"
- "{{'stats uri /stats' if hashistack_ingress_enable_admin_interface else omit }}"
- "{{'stats refresh 30s' if hashistack_ingress_enable_admin_interface else omit }}"
- "{{'stats show-desc' if hashistack_ingress_enable_admin_interface else omit }}"
- "{{'stats show-legends' if hashistack_ingress_enable_admin_interface else omit }}"
- "{{'stats auth admin:'~hashistack_ingress_admin_interface_password if hashistack_ingress_enable_admin_interface else omit }}"
- http-check send meth GET uri /health ver HTTP/1.1 hdr Host localhost
- http-check expect status 200
- acl health_check_ok nbsrv() ge 1
- monitor-uri /health
- "{{'http-request use-service prometheus-exporter if { path /metrics }' if hashistack_ingress_enable_prometheus_metrics else omit }}"

13
roles/nomad/.docsible Normal file
View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

221
roles/nomad/README.md Normal file
View File

@ -0,0 +1,221 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## nomad
Description: Install and configure hashicorp nomad for debian-based distros.
| Field | Value |
|--------------------- |-----------------|
| Readme update | 26/08/2024 |
### Defaults
**These are static variables with lower priority**
#### File: defaults/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [nomad_version](defaults/main.yml#L4) | str | `latest` | n/a | n/a |
| [nomad_start_service](defaults/main.yml#L5) | bool | `True` | n/a | n/a |
| [nomad_config_dir](defaults/main.yml#L6) | str | `/etc/nomad.d` | n/a | n/a |
| [nomad_data_dir](defaults/main.yml#L7) | str | `/opt/nomad` | n/a | n/a |
| [nomad_certs_dir](defaults/main.yml#L8) | str | `{{ nomad_config_dir }}/tls` | n/a | n/a |
| [nomad_logs_dir](defaults/main.yml#L9) | str | `/var/log/nomad` | n/a | n/a |
| [nomad_extra_files](defaults/main.yml#L11) | bool | `False` | n/a | n/a |
| [nomad_extra_files_list](defaults/main.yml#L12) | list | `[]` | n/a | n/a |
| [nomad_env_variables](defaults/main.yml#L14) | dict | `{}` | n/a | n/a |
| [nomad_extra_configuration](defaults/main.yml#L25) | dict | `{}` | n/a | n/a |
| [nomad_region](defaults/main.yml#L31) | str | `global` | n/a | n/a |
| [nomad_datacenter](defaults/main.yml#L32) | str | `dc1` | n/a | n/a |
| [nomad_bind_addr](defaults/main.yml#L38) | str | `0.0.0.0` | n/a | n/a |
| [nomad_advertise_addr](defaults/main.yml#L39) | str | `{{ ansible_default_ipv4.address }}` | n/a | n/a |
| [nomad_address_configuration](defaults/main.yml#L40) | dict | `{'bind_addr': '{{ nomad_bind_addr }}', 'addresses': {'http': '{{ nomad_advertise_addr }}', 'rpc': '{{ nomad_advertise_addr }}', 'serf': '{{ nomad_advertise_addr }}'}, 'advertise': {'http': '{{ nomad_advertise_addr }}', 'rpc': '{{ nomad_advertise_addr }}', 'serf': '{{ nomad_advertise_addr }}'}, 'ports': {'http': 4646, 'rpc': 4647, 'serf': 4648}}` | n/a | n/a |
| [nomad_autopilot_configuration](defaults/main.yml#L59) | dict | `{}` | n/a | n/a |
| [nomad_leave_on_interrupt](defaults/main.yml#L65) | bool | `False` | n/a | n/a |
| [nomad_leave_on_terminate](defaults/main.yml#L66) | bool | `False` | n/a | n/a |
| [nomad_enable_server](defaults/main.yml#L72) | bool | `True` | n/a | n/a |
| [nomad_server_bootstrap_expect](defaults/main.yml#L73) | int | `1` | n/a | n/a |
| [nomad_server_configuration](defaults/main.yml#L74) | dict | `{'enabled': '{{ nomad_enable_server }}', 'data_dir': '{{ nomad_data_dir }}/server', 'encrypt': "{{ 'mysupersecretgossipencryptionkey'\|b64encode }}", 'server_join': {'retry_join': ['{{ ansible_default_ipv4.address }}']}}` | n/a | n/a |
| [nomad_enable_client](defaults/main.yml#L86) | bool | `False` | n/a | n/a |
| [nomad_client_configuration](defaults/main.yml#L87) | dict | `{'enabled': '{{ nomad_enable_client }}', 'state_dir': '{{ nomad_data_dir }}/client', 'cni_path': '/opt/cni/bin', 'bridge_network_name': 'nomad', 'bridge_network_subnet': '172.26.64.0/20'}` | n/a | n/a |
| [nomad_ui_configuration](defaults/main.yml#L98) | dict | `{'enabled': '{{ nomad_enable_server }}'}` | n/a | n/a |
| [nomad_driver_enable_docker](defaults/main.yml#L105) | bool | `True` | n/a | n/a |
| [nomad_driver_enable_podman](defaults/main.yml#L106) | bool | `False` | n/a | n/a |
| [nomad_driver_enable_raw_exec](defaults/main.yml#L107) | bool | `False` | n/a | n/a |
| [nomad_driver_enable_java](defaults/main.yml#L108) | bool | `False` | n/a | n/a |
| [nomad_driver_enable_qemu](defaults/main.yml#L109) | bool | `False` | n/a | n/a |
| [nomad_driver_configuration](defaults/main.yml#L111) | dict | `{'raw_exec': {'enabled': False}}` | n/a | n/a |
| [nomad_driver_extra_configuration](defaults/main.yml#L115) | dict | `{}` | n/a | n/a |
| [nomad_log_level](defaults/main.yml#L121) | str | `info` | n/a | n/a |
| [nomad_enable_log_to_file](defaults/main.yml#L122) | bool | `False` | n/a | n/a |
| [nomad_log_to_file_configuration](defaults/main.yml#L123) | dict | `{'log_file': '{{ nomad_logs_dir }}/nomad.log', 'log_rotate_duration': '24h', 'log_rotate_max_files': 30}` | n/a | n/a |
| [nomad_acl_configuration](defaults/main.yml#L132) | dict | `{'enabled': False, 'token_ttl': '30s', 'policy_ttl': '60s', 'role_ttl': '60s'}` | n/a | n/a |
| [nomad_enable_tls](defaults/main.yml#L142) | bool | `False` | n/a | n/a |
| [nomad_tls_configuration](defaults/main.yml#L143) | dict | `{'http': True, 'rpc': True, 'ca_file': '/etc/ssl/certs/ca-certificates.crt', 'cert_file': '{{ nomad_certs_dir }}/cert.pem', 'key_file': '{{ nomad_certs_dir }}/key.pem', 'verify_server_hostname': True}` | n/a | n/a |
| [nomad_certificates_extra_files_dir](defaults/main.yml#L151) | list | `[]` | n/a | n/a |
| [nomad_telemetry_configuration](defaults/main.yml#L160) | dict | `{'collection_interval': '10s', 'disable_hostname': False, 'use_node_name': False, 'publish_allocation_metrics': False, 'publish_node_metrics': False, 'prefix_filter': [], 'disable_dispatched_job_summary_metrics': False, 'prometheus_metrics': False}` | n/a | n/a |
| [nomad_enable_consul_integration](defaults/main.yml#L174) | bool | `False` | n/a | n/a |
| [nomad_consul_integration_configuration](defaults/main.yml#L175) | dict | `{'address': '127.0.0.1:8500', 'auto_advertise': True, 'ssl': False, 'token': '', 'tags': []}` | n/a | n/a |
| [nomad_consul_integration_tls_configuration](defaults/main.yml#L182) | dict | `{'ca_file': '/etc/ssl/certs/ca-certificates.crt'}` | n/a | n/a |
| [nomad_consul_integration_server_configuration](defaults/main.yml#L185) | dict | `{'server_auto_join': True}` | n/a | n/a |
| [nomad_consul_integration_client_configuration](defaults/main.yml#L188) | dict | `{'client_auto_join': True, 'grpc_address': '127.0.0.1:8502'}` | n/a | n/a |
| [nomad_consul_integration_client_tls_configuration](defaults/main.yml#L192) | dict | `{'grpc_ca_file': '/etc/ssl/certs/ca-certificates.crt'}` | n/a | n/a |
| [nomad_enable_vault_integration](defaults/main.yml#L199) | bool | `False` | n/a | n/a |
| [nomad_vault_integration_configuration](defaults/main.yml#L200) | dict | `{}` | n/a | n/a |
### Vars
**These are variables with higher priority**
#### File: vars/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [nomad_user](vars/main.yml#L3) | str | `nomad` | n/a | n/a |
| [nomad_group](vars/main.yml#L4) | str | `nomad` | n/a | n/a |
| [nomad_binary_path](vars/main.yml#L5) | str | `/usr/local/bin/nomad` | n/a | n/a |
| [nomad_deb_architecture_map](vars/main.yml#L6) | dict | `{'x86_64': 'amd64', 'aarch64': 'arm64', 'armv7l': 'arm', 'armv6l': 'arm'}` | n/a | n/a |
| [nomad_architecture](vars/main.yml#L11) | str | `{{ nomad_deb_architecture_map[ansible_architecture] \| default(ansible_architecture) }}` | n/a | n/a |
| [nomad_service_name](vars/main.yml#L12) | str | `nomad` | n/a | n/a |
| [nomad_github_api](vars/main.yml#L13) | str | `https://api.github.com/repos` | n/a | n/a |
| [nomad_github_project](vars/main.yml#L14) | str | `hashicorp/nomad` | n/a | n/a |
| [nomad_github_url](vars/main.yml#L15) | str | `https://github.com` | n/a | n/a |
| [nomad_repository_url](vars/main.yml#L16) | str | `https://releases.hashicorp.com/nomad` | n/a | n/a |
| [nomad_configuration](vars/main.yml#L18) | dict | `{'datacenter': '{{ nomad_datacenter }}', 'region': '{{ nomad_region }}', 'data_dir': '{{ nomad_data_dir }}', 'leave_on_interrupt': '{{ nomad_leave_on_interrupt }}', 'leave_on_terminate': '{{ nomad_leave_on_terminate }}', 'acl': '{{ nomad_acl_configuration }}', 'server': '{{ nomad_server_configuration }}', 'client': '{{ nomad_client_configuration }}', 'ui': '{{ nomad_ui_configuration }}', 'log_level': '{{ nomad_log_level }}'}` | n/a | n/a |
| [nomad_configuration_string](vars/main.yml#L30) | str | `<multiline value>` | n/a | n/a |
### Tasks
#### File: tasks/recursive_copy_extra_dirs.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Ensure destination directory exists | ansible.builtin.file | False |
| Nomad \| Create extra directory sources | ansible.builtin.file | True |
| Nomad \| Template extra directory sources | ansible.builtin.template | True |
#### File: tasks/merge_variables.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Merge stringified configuration | vars | False |
| Nomad \| Merge addresses configuration | vars | False |
| Nomad \| Merge consul integration configuration | block | True |
| Nomad \| Merge consul tls configuration | block | True |
| Nomad \| Merge consul default client configuration | vars | False |
| Nomad \| Merge consul configuration for nomad servers | block | True |
| Nomad \| Merge consul default server configuration | vars | False |
| Nomad \| Merge consul configuration for nomad clients | block | True |
| Nomad \| Merge consul default client configuration | vars | False |
| Nomad \| Merge consul tls client configuration | vars | True |
| Nomad \| Merge consul block into main configuration | vars | False |
| Nomad \| Merge TLS configuration | block | True |
| Nomad \| Merge TLS configuration | vars | False |
| Nomad \| Add certificates directory to extra_files_dir | ansible.builtin.set_fact | False |
| Nomad \| Merge plugin configuration | vars | True |
| Nomad \| Merge extra configuration settings | vars | False |
| Nomad \| Merge log to file configuration | vars | True |
| Nomad \| Merge telemetry configuration | vars | False |
#### File: tasks/main.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Set reload-check & restart-check variable | ansible.builtin.set_fact | False |
| Nomad \| Import merge_variables.yml | ansible.builtin.include_tasks | False |
| Nomad \| Import prerequisites.yml | ansible.builtin.include_tasks | False |
| Nomad \| Import install.yml | ansible.builtin.include_tasks | False |
| Nomad \| Import configure.yml | ansible.builtin.include_tasks | False |
| Nomad \| Populate service facts | ansible.builtin.service_facts | False |
| Nomad \| Set restart-check variable | ansible.builtin.set_fact | True |
| Nomad \| Enable service: {{ nomad_service_name }} | ansible.builtin.service | False |
| Nomad \| Reload systemd daemon | ansible.builtin.systemd | True |
| Nomad \| Start service: {{ nomad_service_name }} | ansible.builtin.service | True |
#### File: tasks/install.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Get latest release of nomad | block | True |
| Nomad \| Get latest nomad release from github api | ansible.builtin.uri | False |
| Nomad \| Set wanted nomad version to latest tag | ansible.builtin.set_fact | False |
| Nomad \| Set wanted nomad version to {{ nomad_version }} | ansible.builtin.set_fact | True |
| Nomad \| Get current nomad version | block | False |
| Nomad \| Stat nomad version file | ansible.builtin.stat | False |
| Nomad \| Get current nomad version | ansible.builtin.slurp | True |
| Nomad \| Download and install nomad binary | block | True |
| Nomad \| Set nomad package name to download | ansible.builtin.set_fact | False |
| Nomad \| Download checksum file for nomad archive | ansible.builtin.get_url | False |
| Nomad \| Extract correct checksum from checksum file | ansible.builtin.command | False |
| Nomad \| Parse the expected checksum | ansible.builtin.set_fact | False |
| Nomad \| Download nomad binary archive | ansible.builtin.get_url | False |
| Nomad \| Create temporary directory for archive decompression | ansible.builtin.file | False |
| Nomad \| Unpack nomad archive | ansible.builtin.unarchive | False |
| Nomad \| Copy nomad binary to {{ nomad_binary_path }} | ansible.builtin.copy | False |
| Nomad \| Update nomad version file | ansible.builtin.copy | False |
| Nomad \| Set restart-check variable | ansible.builtin.set_fact | False |
| Nomad \| Cleanup temporary directory | ansible.builtin.file | False |
| Nomad \| Copy systemd service file for nomad | ansible.builtin.template | False |
| Nomad \| Set reload-check & restart-check variable | ansible.builtin.set_fact | True |
#### File: tasks/prerequisites.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Create group {{ nomad_group }} | ansible.builtin.group | False |
| Nomad \| Create user {{ nomad_user }} | ansible.builtin.user | False |
| Nomad \| Create directory {{ nomad_config_dir }} | ansible.builtin.file | False |
| Nomad \| Create directory {{ nomad_data_dir }} | ansible.builtin.file | False |
| Nomad \| Create directory {{ nomad_certs_dir }} | ansible.builtin.file | False |
| Nomad \| Create directory {{ nomad_logs_dir }} | ansible.builtin.file | True |
#### File: tasks/configure.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Nomad \| Create nomad.env | ansible.builtin.template | False |
| Nomad \| Copy nomad.json template | ansible.builtin.template | False |
| Nomad \| Set restart-check variable | ansible.builtin.set_fact | True |
| Nomad \| Copy extra configuration files | block | True |
| Nomad \| Get extra file types | ansible.builtin.stat | False |
| Nomad \| Set list for file sources | vars | True |
| Nomad \| Set list for directory sources | vars | True |
| Nomad \| Template extra file sources | ansible.builtin.template | True |
| Nomad \| Template extra directory sources | ansible.builtin.include_tasks | True |
## Author Information
Bertrand Lanson
#### License
license (BSD, MIT)
#### Minimum Ansible Version
2.10
#### Platforms
- **Ubuntu**: ['focal', 'jammy', 'noble']
- **Debian**: ['bullseye', 'bookworm']
<!-- DOCSIBLE END -->

13
roles/vault/.docsible Normal file
View File

@ -0,0 +1,13 @@
aap_hub: null
automation_kind: null
category: null
critical: null
description: null
dt_dev: null
dt_prod: null
dt_update: 26/08/2024
requester: null
subCategory: null
time_saving: null
users: null
version: null

193
roles/vault/README.md Normal file
View File

@ -0,0 +1,193 @@
<!-- DOCSIBLE START -->
# 📃 Role overview
## vault
Description: Install and configure hashicorp vault for debian-based distros.
| Field | Value |
|--------------------- |-----------------|
| Readme update | 26/08/2024 |
### Defaults
**These are static variables with lower priority**
#### File: defaults/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [vault_version](defaults/main.yml#L3) | str | `latest` | n/a | n/a |
| [vault_start_service](defaults/main.yml#L4) | bool | `True` | n/a | n/a |
| [vault_config_dir](defaults/main.yml#L5) | str | `/etc/vault.d` | n/a | n/a |
| [vault_data_dir](defaults/main.yml#L6) | str | `/opt/vault` | n/a | n/a |
| [vault_certs_dir](defaults/main.yml#L7) | str | `{{ vault_config_dir }}/tls` | n/a | n/a |
| [vault_logs_dir](defaults/main.yml#L8) | str | `/var/log/vault` | n/a | n/a |
| [vault_extra_files](defaults/main.yml#L10) | bool | `False` | n/a | n/a |
| [vault_extra_files_list](defaults/main.yml#L11) | list | `[]` | n/a | n/a |
| [vault_env_variables](defaults/main.yml#L13) | dict | `{}` | n/a | n/a |
| [vault_extra_configuration](defaults/main.yml#L24) | dict | `{}` | n/a | n/a |
| [vault_cluster_name](defaults/main.yml#L30) | str | `vault` | n/a | n/a |
| [vault_bind_addr](defaults/main.yml#L31) | str | `0.0.0.0` | n/a | n/a |
| [vault_cluster_addr](defaults/main.yml#L32) | str | `{{ ansible_default_ipv4.address }}` | n/a | n/a |
| [vault_enable_ui](defaults/main.yml#L33) | bool | `True` | n/a | n/a |
| [vault_disable_mlock](defaults/main.yml#L34) | bool | `False` | n/a | n/a |
| [vault_disable_cache](defaults/main.yml#L35) | bool | `False` | n/a | n/a |
| [vault_storage_configuration](defaults/main.yml#L41) | dict | `{'file': {'path': '{{ vault_data_dir }}'}}` | n/a | n/a |
| [vault_enable_tls](defaults/main.yml#L49) | bool | `False` | n/a | n/a |
| [vault_listener_configuration](defaults/main.yml#L50) | list | `[{'tcp': {'address': '{{ vault_cluster_addr }}:8200', 'tls_disable': True}}]` | n/a | n/a |
| [vault_tls_listener_configuration](defaults/main.yml#L55) | list | `[{'tcp': {'tls_disable': False, 'tls_cert_file': '{{ vault_certs_dir }}/cert.pem', 'tls_key_file': '{{ vault_certs_dir }}/key.pem', 'tls_disable_client_certs': True}}]` | n/a | n/a |
| [vault_certificates_extra_files_dir](defaults/main.yml#L62) | list | `[]` | n/a | n/a |
| [vault_extra_listener_configuration](defaults/main.yml#L67) | list | `[]` | n/a | n/a |
| [vault_enable_service_registration](defaults/main.yml#L73) | bool | `False` | n/a | n/a |
| [vault_service_registration_configuration](defaults/main.yml#L74) | dict | `{'consul': {'address': '127.0.0.1:8500', 'scheme': 'http', 'token': ''}}` | n/a | n/a |
| [vault_enable_plugins](defaults/main.yml#L84) | bool | `False` | n/a | n/a |
| [vault_plugins_directory](defaults/main.yml#L85) | str | `{{ vault_config_dir }}/plugins` | n/a | n/a |
| [vault_log_level](defaults/main.yml#L91) | str | `info` | n/a | n/a |
| [vault_enable_log_to_file](defaults/main.yml#L92) | bool | `False` | n/a | n/a |
| [vault_log_to_file_configuration](defaults/main.yml#L93) | dict | `{'log_file': '{{ vault_logs_dir }}/vault.log', 'log_rotate_duration': '24h', 'log_rotate_max_files': 30}` | n/a | n/a |
### Vars
**These are variables with higher priority**
#### File: vars/main.yml
| Var | Type | Value |Required | Title |
|--------------|--------------|-------------|-------------|-------------|
| [vault_user](vars/main.yml#L3) | str | `vault` | n/a | n/a |
| [vault_group](vars/main.yml#L4) | str | `vault` | n/a | n/a |
| [vault_binary_path](vars/main.yml#L5) | str | `/usr/local/bin/vault` | n/a | n/a |
| [vault_deb_architecture_map](vars/main.yml#L6) | dict | `{'x86_64': 'amd64', 'aarch64': 'arm64', 'armv7l': 'arm', 'armv6l': 'arm'}` | n/a | n/a |
| [vault_architecture](vars/main.yml#L11) | str | `{{ vault_deb_architecture_map[ansible_architecture] \| default(ansible_architecture) }}` | n/a | n/a |
| [vault_service_name](vars/main.yml#L12) | str | `vault` | n/a | n/a |
| [vault_github_api](vars/main.yml#L13) | str | `https://api.github.com/repos` | n/a | n/a |
| [vault_github_project](vars/main.yml#L14) | str | `hashicorp/vault` | n/a | n/a |
| [vault_github_url](vars/main.yml#L15) | str | `https://github.com` | n/a | n/a |
| [vault_repository_url](vars/main.yml#L16) | str | `https://releases.hashicorp.com/vault` | n/a | n/a |
| [vault_configuration](vars/main.yml#L18) | dict | `{'cluster_name': '{{ vault_cluster_name }}', 'cluster_addr': "{{ 'https' if vault_enable_tls else 'http'}}://{{ vault_cluster_addr }}:8201", 'api_addr': "{{ 'https' if vault_enable_tls else 'http'}}://{{ vault_cluster_addr }}:8200", 'ui': '{{ vault_enable_ui }}', 'disable_mlock': '{{ vault_disable_mlock }}', 'disable_cache': '{{ vault_disable_cache }}', 'listener': '{{ vault_listener_configuration }}', 'storage': '{{ vault_storage_configuration }}'}` | n/a | n/a |
### Tasks
#### File: tasks/recursive_copy_extra_dirs.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Ensure destination directory exists | ansible.builtin.file | False |
| Vault \| Create extra directory sources | ansible.builtin.file | True |
| Vault \| Template extra directory sources | ansible.builtin.template | True |
#### File: tasks/merge_variables.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Merge listener configuration | block | False |
| Vault \| Merge tls listener configuration | vars | True |
| Vault \| Merge extra listener configuration | vars | False |
| Vault \| Add certificates directory to extra_files_dir | ansible.builtin.set_fact | False |
| Vault \| Merge service registration configuration | vars | True |
| Vault \| Merge plugins configuration | vars | True |
| Vault \| Merge logging configuration | vars | True |
| Vault \| Merge extra configuration settings | vars | True |
#### File: tasks/main.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Set reload-check & restart-check variable | ansible.builtin.set_fact | False |
| Vault \| Import merge_variables.yml | ansible.builtin.include_tasks | False |
| Vault \| Import prerequisites.yml | ansible.builtin.include_tasks | False |
| Vault \| Import install.yml | ansible.builtin.include_tasks | False |
| Vault \| Import configure.yml | ansible.builtin.include_tasks | False |
| Vault \| Populate service facts | ansible.builtin.service_facts | False |
| Vault \| Set restart-check variable | ansible.builtin.set_fact | True |
| Vault \| Enable service: {{ vault_service_name }} | ansible.builtin.service | False |
| Vault \| Reload systemd daemon | ansible.builtin.systemd | True |
| Vault \| Start service: {{ vault_service_name }} | ansible.builtin.service | True |
#### File: tasks/install.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Get latest release of vault | block | True |
| Vault \| Get latest vault release from github api | ansible.builtin.uri | False |
| Vault \| Set wanted vault version to latest tag | ansible.builtin.set_fact | False |
| Vault \| Set wanted vault version to {{ vault_version }} | ansible.builtin.set_fact | True |
| Vault \| Get current vault version | block | False |
| Vault \| Stat vault version file | ansible.builtin.stat | False |
| Vault \| Get current vault version | ansible.builtin.slurp | True |
| Vault \| Download and install vault binary | block | True |
| Vault \| Set vault package name to download | ansible.builtin.set_fact | False |
| Vault \| Download checksum file for vault archive | ansible.builtin.get_url | False |
| Vault \| Extract correct checksum from checksum file | ansible.builtin.command | False |
| Vault \| Parse the expected checksum | ansible.builtin.set_fact | False |
| Vault \| Download vault binary archive | ansible.builtin.get_url | False |
| Vault \| Create temporary directory for archive decompression | ansible.builtin.file | False |
| Vault \| Unpack vault archive | ansible.builtin.unarchive | False |
| Vault \| Copy vault binary to {{ vault_binary_path }} | ansible.builtin.copy | False |
| Vault \| Update vault version file | ansible.builtin.copy | False |
| Vault \| Set restart-check variable | ansible.builtin.set_fact | False |
| Vault \| Cleanup temporary directory | ansible.builtin.file | False |
| Vault \| Copy systemd service file for vault | ansible.builtin.template | False |
| Vault \| Set reload-check & restart-check variable | ansible.builtin.set_fact | True |
| Vault \| Copy systemd service file for vault | ansible.builtin.template | False |
#### File: tasks/prerequisites.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Create group {{ vault_group }} | ansible.builtin.group | False |
| Vault \| Create user {{ vault_user }} | ansible.builtin.user | False |
| Vault \| Create directory {{ vault_config_dir }} | ansible.builtin.file | False |
| Vault \| Create directory {{ vault_data_dir}} | ansible.builtin.file | False |
| Vault \| Create directory {{ vault_certs_dir }} | ansible.builtin.file | False |
| Vault \| Create directory {{ vault_logs_dir }} | ansible.builtin.file | True |
#### File: tasks/configure.yml
| Name | Module | Has Conditions |
| ---- | ------ | --------- |
| Vault \| Create vault.env | ansible.builtin.template | False |
| Vault \| Copy vault.json template | ansible.builtin.template | False |
| Vault \| Set restart-check variable | ansible.builtin.set_fact | True |
| Vault \| Copy extra configuration files | block | True |
| Vault \| Get extra file types | ansible.builtin.stat | False |
| Vault \| Set list for file sources | vars | True |
| Vault \| Set list for directory sources | vars | True |
| Vault \| Template extra file sources | ansible.builtin.template | True |
| Vault \| Template extra directory sources | ansible.builtin.include_tasks | True |
## Author Information
Bertrand Lanson
#### License
license (BSD, MIT)
#### Minimum Ansible Version
2.10
#### Platforms
- **Ubuntu**: ['focal', 'jammy', 'noble']
- **Debian**: ['bullseye', 'bookworm']
<!-- DOCSIBLE END -->