new files from source

This commit is contained in:
thesabear committed 2026-06-09 10:20:07 +03:00
commit 973546647d
132 files changed
+5335

No files matched your search

@@ -0,0 +1,41 @@
---
vault_addr: "http://VAULT_IP:VAULT_PORT"
vault_agent_config_path: "/etc/vault-agent-config.hcl"
vault_agent_pid_file: "/var/run/vault-agent.pid"
vault_agent_user: "root"
vault_agent_service: "vault-agent"
vault_agent_systemd_unit: "/etc/systemd/system/vault-agent.service"
# Paths to role_id / secret_id files (written by bootstrap process)
vault_role_id_file: "/etc/vault-agent/role_id"
vault_secret_id_file: "/etc/vault-agent/secret_id"
# Templates
vault_templates_dir: "/etc/vault-agent-templates"
vault_agent_templates:
# HAProxy
- src: "haproxy.pem.ctmpl"
dest: "/etc/haproxy/certs/haproxy.pem"
service: haproxy
- src: "haproxy_ca.ctmpl"
dest: "/etc/haproxy/certs/haproxy_ca.crt"
service: haproxy
- src: "thesabear-client.ctmpl"
dest: "/etc/haproxy/certs/clients/thesabear-client.pem"
service: "haproxy"
# Technitium
- src: "technitium_cert.ctmpl"
dest: "/etc/technitium/certs/technitium.crt"
service: technitium
- src: "technitium_key.ctmpl"
dest: "/etc/technitium/certs/technitium.key"
service: technitium
- src: "technitium_ca.ctmpl"
dest: "/etc/technitium/certs/technitium_ca.crt"
service: technitium
# Default Vault PKI options (can remain)
pki_mount_path: "pki"
@@ -0,0 +1,3 @@
{{- with secret "pki/cert/ca" -}}
{{ trim .Data.certificate "\n" }}
{{- end }}
@@ -0,0 +1,7 @@
{% raw %}
{{- with secret "pki/issue/{{ wildcard_role_name }}" "common_name={{ common_name }}" -}}
{{ .Data.certificate }}
{{ .Data.private_key }}
{{ .Data.issuing_ca }}
{{- end }}
{% endraw %}
@@ -0,0 +1,6 @@
{{ with secret "pki/issue/securevault-wildcard" "common_name=*.local.DOMAIN_PLACEHOLDER" "ttl=8760h" }}
{{ .Data.certificate }}
{{ .Data.issuing_ca }}
{{ .Data.private_key }}
{{ end }}
@@ -0,0 +1,3 @@
{{- with secret "pki/issue/securevault-wildcard" "common_name=*.local.DOMAIN_PLACEHOLDER" -}}
{{ .Data.issuing_ca }}
{{- end }}
@@ -0,0 +1,3 @@
{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}}
{{ .Data.issuing_ca }}
{{- end }}
@@ -0,0 +1,3 @@
{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}}
{{ .Data.certificate }}
{{- end }}
@@ -0,0 +1,3 @@
{{- with secret "pki_int/issue/securevault-wildcard" "common_name=technitium.local.DOMAIN_PLACEHOLDER" -}}
{{ .Data.private_key }}
{{- end }}
@@ -0,0 +1,6 @@
{{ with secret "pki_int/issue/mtls-client-cert" "common_name=clientname.local.DOMAIN_PLACEHOLDER" "ttl=8760h" }}
{{ .Data.certificate }}
{{ .Data.private_key }}
{{ .Data.issuing_ca }}
{{ end }}
@@ -0,0 +1,3 @@
---
- name: Reload systemd
command: systemctl daemon-reload
@@ -0,0 +1,230 @@
---
# ==========================================================
# 1️⃣ Install Vault and Dependencies
# ==========================================================
- name: Ensure HashiCorp repository (RHEL9)
ansible.builtin.copy:
dest: /etc/yum.repos.d/hashicorp.repo
mode: "0644"
content: |
[hashicorp]
name=HashiCorp Stable Repository
baseurl=https://rpm.releases.hashicorp.com/RHEL/9/x86_64/stable/
enabled=1
gpgcheck=1
gpgkey=https://rpm.releases.hashicorp.com/gpg
- name: Install Vault (includes vault-agent)
ansible.builtin.dnf:
name: vault
state: present
# ==========================================================
# 2️⃣ Firewall Configuration
# ==========================================================
- name: Ensure firewalld is running and enabled
ansible.builtin.systemd:
name: firewalld
enabled: true
state: started
- name: Allow outbound access to Vault (VAULT_PORT/tcp)
ansible.posix.firewalld:
rich_rule: >
rule family="ipv4"
destination address="VAULT_IP"
port port="VAULT_PORT" protocol="tcp" accept
permanent: true
state: enabled
immediate: true
# ==========================================================
# 3️⃣ Vault-Agent Directories and Configs
# ==========================================================
- name: Ensure Vault-Agent directories exist
ansible.builtin.file:
path: "{{ vault_dir.path }}"
state: directory
owner: root
group: root
mode: "{{ vault_dir.mode | default('0750') }}"
loop:
- { path: "{{ vault_templates_dir }}" }
- { path: "/etc/vault-agent", mode: "0700" }
loop_control:
loop_var: vault_dir
- name: Deploy Vault-Agent configuration
ansible.builtin.template:
src: vault-agent-config.hcl.j2
dest: "{{ vault_agent_config_path }}"
owner: root
group: root
mode: "0600"
- name: Install Vault-Agent systemd unit
ansible.builtin.template:
src: vault-agent.service.j2
dest: "{{ vault_agent_systemd_unit }}"
owner: root
group: root
mode: "0644"
notify: Reload systemd
- name: Enable Vault-Agent but do not start yet
ansible.builtin.systemd:
name: "{{ vault_agent_service }}"
enabled: true
state: stopped
# ==========================================================
# 4️⃣ Vault-Agent Templates and Cert Paths
# ==========================================================
- name: Copy Vault-Agent templates
ansible.builtin.copy:
src: "{{ vault_item.src }}"
dest: "{{ vault_templates_dir }}/{{ vault_item.src | basename }}"
owner: root
group: root
mode: "0600"
loop: "{{ vault_agent_templates }}"
loop_control:
loop_var: vault_item
- name: Ensure directories for Vault-rendered files exist
ansible.builtin.file:
path: "{{ vault_template.dest | dirname }}"
state: directory
owner: root
group: root
mode: "0755"
loop: "{{ vault_agent_templates }}"
loop_control:
loop_var: vault_template
- name: Start Vault-Agent (now that templates exist)
ansible.builtin.systemd:
name: "{{ vault_agent_service }}"
state: started
# ==========================================================
# 5️⃣ AppRole Authentication Setup
# ==========================================================
- name: Fetch AppRole credentials for this host
delegate_to: localhost
block:
- name: Get role_id
ansible.builtin.command:
cmd: >
vault read -field=role_id auth/approle/role/{{ inventory_hostname }}-role/role-id
register: role_id_raw
changed_when: false
failed_when: role_id_raw.stdout | trim == ""
environment:
VAULT_ADDR: "http://VAULT_IP:VAULT_PORT"
VAULT_TOKEN: "{{ vault_token }}"
- name: Get secret_id
ansible.builtin.command:
cmd: >
vault write -f -field=secret_id auth/approle/role/{{ inventory_hostname }}-role/secret-id
register: secret_id_raw
changed_when: false
failed_when: secret_id_raw.stdout | trim == ""
environment:
VAULT_ADDR: "http://VAULT_IP:VAULT_PORT"
VAULT_TOKEN: "{{ vault_token }}"
- name: Write AppRole credentials to Vault-Agent directory
ansible.builtin.copy:
dest: "/etc/vault-agent/{{ cred.name }}"
content: "{{ cred.content }}"
owner: root
group: root
mode: "0600"
loop:
- { name: "role_id", content: "{{ role_id_raw.stdout | trim }}" }
- { name: "secret_id", content: "{{ secret_id_raw.stdout | trim }}" }
loop_control:
loop_var: cred
label: "{{ cred.name }}"
# ==========================================================
# 6️⃣ Register Service in Vault
# ==========================================================
- name: Login to Vault with AppRole and register VM
delegate_to: localhost
block:
- name: Login to Vault with AppRole
ansible.builtin.command:
cmd: >
vault write -field=token auth/approle/login
role_id={{ role_id_raw.stdout | trim }}
secret_id={{ secret_id_raw.stdout | trim }}
register: vault_login
changed_when: false
environment:
VAULT_ADDR: "http://VAULT_IP:VAULT_PORT"
- name: Register VM IP in Vault KV
ansible.builtin.uri:
url: "http://VAULT_IP:VAULT_PORT/v1/kv/data/services/{{ inventory_hostname }}"
method: POST
headers:
X-Vault-Token: "{{ vault_login.stdout }}"
body:
data:
ip: "{{ ansible_default_ipv4.address }}"
body_format: json
status_code: [200, 204]
# ==========================================================
# 7️⃣ SELinux Context for Vault Rendered Paths
# ==========================================================
- name: Check if SELinux is enforcing
ansible.builtin.command: getenforce
register: selinux_status
changed_when: false
failed_when: false
- name: Gather all Vault-Agent template and rendered paths
ansible.builtin.set_fact:
all_vault_paths: >-
{{
(
(vault_agent_templates | default([]) | map(attribute='dest') | map('dirname') | list)
+
(vault_agent_templates | default([]) | map(attribute='dest') | list)
) | unique
}}
when: vault_agent_templates is defined and vault_agent_templates | length > 0
- name: Filter only paths that exist on the host
ansible.builtin.find:
paths: "{{ all_vault_paths }}"
file_type: directory
register: existing_selinux_paths
when: all_vault_paths is defined and all_vault_paths | length > 0
- name: Apply SELinux fcontext to all existing Vault paths
ansible.builtin.command:
cmd: semanage fcontext -a -t etc_t '{{ selinux_path_item.path }}(/.*)?'
loop: "{{ existing_selinux_paths.files | default([]) }}"
loop_control:
loop_var: selinux_path_item
ignore_errors: true
when: selinux_status.stdout == "Enforcing"
- name: Restore SELinux context for all existing Vault paths
ansible.builtin.command:
cmd: restorecon -Rv "{{ selinux_path_item.path }}"
loop: "{{ existing_selinux_paths.files | default([]) }}"
loop_control:
loop_var: selinux_path_item
ignore_errors: true
when: selinux_status.stdout == "Enforcing"
- name: Warn if SELinux is not enforcing
ansible.builtin.debug:
msg: "⚠️ SELinux is not enforcing — Vault-Agent directories may not be properly confined."
when: selinux_status.stdout != "Enforcing"
@@ -0,0 +1,30 @@
pid_file = "{{ vault_agent_pid_file }}"
auto_auth {
method {
type = "approle"
config = {
role_id_file_path = "{{ vault_role_id_file }}"
secret_id_file_path = "{{ vault_secret_id_file }}"
remove_secret_id_file_after_reading = false
}
}
sink {
type = "file"
config = {
path = "/etc/vault-token"
}
}
}
{% for tpl in vault_agent_templates if tpl.service == hostvars[inventory_hostname].service %}
template {
source = "{{ vault_templates_dir }}/{{ tpl.src }}"
destination = "{{ tpl.dest }}"
perms = "0644"
}
{% endfor %}
vault {
address = "{{ vault_addr }}"
}
@@ -0,0 +1,13 @@
[Unit]
Description=Vault Agent
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/bin/vault agent -config={{ vault_agent_config_path }}
Restart=always
RestartSec=5
User={{ vault_agent_user }}
[Install]
WantedBy=multi-user.target