165 lines
6.0 KiB
YAML
165 lines
6.0 KiB
YAML
|
|
---
|
||
|
|
- name: Deploy Uptime Kuma on GCP and Configure Non-Interactively
|
||
|
|
|
||
|
|
vars:
|
||
|
|
# GCP Configuration
|
||
|
|
gcp_project: "your-gcp-project-id"
|
||
|
|
gcp_region: "us-central1"
|
||
|
|
gcp_zone: "us-central1-a"
|
||
|
|
instance_name: "uptime-kuma-vm"
|
||
|
|
machine_type: "e2-small" # 2GB RAM is plenty for Uptime Kuma
|
||
|
|
static_ip_name: "uptime-kuma-ip"
|
||
|
|
firewall_rule_name: "allow-uptime-kuma-3001"
|
||
|
|
|
||
|
|
# Uptime Kuma Credentials & Target
|
||
|
|
kuma_admin_user: "admin"
|
||
|
|
kuma_admin_pass: "ChangeMeImmediately123!"
|
||
|
|
target_monitor_name: "Target Web App"
|
||
|
|
target_monitor_url: "https://example.com"
|
||
|
|
|
||
|
|
tasks:
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 1. Local Prerequisites
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Ensure uptime-kuma-api Python library is installed locally
|
||
|
|
ansible.builtin.pip:
|
||
|
|
name: uptime-kuma-api
|
||
|
|
state: present
|
||
|
|
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 2. Allocate Static Public IP (Idempotent)
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Check if static IP exists
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute addresses describe {{ static_ip_name }}
|
||
|
|
--region={{ gcp_region }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
register: ip_check
|
||
|
|
failed_when: false
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Allocate static external IP in GCP
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute addresses create {{ static_ip_name }}
|
||
|
|
--region={{ gcp_region }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
--description="Static IP for Uptime Kuma"
|
||
|
|
when: ip_check.rc != 0
|
||
|
|
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 3. Create Firewall Rule (Port 3001)
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Check if firewall rule exists
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute firewall-rules describe {{ firewall_rule_name }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
register: fw_check
|
||
|
|
failed_when: false
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Allow TCP traffic to port 3001
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute firewall-rules create {{ firewall_rule_name }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
--allow=tcp:3001
|
||
|
|
--target-tags=uptime-kuma
|
||
|
|
--source-ranges=0.0.0.0/0
|
||
|
|
--description="Allow traffic to Uptime Kuma UI & API"
|
||
|
|
when: fw_check.rc != 0
|
||
|
|
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 4. Provision VM with Container-Optimized OS
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Check if instance already exists
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute instances describe {{ instance_name }}
|
||
|
|
--zone={{ gcp_zone }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
register: instance_check
|
||
|
|
failed_when: false
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Launch Compute Engine VM with Uptime Kuma container
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute instances create-with-container {{ instance_name }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
--zone={{ gcp_zone }}
|
||
|
|
--machine-type={{ machine_type }}
|
||
|
|
--tags=uptime-kuma
|
||
|
|
--address={{ static_ip_name }}
|
||
|
|
--boot-disk-size=20GB
|
||
|
|
--container-image=louislam/uptime-kuma:1
|
||
|
|
--container-mount-host-path=host-path=/var/uptime-kuma,mount-path=/app/data,mode=rw
|
||
|
|
when: instance_check.rc != 0
|
||
|
|
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 5. Fetch Public IP and Wait for Service Readiness
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Fetch instance public IP address
|
||
|
|
ansible.builtin.command: >
|
||
|
|
gcloud compute instances describe {{ instance_name }}
|
||
|
|
--zone={{ gcp_zone }}
|
||
|
|
--project={{ gcp_project }}
|
||
|
|
--format="value(networkInterfaces[0].accessConfigs[0].natIP)"
|
||
|
|
register: vm_ip
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Display Uptime Kuma URL
|
||
|
|
ansible.builtin.debug:
|
||
|
|
msg: "Uptime Kuma is booting at: http://{{ vm_ip.stdout.strip() }}:3001"
|
||
|
|
|
||
|
|
- name: Wait for Uptime Kuma to respond with HTTP 200
|
||
|
|
ansible.builtin.uri:
|
||
|
|
url: "http://{{ vm_ip.stdout.strip() }}:3001"
|
||
|
|
status_code: 200
|
||
|
|
register: readiness
|
||
|
|
until: readiness.status == 200
|
||
|
|
retries: 30
|
||
|
|
delay: 6
|
||
|
|
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
# 6. Non-Interactive Configuration via API
|
||
|
|
# -------------------------------------------------------------
|
||
|
|
- name: Perform headless setup and add monitor
|
||
|
|
ansible.builtin.command:
|
||
|
|
cmd: >
|
||
|
|
python3 -c "
|
||
|
|
import sys
|
||
|
|
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||
|
|
|
||
|
|
kuma_url = 'http://{{ vm_ip.stdout.strip() }}:3001'
|
||
|
|
api = UptimeKumaApi(kuma_url)
|
||
|
|
|
||
|
|
# 1. Initial admin account creation if not yet initialized
|
||
|
|
if api.need_setup():
|
||
|
|
api.setup('{{ kuma_admin_user }}', '{{ kuma_admin_pass }}')
|
||
|
|
print('ADMIN_CREATED')
|
||
|
|
|
||
|
|
# 2. Login
|
||
|
|
api.login('{{ kuma_admin_user }}', '{{ kuma_admin_pass }}')
|
||
|
|
|
||
|
|
# 3. Add monitor idempotently
|
||
|
|
current_monitors = [m['name'] for m in api.get_monitors()]
|
||
|
|
if '{{ target_monitor_name }}' not in current_monitors:
|
||
|
|
api.add_monitor(
|
||
|
|
type=MonitorType.HTTP,
|
||
|
|
name='{{ target_monitor_name }}',
|
||
|
|
url='{{ target_monitor_url }}',
|
||
|
|
interval=60
|
||
|
|
)
|
||
|
|
print('MONITOR_ADDED')
|
||
|
|
else:
|
||
|
|
print('MONITOR_ALREADY_EXISTS')
|
||
|
|
|
||
|
|
api.disconnect()
|
||
|
|
"
|
||
|
|
register: setup_output
|
||
|
|
changed_when: "'MONITOR_ADDED' in setup_output.stdout"
|
||
|
|
|
||
|
|
- name: Show setup summary
|
||
|
|
ansible.builtin.debug:
|
||
|
|
msg:
|
||
|
|
- "Setup Status: {{ setup_output.stdout.strip() }}"
|
||
|
|
- "Access UI at: http://{{ vm_ip.stdout.strip() }}:3001"
|
||
|
|
- "Username: {{ kuma_admin_user }}"
|