infra/ansible/roles/raid/tasks/main.yml
2025-07-27 11:35:59 -05:00

210 lines
No EOL
5.3 KiB
YAML

---
- name: Install RAID management tools
apt:
name:
- mdadm
- smartmontools
- parted
- nvme-cli
- lsscsi
state: present
update_cache: yes
- name: Gather disk information
shell: |
echo "=== Block devices ==="
lsblk -d -o NAME,SIZE,TYPE,MODEL
echo "=== NVMe devices ==="
nvme list 2>/dev/null || echo "No NVMe devices found"
echo "=== SCSI devices ==="
lsscsi -s 2>/dev/null || echo "No SCSI devices found"
echo "=== All disk devices ==="
ls -la /dev/sd* /dev/nvme* /dev/vd* /dev/mmcblk* 2>/dev/null | grep -E "^b" || echo "Checking other paths..."
echo "=== Detailed block device tree ==="
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL
register: disk_info
changed_when: false
- name: Display disk information
debug:
msg: "{{ disk_info.stdout_lines }}"
- name: Check if we should auto-detect RAID devices
set_fact:
auto_detect_devices: "{{ raid_devices is not defined or raid_devices | length == 0 }}"
- name: Auto-detect two largest unused disks
when: auto_detect_devices
block:
- name: Find unused block devices
shell: |
lsblk -dpno NAME,SIZE,TYPE,MOUNTPOINT | grep -E "disk.*$" | grep -v -E "/(|/boot)" | sort -k2 -h -r | head -2 | awk '{print $1}'
register: detected_devices
changed_when: false
- name: Set raid_devices from detected devices
set_fact:
raid_devices: "{{ detected_devices.stdout_lines }}"
when: detected_devices.stdout_lines | length >= 2
- name: Fail if not enough devices detected
fail:
msg: "Could not detect at least 2 unused block devices for RAID. Please specify raid_devices manually."
when: detected_devices.stdout_lines | length < 2
- name: Display RAID devices to be used
debug:
msg: "Will use these devices for RAID0: {{ raid_devices }}"
- name: Check if RAID array already exists
command: mdadm --detail /dev/md0
register: raid_status
failed_when: false
changed_when: false
- name: Stop and remove existing RAID array if it exists
block:
- name: Stop RAID array
command: mdadm --stop /dev/md0
when: raid_status.rc == 0
- name: Zero superblocks on disks
command: mdadm --zero-superblock {{ item }}
loop:
- /dev/nvme0n1
- /dev/nvme1n1
when: raid_status.rc == 0
when: force_raid_rebuild | default(false)
- name: Create partition table on first NVMe drive
parted:
device: /dev/nvme0n1
number: 1
state: present
part_type: primary
part_start: 0%
part_end: 100%
label: gpt
when: raid_status.rc != 0
- name: Create partition table on second NVMe drive
parted:
device: /dev/nvme1n1
number: 1
state: present
part_type: primary
part_start: 0%
part_end: 100%
label: gpt
when: raid_status.rc != 0
- name: Create RAID0 array
command: >
mdadm --create /dev/md0
--level=0
--raid-devices=2
/dev/nvme0n1p1 /dev/nvme1n1p1
--force
when: raid_status.rc != 0
register: raid_create
- name: Wait for RAID array to be ready
command: mdadm --detail /dev/md0
register: raid_ready
until: raid_ready.rc == 0
retries: 10
delay: 5
when: raid_create is changed
- name: Create mdadm configuration
shell: mdadm --detail --scan >> /etc/mdadm/mdadm.conf
when: raid_create is changed
- name: Update initramfs
command: update-initramfs -u
when: raid_create is changed
- name: Create filesystem on RAID array
filesystem:
fstype: ext4
dev: /dev/md0
opts: "-E lazy_itable_init=0,lazy_journal_init=0"
when: raid_create is changed
- name: Create mount point for PostgreSQL data
file:
path: /mnt/pgdata
state: directory
mode: '0755'
- name: Mount RAID array
mount:
path: /mnt/pgdata
src: /dev/md0
fstype: ext4
opts: noatime,nodiratime,nobarrier
state: mounted
- name: Create PostgreSQL user and group
block:
- name: Create postgres group
group:
name: postgres
state: present
system: yes
- name: Create postgres user
user:
name: postgres
group: postgres
home: /var/lib/postgresql
shell: /bin/bash
system: yes
state: present
- name: Ensure PostgreSQL directories exist on RAID
file:
path: "{{ item }}"
state: directory
owner: postgres
group: postgres
mode: '0700'
loop:
- /mnt/pgdata
- /mnt/pgdata/16
- /mnt/pgdata/16/main
- /mnt/pgdata/wal
- /mnt/pgdata/archive
- /mnt/pgdata/backups
- name: Set up RAID monitoring
lineinfile:
path: /etc/mdadm/mdadm.conf
line: "MAILADDR root"
insertafter: EOF
- name: Enable mdadm monitoring service
systemd:
name: mdmonitor
enabled: yes
state: started
- name: Create RAID monitoring script
copy:
content: |
#!/bin/bash
# RAID health check script
RAID_STATUS=$(mdadm --detail /dev/md0 | grep "State :" | awk '{print $3}')
if [ "$RAID_STATUS" != "clean" ] && [ "$RAID_STATUS" != "active" ]; then
echo "RAID array /dev/md0 is in state: $RAID_STATUS"
exit 1
fi
exit 0
dest: /usr/local/bin/check-raid-health
mode: '0755'
- name: Set up RAID health check cron job
cron:
name: "Check RAID health"
minute: "*/5"
job: "/usr/local/bin/check-raid-health || echo 'RAID health check failed' | logger -t raid-health"