Files
homelab-ansible-lxc-meridian/roles/meridian/tasks/main.yml
T
Your Name 5e16fee73b initial scaffold: Meridian LXC (Node 22 + npm @rynfar/meridian + systemd)
Deploys @rynfar/meridian on a Debian 12 LXC, bound to 0.0.0.0:3456.
OAuth credentials transferred manually after first deploy (claude login on
Mac, scp ~/.claude to /opt/meridian/.claude). systemd unit is enabled but
gated on credentials.json existence so the first deploy doesn't crash-loop.

LXC has no auth layer — security model is LAN-only reachability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 21:20:41 -04:00

176 lines
4.4 KiB
YAML

---
# ---------- System setup ----------
- name: Set timezone
copy:
content: "{{ timezone }}"
dest: /etc/timezone
owner: root
group: root
mode: '0644'
- name: Link localtime
file:
src: "/usr/share/zoneinfo/{{ timezone }}"
dest: /etc/localtime
state: link
force: true
- name: Install base packages
apt:
name: "{{ packages }}"
state: present
update_cache: true
cache_valid_time: 3600
- name: Ensure users exist
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
shell: "{{ item.shell }}"
append: true
loop: "{{ users }}"
- name: Authorize SSH keys for cbalders
authorized_key:
user: cbalders
key: "{{ item }}"
state: present
loop: "{{ ssh_authorized_keys }}"
- name: Passwordless sudo for cbalders
copy:
content: "cbalders ALL=(ALL) NOPASSWD:ALL\n"
dest: /etc/sudoers.d/90-cbalders
owner: root
group: root
mode: '0440'
# ---------- Node 22 (NodeSource apt repo) ----------
- name: Ensure /etc/apt/keyrings exists
file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Add NodeSource GPG key
get_url:
url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key
dest: /etc/apt/keyrings/nodesource.asc
mode: '0644'
- name: Add NodeSource apt repo
copy:
content: "deb [signed-by=/etc/apt/keyrings/nodesource.asc] https://deb.nodesource.com/node_{{ meridian_node_major }}.x nodistro main\n"
dest: /etc/apt/sources.list.d/nodesource.list
owner: root
group: root
mode: '0644'
register: nodesource_repo
- name: apt update after NodeSource add
apt:
update_cache: true
when: nodesource_repo.changed
- name: Install Node.js
apt:
name: nodejs
state: present
- name: Verify Node major version
command: node --version
register: node_version
changed_when: false
- name: Fail if Node major mismatch
fail:
msg: "Node {{ node_version.stdout }} installed; expected v{{ meridian_node_major }}.x"
when: not node_version.stdout.startswith("v" ~ meridian_node_major | string ~ ".")
# ---------- Meridian user + home ----------
- name: Ensure meridian system user
user:
name: "{{ meridian_user }}"
system: true
home: "{{ meridian_home }}"
shell: /usr/sbin/nologin
create_home: true
state: present
- name: Ensure meridian home perms
file:
path: "{{ meridian_home }}"
state: directory
owner: "{{ meridian_user }}"
group: "{{ meridian_user }}"
mode: '0750'
- name: Ensure .claude credentials dir
file:
path: "{{ meridian_home }}/.claude"
state: directory
owner: "{{ meridian_user }}"
group: "{{ meridian_user }}"
mode: '0700'
# ---------- Install Meridian via npm ----------
- name: Install @rynfar/meridian globally
npm:
name: "@rynfar/meridian"
global: true
state: latest
register: meridian_install
- name: Resolve meridian binary path
command: which meridian
register: meridian_bin
changed_when: false
# ---------- systemd unit ----------
- name: Deploy meridian systemd unit
template:
src: meridian.service.j2
dest: /etc/systemd/system/meridian.service
owner: root
group: root
mode: '0644'
notify: reload systemd
- name: Flush handlers (reload systemd before enable)
meta: flush_handlers
- name: Enable meridian service
systemd:
name: meridian
enabled: true
daemon_reload: true
# OAuth creds (~/.claude/) are scp'd in manually after first deploy.
# Start the service only if creds are present — otherwise the SDK would
# crash-loop on missing credentials.
- name: Check for Claude OAuth credentials
stat:
path: "{{ meridian_home }}/.claude/.credentials.json"
register: claude_creds
- name: Start meridian if credentials present
systemd:
name: meridian
state: started
when: claude_creds.stat.exists
- name: Bootstrap reminder
debug:
msg: |
Meridian installed at {{ meridian_bin.stdout }}.
OAuth credentials not yet present at {{ meridian_home }}/.claude/.credentials.json.
Bootstrap on your Mac:
npm i -g @anthropic-ai/claude-code && claude login
Then transfer creds:
scp -r ~/.claude cbalders@{{ inventory_hostname }}:/tmp/.claude-bootstrap
On the LXC:
sudo cp -r /tmp/.claude-bootstrap/. {{ meridian_home }}/.claude/
sudo chown -R {{ meridian_user }}:{{ meridian_user }} {{ meridian_home }}/.claude/
sudo systemctl start meridian
when: not claude_creds.stat.exists