redeploy authentic policies as code.
This commit is contained in:
6
ansible/playbooks/deploy_common.yml
Normal file
6
ansible/playbooks/deploy_common.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Apply common role
|
||||
hosts: "{{ target | default('all') }}"
|
||||
become: true
|
||||
roles:
|
||||
- common
|
||||
7
ansible/playbooks/enroll_step_ca_client.yml
Normal file
7
ansible/playbooks/enroll_step_ca_client.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Enroll host as step-ca SSH client
|
||||
hosts: "{{ target | default('all') }}"
|
||||
become: true
|
||||
tasks:
|
||||
- name: Include step-ca client enrollment
|
||||
ansible.builtin.include_tasks: roles/common/tasks/step_ca_client.yml
|
||||
15
ansible/playbooks/install_talosctl.yml
Normal file
15
ansible/playbooks/install_talosctl.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# ------------------------------------------------------------------------------
|
||||
# FILE: playbooks/install_talosctl.yml
|
||||
# DESCRIPTION: Install talosctl on city-hall for managing the fastpass cluster.
|
||||
# USAGE:
|
||||
# cd ansible
|
||||
# ansible-playbook -i inventory.yml playbooks/install_talosctl.yml
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
- name: Install talosctl
|
||||
hosts: talos_control
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- talosctl
|
||||
@@ -1,20 +1,25 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
---
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# FILE: roles/authentik/tasks/main.yml
|
||||
# DESCRIPTION: Deploys Authentik from boilerplate-generated files in the repo.
|
||||
# The compose.yaml lives in boilerplates/authentik/.
|
||||
# The .env file is templated to inject secrets from Ansible vault.
|
||||
# ------------------------------------------------------------------------------
|
||||
# Custom blueprints are synced from boilerplates/authentik/blueprints/.
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
- name: Create Authentik directory structure
|
||||
file:
|
||||
path: "{{ authentik_base_dir }}"
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ ansible_user }}"
|
||||
group: docker
|
||||
mode: '0775'
|
||||
loop:
|
||||
- "{{ authentik_base_dir }}"
|
||||
- "{{ authentik_base_dir }}/blueprints"
|
||||
|
||||
- name: Copy compose.yaml from boilerplate
|
||||
copy:
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/../../boilerplates/authentik/compose.yaml"
|
||||
dest: "{{ authentik_base_dir }}/compose.yaml"
|
||||
owner: "{{ ansible_user }}"
|
||||
@@ -22,8 +27,17 @@
|
||||
mode: '0644'
|
||||
notify: restart authentik
|
||||
|
||||
- name: Sync custom blueprints
|
||||
ansible.builtin.copy:
|
||||
src: "{{ playbook_dir }}/../../boilerplates/authentik/blueprints/"
|
||||
dest: "{{ authentik_base_dir }}/blueprints/"
|
||||
owner: "{{ ansible_user }}"
|
||||
group: docker
|
||||
mode: '0644'
|
||||
notify: restart authentik
|
||||
|
||||
- name: Deploy .env with secrets from vault
|
||||
template:
|
||||
ansible.builtin.template:
|
||||
src: env.j2
|
||||
dest: "{{ authentik_base_dir }}/.env"
|
||||
owner: "{{ ansible_user }}"
|
||||
|
||||
@@ -2,3 +2,10 @@
|
||||
AUTHENTIK_SECRET_KEY={{ authentik_secret_key }}
|
||||
DATABASE_PASSWORD={{ authentik_database_password }}
|
||||
AUTHENTIK_ADMIN_PASSWORD={{ authentik_admin_password }}
|
||||
|
||||
# OIDC client credentials for blueprints
|
||||
# These are substituted into blueprint YAML via ${VAR} syntax
|
||||
PROXMOX_OIDC_CLIENT_ID={{ vault_proxmox_oidc_client_id }}
|
||||
PROXMOX_OIDC_CLIENT_SECRET={{ vault_proxmox_oidc_client_secret }}
|
||||
STEPCA_OIDC_CLIENT_ID={{ vault_stepca_oidc_client_id }}
|
||||
STEPCA_OIDC_CLIENT_SECRET={{ vault_stepca_oidc_client_secret }}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
name: "{{ inventory_hostname | replace('_', '-') }}"
|
||||
|
||||
- name: Set timezone
|
||||
timezone:
|
||||
community.general.timezone:
|
||||
name: "{{ common_timezone }}"
|
||||
|
||||
- name: Update apt cache
|
||||
@@ -52,3 +52,30 @@
|
||||
# --- Step-CA SSH certificate enrollment ---
|
||||
- name: Enroll host in step-ca SSH CA
|
||||
include_tasks: step_ca_client.yml
|
||||
|
||||
- name: Create authorized principals directory
|
||||
ansible.builtin.file:
|
||||
path: /etc/ssh/auth_principals
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
|
||||
- name: Create authorized principals files
|
||||
ansible.builtin.copy:
|
||||
content: "{{ item.principals | join('\n') }}\n"
|
||||
dest: "/etc/ssh/auth_principals/{{ item.local_user }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
loop: "{{ step_ca_principal_mappings }}"
|
||||
notify: restart sshd
|
||||
|
||||
- name: Configure sshd AuthorizedPrincipalsFile
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
line: "AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u"
|
||||
regexp: "^#?AuthorizedPrincipalsFile"
|
||||
state: present
|
||||
notify: restart sshd
|
||||
|
||||
@@ -95,3 +95,29 @@
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ stepca_base_dir }}"
|
||||
state: present
|
||||
|
||||
- name: Template OIDC provisioner patch script
|
||||
ansible.builtin.template:
|
||||
src: patch_oidc_provisioner.py.j2
|
||||
dest: "{{ stepca_base_dir }}/patch_oidc_provisioner.py"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
no_log: true
|
||||
|
||||
- name: Patch OIDC provisioner in ca.json
|
||||
ansible.builtin.command:
|
||||
cmd: python3 {{ stepca_base_dir }}/patch_oidc_provisioner.py
|
||||
register: oidc_patch_result
|
||||
changed_when: "'CHANGED' in oidc_patch_result.stdout"
|
||||
|
||||
- name: Restart step-ca if OIDC provisioner changed
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ stepca_base_dir }}"
|
||||
state: restarted
|
||||
when: oidc_patch_result is changed
|
||||
|
||||
- name: Clean up patch script
|
||||
ansible.builtin.file:
|
||||
path: "{{ stepca_base_dir }}/patch_oidc_provisioner.py"
|
||||
state: absent
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
# Managed by Ansible — do not edit manually
|
||||
# Patches the OIDC provisioner in step-ca's ca.json with values from Ansible vars
|
||||
import json
|
||||
import sys
|
||||
|
||||
ca_json_path = "{{ stepca_data_dir }}/config/ca.json"
|
||||
provisioner_name = "{{ stepca_oidc_provisioner_name }}"
|
||||
desired_domains = {{ stepca_oidc_domains | to_json }}
|
||||
desired_client_id = "{{ stepca_oidc_client_id }}"
|
||||
desired_client_secret = "{{ stepca_oidc_client_secret }}"
|
||||
desired_config_endpoint = "{{ stepca_oidc_configuration_endpoint }}"
|
||||
desired_listen_address = "{{ stepca_oidc_listen_address }}"
|
||||
|
||||
with open(ca_json_path) as f:
|
||||
cfg = json.load(f)
|
||||
|
||||
changed = False
|
||||
found = False
|
||||
|
||||
for p in cfg["authority"]["provisioners"]:
|
||||
if p.get("name") == provisioner_name and p.get("type") == "OIDC":
|
||||
found = True
|
||||
updates = {
|
||||
"domains": desired_domains,
|
||||
"clientID": desired_client_id,
|
||||
"clientSecret": desired_client_secret,
|
||||
"configurationEndpoint": desired_config_endpoint,
|
||||
"listenAddress": desired_listen_address,
|
||||
}
|
||||
for key, value in updates.items():
|
||||
if p.get(key) != value:
|
||||
p[key] = value
|
||||
changed = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
# Add the OIDC provisioner if it doesn't exist
|
||||
cfg["authority"]["provisioners"].append({
|
||||
"type": "OIDC",
|
||||
"name": provisioner_name,
|
||||
"clientID": desired_client_id,
|
||||
"clientSecret": desired_client_secret,
|
||||
"configurationEndpoint": desired_config_endpoint,
|
||||
"domains": desired_domains,
|
||||
"listenAddress": desired_listen_address,
|
||||
"claims": {"enableSSHCA": True},
|
||||
"options": {"x509": {}, "ssh": {}},
|
||||
})
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
with open(ca_json_path, "w") as f:
|
||||
json.dump(cfg, f, indent=8)
|
||||
print("CHANGED")
|
||||
else:
|
||||
print("OK")
|
||||
15
ansible/playbooks/roles/talosctl/defaults/main.yml
Normal file
15
ansible/playbooks/roles/talosctl/defaults/main.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# ------------------------------------------------------------------------------
|
||||
# FILE: roles/talosctl/defaults/main.yml
|
||||
# DESCRIPTION: Default variables for talosctl installation.
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Pin to a specific version for reproducibility.
|
||||
# Update this when upgrading the fastpass cluster.
|
||||
talosctl_version: "v1.12.4"
|
||||
|
||||
# Architecture of the target host (amd64 or arm64)
|
||||
talosctl_arch: "amd64"
|
||||
|
||||
# Where to install the binary
|
||||
talosctl_install_dir: "/usr/local/bin"
|
||||
51
ansible/playbooks/roles/talosctl/main.yml
Normal file
51
ansible/playbooks/roles/talosctl/main.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
# ------------------------------------------------------------------------------
|
||||
# FILE: roles/talosctl/tasks/main.yml
|
||||
# DESCRIPTION: Install talosctl binary from GitHub releases.
|
||||
# Downloads a pinned version, installs to /usr/local/bin,
|
||||
# and verifies the installation.
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
- name: Check if talosctl is already installed
|
||||
stat:
|
||||
path: "{{ talosctl_install_dir }}/talosctl"
|
||||
register: talosctl_binary
|
||||
|
||||
- name: Get installed talosctl version
|
||||
command: "{{ talosctl_install_dir }}/talosctl version --client --short"
|
||||
register: talosctl_installed_version
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: talosctl_binary.stat.exists
|
||||
|
||||
- name: Install talosctl
|
||||
when: >
|
||||
not talosctl_binary.stat.exists or
|
||||
talosctl_version not in (talosctl_installed_version.stdout | default(''))
|
||||
block:
|
||||
- name: Download talosctl {{ talosctl_version }}
|
||||
get_url:
|
||||
url: "https://github.com/siderolabs/talos/releases/download/{{ talosctl_version }}/talosctl-linux-{{ talosctl_arch }}"
|
||||
dest: "/tmp/talosctl"
|
||||
mode: "0755"
|
||||
|
||||
- name: Install talosctl to {{ talosctl_install_dir }}
|
||||
copy:
|
||||
src: "/tmp/talosctl"
|
||||
dest: "{{ talosctl_install_dir }}/talosctl"
|
||||
mode: "0755"
|
||||
remote_src: true
|
||||
|
||||
- name: Clean up downloaded binary
|
||||
file:
|
||||
path: "/tmp/talosctl"
|
||||
state: absent
|
||||
|
||||
- name: Verify talosctl installation
|
||||
command: "{{ talosctl_install_dir }}/talosctl version --client --short"
|
||||
register: talosctl_verify
|
||||
changed_when: false
|
||||
|
||||
- name: Display installed talosctl version
|
||||
debug:
|
||||
msg: "talosctl installed: {{ talosctl_verify.stdout }}"
|
||||
17
ansible/playbooks/roles/talosctl/meta/main.yml
Normal file
17
ansible/playbooks/roles/talosctl/meta/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# ------------------------------------------------------------------------------
|
||||
# FILE: roles/talosctl/meta/main.yml
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
galaxy_info:
|
||||
author: rblundon
|
||||
description: Install talosctl CLI for managing TalosOS clusters
|
||||
license: MIT
|
||||
min_ansible_version: "2.14"
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- noble
|
||||
|
||||
dependencies:
|
||||
- role: common
|
||||
Reference in New Issue
Block a user