From dc269e5fc2868e0785ed51ec3f4bbd60853fd441 Mon Sep 17 00:00:00 2001 From: Patrick de Ruiter Date: Mon, 10 Nov 2025 21:57:00 +0100 Subject: [PATCH] Convert consul_template submodules to regular directories - Removed gitlink entries for consul_template-legacy and consul_template-org - Converted from git submodules to regular directories - Fixes: 'fatal: No url found for submodule path' error when downloading module - Required for using module with git::https:// source in parent modules --- ansible/roles/consul_template-legacy | 1 - .../roles/consul_template-legacy/README.md | 49 +++++++++++ .../consul_template-legacy/defaults/main.yml | 3 + .../files/certificate.ctmpl | 5 ++ .../files/chain_pem.ctmpl | 3 + .../files/private_key.ctmpl | 3 + .../consul_template-legacy/handlers/main.yml | 9 ++ .../consul_template-legacy/meta/main.yml | 20 +++++ .../consul_template-legacy/tasks/main.yml | 86 +++++++++++++++++++ .../templates/consul-template-config.hcl.j2 | 35 ++++++++ .../templates/consul-template.service.j2 | 18 ++++ .../consul_template-legacy/tests/inventory | 3 + .../consul_template-legacy/tests/test.yml | 6 ++ .../consul_template-legacy/vars/main.yml | 3 + ansible/roles/consul_template-org | 1 - .../files/certificate.ctmpl | 5 ++ .../consul_template-org/files/chain_pem.ctmpl | 3 + .../files/private_key.ctmpl | 3 + .../roles/consul_template-org/tasks/main.yml | 33 +++++++ .../templates/consul-template-config.hcl.j2 | 30 +++++++ .../templates/consul-template.service.j2 | 11 +++ 21 files changed, 328 insertions(+), 2 deletions(-) delete mode 160000 ansible/roles/consul_template-legacy create mode 100644 ansible/roles/consul_template-legacy/README.md create mode 100644 ansible/roles/consul_template-legacy/defaults/main.yml create mode 100644 ansible/roles/consul_template-legacy/files/certificate.ctmpl create mode 100644 ansible/roles/consul_template-legacy/files/chain_pem.ctmpl create mode 100644 ansible/roles/consul_template-legacy/files/private_key.ctmpl create mode 100644 ansible/roles/consul_template-legacy/handlers/main.yml create mode 100644 ansible/roles/consul_template-legacy/meta/main.yml create mode 100644 ansible/roles/consul_template-legacy/tasks/main.yml create mode 100644 ansible/roles/consul_template-legacy/templates/consul-template-config.hcl.j2 create mode 100644 ansible/roles/consul_template-legacy/templates/consul-template.service.j2 create mode 100644 ansible/roles/consul_template-legacy/tests/inventory create mode 100644 ansible/roles/consul_template-legacy/tests/test.yml create mode 100644 ansible/roles/consul_template-legacy/vars/main.yml delete mode 160000 ansible/roles/consul_template-org create mode 100644 ansible/roles/consul_template-org/files/certificate.ctmpl create mode 100644 ansible/roles/consul_template-org/files/chain_pem.ctmpl create mode 100644 ansible/roles/consul_template-org/files/private_key.ctmpl create mode 100644 ansible/roles/consul_template-org/tasks/main.yml create mode 100644 ansible/roles/consul_template-org/templates/consul-template-config.hcl.j2 create mode 100644 ansible/roles/consul_template-org/templates/consul-template.service.j2 diff --git a/ansible/roles/consul_template-legacy b/ansible/roles/consul_template-legacy deleted file mode 160000 index 011db90..0000000 --- a/ansible/roles/consul_template-legacy +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 011db9074813e45da783f410592c31a0f31c482e diff --git a/ansible/roles/consul_template-legacy/README.md b/ansible/roles/consul_template-legacy/README.md new file mode 100644 index 0000000..2f3b001 --- /dev/null +++ b/ansible/roles/consul_template-legacy/README.md @@ -0,0 +1,49 @@ +#consul_template + +An Ansible role to install and configure HashiCorp’s consul-template, securely fetching TLS certificates and private keys\ +from HashiCorp Vault using AppRole authentication, rendering them to disk, and reloading services when certificates change. + +### Requirements + • consul-template binary downloaded from HashiCorp releases. + • Network connectivity from the target host to the Vault instance (vault_address). + • Appropriate Vault AppRole credentials (vault_approle_role_id, vault_approle_secret_id) provisioned by Terraform or other automation. + +### Role Variables + +The following variables are required and should be set either through inventory or as role parameters: + + | Variable | Description | Default | + | vault_address | URL of your HashiCorp Vault instance | None (required) | + | vault_approle_role_id | Vault AppRole Role ID for consul-template authentication | None (required) | + | vault_approle_secret_id | Vault AppRole Secret ID for consul-template authentication | None (required) | + | environment | Environment identifier (e.g., prod, nonprod) | None (required) | + | short_hostname | Short hostname of the target server (used in file naming) | None (required) | + +### Dependencies + +No direct Ansible Galaxy role dependencies. However, it relies on Terraform to provision AppRole credentials and Vault secrets. + +### Example Playbook + +Example playbook demonstrating basic role usage: + +```yml +- hosts: webservers + become: true + roles: + - role: consul_template + vars: + vault_address: "https://vault.example.com:8200" + vault_approle_role_id: "{{ vault_approle_role_id }}" + vault_approle_secret_id: "{{ vault_approle_secret_id }}" + environment: "prod" + short_hostname: "web01" +``` + +### License + +BSD + +### Author Information + +Created by Patrick De Ruiter. diff --git a/ansible/roles/consul_template-legacy/defaults/main.yml b/ansible/roles/consul_template-legacy/defaults/main.yml new file mode 100644 index 0000000..5359b0f --- /dev/null +++ b/ansible/roles/consul_template-legacy/defaults/main.yml @@ -0,0 +1,3 @@ +#SPDX-License-Identifier: MIT-0 +--- +# defaults file for consul_template diff --git a/ansible/roles/consul_template-legacy/files/certificate.ctmpl b/ansible/roles/consul_template-legacy/files/certificate.ctmpl new file mode 100644 index 0000000..75e31b2 --- /dev/null +++ b/ansible/roles/consul_template-legacy/files/certificate.ctmpl @@ -0,0 +1,5 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.certificate }} +{{ .Data.data.chain_pem }} +{{ end }} + diff --git a/ansible/roles/consul_template-legacy/files/chain_pem.ctmpl b/ansible/roles/consul_template-legacy/files/chain_pem.ctmpl new file mode 100644 index 0000000..84eb1cf --- /dev/null +++ b/ansible/roles/consul_template-legacy/files/chain_pem.ctmpl @@ -0,0 +1,3 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.chain_pem }} +{{ end }} diff --git a/ansible/roles/consul_template-legacy/files/private_key.ctmpl b/ansible/roles/consul_template-legacy/files/private_key.ctmpl new file mode 100644 index 0000000..7fc178b --- /dev/null +++ b/ansible/roles/consul_template-legacy/files/private_key.ctmpl @@ -0,0 +1,3 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.private_key }} +{{ end }} diff --git a/ansible/roles/consul_template-legacy/handlers/main.yml b/ansible/roles/consul_template-legacy/handlers/main.yml new file mode 100644 index 0000000..c9c97af --- /dev/null +++ b/ansible/roles/consul_template-legacy/handlers/main.yml @@ -0,0 +1,9 @@ +#SPDX-License-Identifier: MIT-0 +--- +# handlers file for consul_template + +- name: restart consul-template + systemd: + name: consul-template + state: restarted + daemon_reload: yes diff --git a/ansible/roles/consul_template-legacy/meta/main.yml b/ansible/roles/consul_template-legacy/meta/main.yml new file mode 100644 index 0000000..4a19692 --- /dev/null +++ b/ansible/roles/consul_template-legacy/meta/main.yml @@ -0,0 +1,20 @@ +#SPDX-License-Identifier: BSD-3-Clause +galaxy_info: +author: Patrick De Ruiter +description: An Ansible role to install and configure consul-template, fetching TLS certificates from HashiCorp Vault using AppRole authentication. +company: “Benerail N.V.” + +license: BSD-3-Clause + +min_ansible_version: 2.10 + +galaxy_tags: +- vault +- consul +- consultemplate +- tls +- certificates +- security +- automation + +dependencies: [] diff --git a/ansible/roles/consul_template-legacy/tasks/main.yml b/ansible/roles/consul_template-legacy/tasks/main.yml new file mode 100644 index 0000000..6978b3d --- /dev/null +++ b/ansible/roles/consul_template-legacy/tasks/main.yml @@ -0,0 +1,86 @@ +- name: Determine architecture + set_fact: + consul_template_arch: "{{ arch_mapping[ansible_architecture] | default('amd64') }}" + +- name: Download consul-template checksum file + get_url: + url: "https://releases.hashicorp.com/consul-template/{{ consul_template.version }}/consul-template_{{ consul_template.version }}_SHA256SUMS" + dest: "/tmp/consul-template_{{ consul_template.version }}_SHA256SUMS" + mode: '0644' + +- name: Extract expected checksum + shell: | + grep "consul-template_{{ consul_template.version }}_linux_{{ consul_template_arch }}.zip" \ + /tmp/consul-template_{{ consul_template.version }}_SHA256SUMS | cut -d' ' -f1 + register: expected_checksum + changed_when: false + +- name: Install consul-template + unarchive: + src: "https://releases.hashicorp.com/consul-template/{{ consul_template.version }}/consul-template_{{ consul_template.version }}_linux_{{ consul_template_arch }}.zip" + dest: "{{ consul_template.install_dir }}" + remote_src: yes + owner: root + group: root + mode: '0755' + checksum: "sha256:{{ expected_checksum.stdout }}" + +- name: Create consul-template user + user: + name: "{{ consul_template.user }}" + group: "{{ consul_template.group }}" + system: yes + shell: /bin/false + home: "{{ consul_template.config_dir }}" + create_home: no + +- name: Create consul-template group + group: + name: "{{ consul_template.group }}" + system: yes + +- name: Create consul-template directories + file: + path: "{{ item.path }}" + state: directory + mode: "{{ item.mode }}" + owner: "{{ item.owner | default('root') }}" + group: "{{ item.group | default('root') }}" + loop: + - { path: "{{ consul_template.config_dir }}", mode: '0755', owner: "{{ consul_template.user }}", group: "{{ consul_template.group }}" } + - { path: "{{ certificate_paths.cert_dir }}", mode: '0755' } + - { path: "{{ certificate_paths.private_dir }}", mode: '0700' } + +- name: Deploy consul-template template files + copy: + src: "{{ item }}" + dest: "{{ consul_template.config_dir }}/{{ item }}" + mode: '0644' + owner: "{{ consul_template.user }}" + group: "{{ consul_template.group }}" + loop: + - certificate.ctmpl + - private_key.ctmpl + - chain_pem.ctmpl + notify: restart consul-template + +- name: Deploy consul-template config + template: + src: consul-template-config.hcl.j2 + dest: "{{ consul_template.config_dir }}/config.hcl" + mode: '0600' + owner: "{{ consul_template.user }}" + group: "{{ consul_template.group }}" + notify: restart consul-template + +- name: Deploy consul-template systemd unit + template: + src: consul-template.service.j2 + dest: /etc/systemd/system/consul-template.service + +- name: Enable and start consul-template + systemd: + name: consul-template + enabled: true + state: started + daemon_reload: yes diff --git a/ansible/roles/consul_template-legacy/templates/consul-template-config.hcl.j2 b/ansible/roles/consul_template-legacy/templates/consul-template-config.hcl.j2 new file mode 100644 index 0000000..244fd6f --- /dev/null +++ b/ansible/roles/consul_template-legacy/templates/consul-template-config.hcl.j2 @@ -0,0 +1,35 @@ +vault { + address = "{{ vault_address }}" + auth { + method "approle" { + config = { + role_id = "{{ vault_approle_role_id }}" + secret_id = "{{ vault_approle_secret_id }}" + } + } + } + renew_token = true +} + +log_level = "{{ consul_template.log_level | default('INFO') }}" + +template { + source = "{{ consul_template.config_dir }}/certificate.ctmpl" + destination = "{{ certificate_paths.cert_dir }}/{{ certificate_paths.cert_file }}" + command = "{{ service_reload_commands[certificate_service | default('default')] }}" + perms = 0644 +} + +template { + source = "{{ consul_template.config_dir }}/private_key.ctmpl" + destination = "{{ certificate_paths.private_dir }}/{{ certificate_paths.private_key_file }}" + command = "chmod 600 {{ certificate_paths.private_dir }}/{{ certificate_paths.private_key_file }}" + perms = 0600 +} + +template { + source = "{{ consul_template.config_dir }}/chain_pem.ctmpl" + destination = "{{ certificate_paths.private_dir }}/{{ certificate_paths.chain_file }}" + command = "chmod 600 {{ certificate_paths.private_dir }}/{{ certificate_paths.chain_file }}" + perms = 0600 +} diff --git a/ansible/roles/consul_template-legacy/templates/consul-template.service.j2 b/ansible/roles/consul_template-legacy/templates/consul-template.service.j2 new file mode 100644 index 0000000..dfd71fa --- /dev/null +++ b/ansible/roles/consul_template-legacy/templates/consul-template.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=consul-template TLS Certificate +After=network-online.target +Wants=network-online.target + +[Service] +Type=notify +User={{ consul_template.user }} +Group={{ consul_template.group }} +ExecStart={{ consul_template.install_dir }}/consul-template \ + -config={{ consul_template.config_dir }}/config.hcl +ExecReload=/bin/kill -HUP $MAINPID +KillMode=process +Restart=on-failure +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target diff --git a/ansible/roles/consul_template-legacy/tests/inventory b/ansible/roles/consul_template-legacy/tests/inventory new file mode 100644 index 0000000..03ca42f --- /dev/null +++ b/ansible/roles/consul_template-legacy/tests/inventory @@ -0,0 +1,3 @@ +#SPDX-License-Identifier: MIT-0 +localhost + diff --git a/ansible/roles/consul_template-legacy/tests/test.yml b/ansible/roles/consul_template-legacy/tests/test.yml new file mode 100644 index 0000000..077eae4 --- /dev/null +++ b/ansible/roles/consul_template-legacy/tests/test.yml @@ -0,0 +1,6 @@ +#SPDX-License-Identifier: MIT-0 +--- +- hosts: localhost + remote_user: root + roles: + - consul_template diff --git a/ansible/roles/consul_template-legacy/vars/main.yml b/ansible/roles/consul_template-legacy/vars/main.yml new file mode 100644 index 0000000..acb5b57 --- /dev/null +++ b/ansible/roles/consul_template-legacy/vars/main.yml @@ -0,0 +1,3 @@ +#SPDX-License-Identifier: MIT-0 +--- +# vars file for consul_template diff --git a/ansible/roles/consul_template-org b/ansible/roles/consul_template-org deleted file mode 160000 index 7c00f1e..0000000 --- a/ansible/roles/consul_template-org +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7c00f1e5e059869c33291948282e7772e5427562 diff --git a/ansible/roles/consul_template-org/files/certificate.ctmpl b/ansible/roles/consul_template-org/files/certificate.ctmpl new file mode 100644 index 0000000..75e31b2 --- /dev/null +++ b/ansible/roles/consul_template-org/files/certificate.ctmpl @@ -0,0 +1,5 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.certificate }} +{{ .Data.data.chain_pem }} +{{ end }} + diff --git a/ansible/roles/consul_template-org/files/chain_pem.ctmpl b/ansible/roles/consul_template-org/files/chain_pem.ctmpl new file mode 100644 index 0000000..84eb1cf --- /dev/null +++ b/ansible/roles/consul_template-org/files/chain_pem.ctmpl @@ -0,0 +1,3 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.chain_pem }} +{{ end }} diff --git a/ansible/roles/consul_template-org/files/private_key.ctmpl b/ansible/roles/consul_template-org/files/private_key.ctmpl new file mode 100644 index 0000000..7fc178b --- /dev/null +++ b/ansible/roles/consul_template-org/files/private_key.ctmpl @@ -0,0 +1,3 @@ +{{ with secret "secret/data/{{ environment }}/{{ short_hostname }}/certificate" }} +{{ .Data.data.private_key }} +{{ end }} diff --git a/ansible/roles/consul_template-org/tasks/main.yml b/ansible/roles/consul_template-org/tasks/main.yml new file mode 100644 index 0000000..f8bdbd8 --- /dev/null +++ b/ansible/roles/consul_template-org/tasks/main.yml @@ -0,0 +1,33 @@ +- name: Install consul-template + unarchive: + src: "https://releases.hashicorp.com/consul-template/0.37.4/consul-template_0.37.4_linux_amd64.zip" + dest: /usr/local/bin + remote_src: yes + +- name: Create consul-template directories + file: + path: "{{ item }}" + state: directory + mode: '0755' + loop: + - /etc/consul-template + - /etc/ssl/certs + - /etc/ssl/private + +- name: Deploy consul-template config + template: + src: consul-template-config.hcl.j2 + dest: /etc/consul-template/config.hcl + mode: '0600' + +- name: Deploy consul-template systemd unit + template: + src: consul-template.service.j2 + dest: /etc/systemd/system/consul-template.service + +- name: Enable and start consul-template + systemd: + name: consul-template + enabled: true + state: restarted + daemon_reload: yes diff --git a/ansible/roles/consul_template-org/templates/consul-template-config.hcl.j2 b/ansible/roles/consul_template-org/templates/consul-template-config.hcl.j2 new file mode 100644 index 0000000..2636720 --- /dev/null +++ b/ansible/roles/consul_template-org/templates/consul-template-config.hcl.j2 @@ -0,0 +1,30 @@ +vault { + address = "{{ vault_address }}" + auth { + method "approle" { + config = { + role_id = "{{ vault_approle_role_id }}" + secret_id = "{{ vault_approle_secret_id }}" + } + } + } + renew_token = true +} + +template { + source = "/etc/consul-template/certificate.ctmpl" + destination = "/etc/ssl/certs/{{ short_hostname }}.pem" + command = "systemctl reload nginx" +} + +template { + source = "/etc/consul-template/private_key.ctmpl" + destination = "/etc/ssl/private/{{ short_hostname }}.key" + command = "chmod 600 /etc/ssl/private/{{ short_hostname }}.key" +} + +template { + source = "/etc/consul-template/chain_pem.ctmpl" + destination = "/etc/ssl/private/le-chaincert.pem" + command = "chmod 600 /etc/ssl/private/le-chaincert.pem" +} diff --git a/ansible/roles/consul_template-org/templates/consul-template.service.j2 b/ansible/roles/consul_template-org/templates/consul-template.service.j2 new file mode 100644 index 0000000..55453b5 --- /dev/null +++ b/ansible/roles/consul_template-org/templates/consul-template.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=consul-template TLS Certificate +After=network-online.target + +[Service] +ExecStart=/usr/local/bin/consul-template \ + -config=/etc/consul-template/config.hcl +Restart=always + +[Install] +WantedBy=multi-user.target