Files
aibook-fun/deploy/terraform/templates/cloud-init.yaml
T

86 lines
2.9 KiB
YAML

#cloud-config
# First-boot bootstrap: base packages + Docker + git. App layer via ansible.
package_update: true
packages:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
- jq
- unzip
- git
write_files:
# Docker installation
- path: /tmp/install-docker.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
sh /tmp/get-docker.sh
systemctl enable docker
systemctl start docker
usermod -aG docker ubuntu
# Docker daemon config (log rotation)
- path: /etc/docker/daemon.json
content: |
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
# Encrypted-at-rest data volume setup (runs BEFORE Docker is installed).
# Graceful no-op when no volume is attached (data_volume_size_gb = 0 default
# for aibook-fun stateless marketing site).
- path: /tmp/setup-data-volume.sh
permissions: "0755"
content: |
#!/bin/bash
set -euo pipefail
DEV="/dev/disk/by-id/scsi-0DO_Volume_aibook-fun-data"
MNT="/mnt/${project_name}_data"
for i in $(seq 1 24); do
[ -e "$DEV" ] && break
sleep 5
done
if [ ! -e "$DEV" ]; then
echo "no data volume attached after 120s - using droplet local disk (stateless mode)"
exit 0
fi
blkid "$DEV" >/dev/null 2>&1 || mkfs.ext4 -q "$DEV"
mkdir -p "$MNT"
grep -q "scsi-0DO_Volume_aibook-fun-data" /etc/fstab || \
echo "$DEV $MNT ext4 defaults,noatime,nofail,discard 0 2" >> /etc/fstab
mountpoint -q "$MNT" || mount "$MNT"
mkdir -p "$MNT/docker"
jq --arg dr "$MNT/docker" '. + {"data-root": $dr}' /etc/docker/daemon.json > /tmp/daemon.json.new
mv /tmp/daemon.json.new /etc/docker/daemon.json
mkdir -p /opt/${project_name}
echo "data volume mounted at $MNT (docker data-root relocated)"
runcmd:
# Data volume setup only when a block volume is attached
- 'bash -c "[ -e /dev/disk/by-id/scsi-0DO_Volume_aibook-fun-data ] && bash /tmp/setup-data-volume.sh || echo no-data-volume"'
- [bash, /tmp/install-docker.sh]
- [systemctl, restart, docker]
# Ensure the app dir exists for ansible to land the compose + Caddyfile
- [mkdir, -p, /opt/${project_name}]
# Marker so ansible/deploy.yml can confirm the host is ready
- [touch, /opt/${project_name}/.bootstrap-complete]
# Enable automatic security updates
- dpkg-reconfigure -plow unattended-upgrades
final_message: |
aibook-fun bootstrap complete. Next step from the operator workstation:
ansible-playbook aibook-fun/ansible/deploy.yml -i 'root@<this-droplet-ip>,'
Ansible will clone the repo, build the Docker image locally on this droplet,
and bring up the compose stack. Site served at https://aibook.fun.