Compare commits
4 Commits
36c63d1243
...
7ba68de68d
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ba68de68d | |||
| d1d38df0e4 | |||
| 62e5027d24 | |||
| 3d596b984b |
@@ -0,0 +1,2 @@
|
||||
ansible_user: adyrem
|
||||
ansible_ssh_common_args: "-o ProxyJump=root@192.168.1.10 -o StrictHostKeyChecking=no"
|
||||
@@ -22,6 +22,11 @@ all:
|
||||
hosts:
|
||||
gitea:
|
||||
|
||||
claude_code_vms:
|
||||
hosts:
|
||||
claude-code:
|
||||
ansible_host: 10.10.2.10
|
||||
|
||||
pihole_servers:
|
||||
hosts:
|
||||
pihole:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- name: Configure Claude Code VM
|
||||
hosts: claude_code_vms
|
||||
roles:
|
||||
- common
|
||||
- node_exporter
|
||||
- promtail
|
||||
- claude_code
|
||||
@@ -0,0 +1,2 @@
|
||||
files/homelab_ed25519
|
||||
files/claude-code_ed25519
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
- name: Install Claude Code dependencies
|
||||
community.general.pacman:
|
||||
name:
|
||||
- nodejs
|
||||
- npm
|
||||
- ansible
|
||||
- python-pip
|
||||
- tmux
|
||||
- git
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Install Claude Code CLI
|
||||
community.general.npm:
|
||||
name: "@anthropic-ai/claude-code"
|
||||
global: true
|
||||
state: present
|
||||
|
||||
- name: Deploy homelab SSH private key
|
||||
ansible.builtin.copy:
|
||||
src: homelab_ed25519
|
||||
dest: /home/{{ admin_user }}/.ssh/homelab_ed25519
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Deploy claude-code SFTP private key
|
||||
ansible.builtin.copy:
|
||||
src: claude-code_ed25519
|
||||
dest: /home/{{ admin_user }}/.ssh/claude-code_ed25519
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Write SSH client config
|
||||
ansible.builtin.template:
|
||||
src: ssh_config.j2
|
||||
dest: /home/{{ admin_user }}/.ssh/config
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Write tmux config
|
||||
ansible.builtin.copy:
|
||||
dest: /home/{{ admin_user }}/.tmux.conf
|
||||
owner: "{{ admin_user }}"
|
||||
group: "{{ admin_user }}"
|
||||
mode: "0644"
|
||||
content: |
|
||||
set -g default-terminal "screen-256color"
|
||||
set -g history-limit 50000
|
||||
set -g mouse on
|
||||
set -g base-index 1
|
||||
set -g escape-time 10
|
||||
bind r source-file ~/.tmux.conf \; display "Reloaded"
|
||||
|
||||
- name: Clone homelab repo
|
||||
ansible.builtin.git:
|
||||
repo: "http://10.10.1.125:3000/adyrem/homelab.git"
|
||||
dest: /home/{{ admin_user }}/dev/homelab
|
||||
version: main
|
||||
become_user: "{{ admin_user }}"
|
||||
become: true
|
||||
@@ -0,0 +1,42 @@
|
||||
# Proxmox host — jump host only, no shell
|
||||
Host proxmox
|
||||
HostName 192.168.1.10
|
||||
User root
|
||||
IdentityFile ~/.ssh/homelab_ed25519
|
||||
StrictHostKeyChecking no
|
||||
|
||||
# Proxmox SFTP — write files to host workspace
|
||||
Host proxmox-sftp
|
||||
HostName 192.168.1.10
|
||||
User claude-code
|
||||
IdentityFile ~/.ssh/claude-code_ed25519
|
||||
StrictHostKeyChecking no
|
||||
|
||||
# Infra VMs — via ProxyJump through Proxmox
|
||||
Host gitea-vm
|
||||
HostName 10.10.1.125
|
||||
User adyrem
|
||||
ProxyJump proxmox
|
||||
IdentityFile ~/.ssh/homelab_ed25519
|
||||
StrictHostKeyChecking no
|
||||
|
||||
Host monitoring-vm
|
||||
HostName 10.10.1.137
|
||||
User adyrem
|
||||
ProxyJump proxmox
|
||||
IdentityFile ~/.ssh/homelab_ed25519
|
||||
StrictHostKeyChecking no
|
||||
|
||||
Host pihole-ct
|
||||
HostName 10.10.1.2
|
||||
User root
|
||||
ProxyJump proxmox
|
||||
IdentityFile ~/.ssh/homelab_ed25519
|
||||
StrictHostKeyChecking no
|
||||
|
||||
Host traefik-ct
|
||||
HostName 10.10.1.3
|
||||
User root
|
||||
ProxyJump proxmox
|
||||
IdentityFile ~/.ssh/homelab_ed25519
|
||||
StrictHostKeyChecking no
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"$$hashKey": "object:75",
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "Log Viewer Dashboard for Loki",
|
||||
"editable": false,
|
||||
"gnetId": 13639,
|
||||
"graphTooltip": 0,
|
||||
"id": 1684514089902080,
|
||||
"iteration": 1608932746420,
|
||||
"links": [
|
||||
{
|
||||
"$$hashKey": "object:59",
|
||||
"icon": "bolt",
|
||||
"includeVars": true,
|
||||
"keepTime": true,
|
||||
"tags": [],
|
||||
"targetBlank": true,
|
||||
"title": "View In Explore",
|
||||
"type": "link",
|
||||
"url": "/explore?orgId=1&left=[\"now-1h\",\"now\",\"Loki\",{\"expr\":\"{job=\\\"$app\\\"}\"},{\"ui\":[true,true,true,\"none\"]}]"
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:61",
|
||||
"icon": "external link",
|
||||
"tags": [],
|
||||
"targetBlank": true,
|
||||
"title": "Learn LogQL",
|
||||
"type": "link",
|
||||
"url": "https://grafana.com/docs/loki/latest/logql/"
|
||||
}
|
||||
],
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": true,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "P8E80F9AEF21F6940",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 3,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 6,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": false,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": false,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.0",
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(count_over_time({job=\"$app\"} |= \"$search\" [$__interval]))",
|
||||
"legendFormat": "",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:168",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:169",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"datasource": "P8E80F9AEF21F6940",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 25,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 3
|
||||
},
|
||||
"id": 2,
|
||||
"maxDataPoints": "",
|
||||
"options": {
|
||||
"showLabels": false,
|
||||
"showTime": true,
|
||||
"sortOrder": "Descending",
|
||||
"wrapLogMessage": false
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "{job=\"$app\"} |= \"$search\" | logfmt",
|
||||
"hide": false,
|
||||
"legendFormat": "",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "",
|
||||
"transparent": true,
|
||||
"type": "logs"
|
||||
}
|
||||
],
|
||||
"refresh": false,
|
||||
"schemaVersion": 26,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {},
|
||||
"datasource": "P8E80F9AEF21F6940",
|
||||
"definition": "label_values(job)",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "App",
|
||||
"multi": false,
|
||||
"name": "app",
|
||||
"options": [],
|
||||
"query": "label_values(job)",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
},
|
||||
{
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "",
|
||||
"value": ""
|
||||
},
|
||||
"hide": 0,
|
||||
"label": "String Match",
|
||||
"name": "search",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"query": "",
|
||||
"skipUrlSync": false,
|
||||
"type": "textbox"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"hidden": false,
|
||||
"refresh_intervals": [
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
]
|
||||
},
|
||||
"timezone": "",
|
||||
"title": "Logs / App",
|
||||
"uid": "sadlil-loki-apps-dashboard",
|
||||
"version": 1
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
[OPTIONS]
|
||||
enable: 1
|
||||
|
||||
[ALIASES]
|
||||
lan 192.168.1.0/24
|
||||
infra_net 10.10.1.0/24
|
||||
dev_net 10.10.2.0/24
|
||||
@@ -0,0 +1,12 @@
|
||||
[OPTIONS]
|
||||
enable: 1
|
||||
log_level_in: nolog
|
||||
log_level_out: nolog
|
||||
|
||||
[RULES]
|
||||
IN ACCEPT -source 192.168.1.0/24 -p tcp -dport 22
|
||||
IN ACCEPT -source 192.168.1.0/24 -p tcp -dport 8006
|
||||
IN ACCEPT -source 192.168.1.0/24 -p tcp -dport 3128
|
||||
IN ACCEPT -source 10.10.0.0/16 -p udp -dport 53
|
||||
IN ACCEPT -source 10.10.0.0/16 -p tcp -dport 53
|
||||
IN ACCEPT -p icmp
|
||||
@@ -0,0 +1,12 @@
|
||||
arch: amd64
|
||||
cores: 1
|
||||
features: nesting=1
|
||||
hostname: pihole
|
||||
memory: 512
|
||||
nameserver: 8.8.8.8
|
||||
net0: name=eth0,bridge=vmbr1,firewall=0,gw=10.10.1.1,hwaddr=BC:24:11:D6:DD:FF,ip=10.10.1.2/24,type=veth
|
||||
onboot: 1
|
||||
ostype: debian
|
||||
rootfs: local-zfs:subvol-103-disk-0,size=4G
|
||||
swap: 0
|
||||
unprivileged: 1
|
||||
@@ -0,0 +1,14 @@
|
||||
arch: amd64
|
||||
cores: 1
|
||||
hostname: traefik
|
||||
memory: 256
|
||||
nameserver: 10.10.1.2
|
||||
net0: name=eth0,bridge=vmbr1,firewall=1,gw=10.10.1.1,hwaddr=BC:24:11:8E:D3:36,ip=10.10.1.3/24,type=veth
|
||||
onboot: 1
|
||||
ostype: debian
|
||||
rootfs: local-zfs:subvol-104-disk-0,size=2G
|
||||
swap: 0
|
||||
unprivileged: 1
|
||||
|
||||
[pve:pending]
|
||||
nameserver: 8.8.8.8
|
||||
@@ -0,0 +1,54 @@
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
|
||||
iface nic0 inet manual
|
||||
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 192.168.1.10/24
|
||||
gateway 192.168.1.1
|
||||
bridge-ports nic0
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to-destination 10.10.1.3:80
|
||||
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to-destination 10.10.1.3:443
|
||||
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 80 -j DNAT --to-destination 10.10.1.3:80
|
||||
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 443 -j DNAT --to-destination 10.10.1.3:443
|
||||
post-up iptables -t nat -A PREROUTING -i vmbr0 -p udp --dport 53 -j DNAT --to-destination 10.10.1.2:53
|
||||
post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp --dport 53 -j DNAT --to-destination 10.10.1.2:53
|
||||
post-up iptables -t nat -A POSTROUTING -p udp -d 10.10.1.2 --dport 53 -j MASQUERADE
|
||||
post-up iptables -t nat -A POSTROUTING -p tcp -d 10.10.1.2 --dport 53 -j MASQUERADE
|
||||
post-down iptables -t nat -D PREROUTING -i vmbr0 -p udp --dport 53 -j DNAT --to-destination 10.10.1.2:53
|
||||
post-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp --dport 53 -j DNAT --to-destination 10.10.1.2:53
|
||||
post-down iptables -t nat -D POSTROUTING -p udp -d 10.10.1.2 --dport 53 -j MASQUERADE
|
||||
post-down iptables -t nat -D POSTROUTING -p tcp -d 10.10.1.2 --dport 53 -j MASQUERADE
|
||||
|
||||
|
||||
source /etc/network/interfaces.d/*
|
||||
|
||||
auto vmbr1
|
||||
iface vmbr1 inet static
|
||||
address 10.10.1.1/24
|
||||
bridge-ports none
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
post-up iptables -t nat -A POSTROUTING -s 10.10.1.0/24 -o vmbr0 -j MASQUERADE
|
||||
post-down iptables -t nat -D POSTROUTING -s 10.10.1.0/24 -o vmbr0 -j MASQUERADE
|
||||
|
||||
auto vmbr2
|
||||
iface vmbr2 inet static
|
||||
address 10.10.2.1/24
|
||||
bridge-ports none
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
post-up iptables -t nat -A POSTROUTING -s 10.10.2.0/24 -o vmbr0 -j MASQUERADE
|
||||
post-down iptables -t nat -D POSTROUTING -s 10.10.2.0/24 -o vmbr0 -j MASQUERADE
|
||||
|
||||
auto vmbr3
|
||||
iface vmbr3 inet static
|
||||
address 10.10.3.1/24
|
||||
bridge-ports none
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
post-up iptables -t nat -A POSTROUTING -s 10.10.3.0/24 -o vmbr0 -j MASQUERADE
|
||||
post-down iptables -t nat -D POSTROUTING -s 10.10.3.0/24 -o vmbr0 -j MASQUERADE
|
||||
@@ -0,0 +1,23 @@
|
||||
agent: enabled=1
|
||||
bios: ovmf
|
||||
boot: order=scsi0
|
||||
cicustom: user=local:snippets/claude-code-userdata.yaml
|
||||
citype: nocloud
|
||||
cores: 4
|
||||
cpu: host
|
||||
efidisk0: local-zfs:vm-105-disk-0,efitype=4m,pre-enrolled-keys=0,size=1M
|
||||
ide2: local-zfs:vm-105-cloudinit,media=cdrom
|
||||
ipconfig0: ip=10.10.2.10/24,gw=10.10.2.1
|
||||
machine: q35
|
||||
memory: 8192
|
||||
name: claude-code
|
||||
nameserver: 10.10.1.2
|
||||
net0: virtio=BC:24:11:E3:A1:D1,bridge=vmbr2,firewall=1
|
||||
onboot: 1
|
||||
ostype: l26
|
||||
scsi0: local-zfs:vm-105-disk-1,iothread=1,size=20G
|
||||
scsihw: virtio-scsi-single
|
||||
searchdomain: homelab
|
||||
smbios1: uuid=cc68aa1f-affe-42ee-8086-ba94b69573af
|
||||
vga: qxl
|
||||
vmgenid: 511710d7-9a40-43ef-901e-0a2de8344f5b
|
||||
Reference in New Issue
Block a user