feat(custodian-agent): Ansible role + Makefile for Custodian SSH identity
Establishes a dedicated SSH keypair for the Custodian automation agent: - ansible/roles/custodian_agent/: authorized_key task (tagged custodian_agent) - ansible/inventory/group_vars/all.yaml: custodian_agent_user/pubkey vars - ansible/playbooks/bootstrap.yaml: custodian_agent role added - Makefile: provision-custodian-agent / provision-custodian-agent-host targets Keypair generation: cd ~/the-custodian && make custodian-keygen Then deploy: cd ~/railiance-infra && make provision-custodian-agent The private key lives at ~/.ssh/id_custodian_agent — never committed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
caa6ae36da
commit
30a3f908aa
4 changed files with 83 additions and 1 deletions
16
Makefile
16
Makefile
|
|
@ -130,9 +130,23 @@ backup: ## Backup S1 OS config to /opt/backup/railiance/infra/ (age-encrypted, r
|
||||||
sudo tools/cmd/railiance-backup-s1
|
sudo tools/cmd/railiance-backup-s1
|
||||||
|
|
||||||
# ---- Ansible ----
|
# ---- Ansible ----
|
||||||
ansible-bootstrap: ## Run base bootstrap play (users, ssh, ufw, sops-agent)
|
ansible-bootstrap: ## Run base bootstrap play (users, ssh, ufw, sops-agent, custodian-agent)
|
||||||
cd ansible && ansible-playbook playbooks/bootstrap.yaml -u admin
|
cd ansible && ansible-playbook playbooks/bootstrap.yaml -u admin
|
||||||
|
|
||||||
|
provision-custodian-agent: ## Deploy custodian agent SSH key to all managed hosts
|
||||||
|
@python3 -c "import yaml; d=yaml.safe_load(open('ansible/inventory/group_vars/all.yaml')); k=d.get('custodian_agent_pubkey',''); exit(0 if k else 1)" \
|
||||||
|
|| (echo "ERROR: custodian_agent_pubkey is empty. Run: cd ~/the-custodian && make custodian-keygen"; exit 1)
|
||||||
|
cd ansible && ansible-playbook playbooks/bootstrap.yaml -u $(SSH_USER) \
|
||||||
|
--tags custodian_agent \
|
||||||
|
--extra-vars "@inventory/group_vars/all.yaml"
|
||||||
|
|
||||||
|
provision-custodian-agent-host: ## Deploy custodian agent key to one host: make provision-custodian-agent-host HOST=railiance01
|
||||||
|
@test -n "$(HOST)" || (echo "Usage: make provision-custodian-agent-host HOST=<name>"; exit 1)
|
||||||
|
cd ansible && ansible-playbook playbooks/bootstrap.yaml -u $(SSH_USER) \
|
||||||
|
--limit "$(HOST)" \
|
||||||
|
--tags custodian_agent \
|
||||||
|
--extra-vars "@inventory/group_vars/all.yaml"
|
||||||
|
|
||||||
# ---- Orchestration ----
|
# ---- Orchestration ----
|
||||||
apply: tf-fmt tf-apply ansible-bootstrap ## Provision via Terraform then converge via Ansible
|
apply: tf-fmt tf-apply ansible-bootstrap ## Provision via Terraform then converge via Ansible
|
||||||
|
|
||||||
|
|
|
||||||
20
ansible/inventory/group_vars/all.yaml
Normal file
20
ansible/inventory/group_vars/all.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Ansible group vars — applied to all managed hosts.
|
||||||
|
#
|
||||||
|
# custodian_agent_pubkey: the SSH public key for the Custodian automation identity.
|
||||||
|
#
|
||||||
|
# HOW TO SET THIS:
|
||||||
|
# 1. Generate the keypair on the workstation (one-time):
|
||||||
|
# cd ~/the-custodian && make custodian-keygen
|
||||||
|
# This creates ~/.ssh/id_custodian_agent (private, never committed)
|
||||||
|
# and writes the public key to:
|
||||||
|
# ~/railiance-infra/ansible/inventory/group_vars/all.yaml ← this file
|
||||||
|
#
|
||||||
|
# 2. Commit the updated all.yaml (public key only — safe to commit).
|
||||||
|
#
|
||||||
|
# 3. Deploy to all managed hosts:
|
||||||
|
# cd ~/railiance-infra && make provision-custodian-agent
|
||||||
|
#
|
||||||
|
# The key below is a placeholder — replace by running `make custodian-keygen`.
|
||||||
|
|
||||||
|
custodian_agent_user: tegwick
|
||||||
|
custodian_agent_pubkey: ""
|
||||||
|
|
@ -6,4 +6,5 @@
|
||||||
roles:
|
roles:
|
||||||
- role: base
|
- role: base
|
||||||
- role: sops_agent
|
- role: sops_agent
|
||||||
|
- role: custodian_agent # injects ~/.ssh/id_custodian_agent.pub into authorized_keys
|
||||||
# - role: wireguard # enable if you configure WireGuard variables
|
# - role: wireguard # enable if you configure WireGuard variables
|
||||||
|
|
|
||||||
47
ansible/roles/custodian_agent/tasks/main.yml
Normal file
47
ansible/roles/custodian_agent/tasks/main.yml
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
---
|
||||||
|
# custodian_agent role — injects the Custodian automation SSH identity
|
||||||
|
#
|
||||||
|
# What it does:
|
||||||
|
# - Ensures the target user (custodian_agent_user) exists
|
||||||
|
# - Adds custodian_agent_pubkey to that user's authorized_keys
|
||||||
|
# - Restricts the key: no X11, no port-forward, no pty for non-interactive use
|
||||||
|
#
|
||||||
|
# Variables (set in group_vars/all.yaml or pass via --extra-vars):
|
||||||
|
# custodian_agent_user: user account the key is added to (default: tegwick)
|
||||||
|
# custodian_agent_pubkey: the public key string (required, set in all.yaml)
|
||||||
|
#
|
||||||
|
# The private key lives on the workstation at ~/.ssh/id_custodian_agent.
|
||||||
|
# It is NEVER committed to any repository.
|
||||||
|
|
||||||
|
- name: Ensure target user exists
|
||||||
|
tags: [custodian_agent]
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ custodian_agent_user | default('tegwick') }}"
|
||||||
|
state: present
|
||||||
|
shell: /bin/bash
|
||||||
|
create_home: true
|
||||||
|
|
||||||
|
- name: Ensure .ssh directory exists for target user
|
||||||
|
tags: [custodian_agent]
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/home/{{ custodian_agent_user | default('tegwick') }}/.ssh"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ custodian_agent_user | default('tegwick') }}"
|
||||||
|
group: "{{ custodian_agent_user | default('tegwick') }}"
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: Add custodian agent public key to authorized_keys
|
||||||
|
tags: [custodian_agent]
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ custodian_agent_user | default('tegwick') }}"
|
||||||
|
key: "{{ custodian_agent_pubkey }}"
|
||||||
|
key_options: "no-X11-forwarding,no-agent-forwarding"
|
||||||
|
comment: "custodian-agent@{{ inventory_hostname }}"
|
||||||
|
state: present
|
||||||
|
when: custodian_agent_pubkey is defined and custodian_agent_pubkey | length > 0
|
||||||
|
|
||||||
|
- name: Warn if custodian_agent_pubkey is not set
|
||||||
|
tags: [custodian_agent]
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "WARNING: custodian_agent_pubkey is not set — skipping authorized_keys injection"
|
||||||
|
when: custodian_agent_pubkey is not defined or custodian_agent_pubkey | length == 0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue