incus-contrib/ansible/playbooks/showcase/staticsite-site.yml

162 lines
6.4 KiB
YAML

---
# showcase/staticsite-site.yml — nginx static site
#
# Installs nginx and deploys a branded HTML page showing the instance
# name, IP, node placement, and deployment timestamp. Each instance is
# independently configured — no cross-instance coordination needed.
- name: Generate static site setup script
ansible.builtin.set_fact:
site_setup_script: |
#!/bin/bash
set -e
echo "=== Static site setup starting ==="
export DEBIAN_FRONTEND=noninteractive
# Install nginx
apt-get install -y -qq nginx 2>&1 | tail -1
echo "[OK] nginx installed"
# Get instance metadata
MY_IP=$(hostname -I | awk '{print $1}')
DEPLOY_TIME=$(date -Iseconds)
# Deploy branded HTML page
cat > /var/www/html/index.html << SITEHTML
<!DOCTYPE html>
<html>
<head>
<title>{{ ffsdn_instance_name }} — Static Site Showcase</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
.container { background: white; border-radius: 16px; padding: 48px; max-width: 600px; width: 90%; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
h1 { font-size: 28px; color: #1a1a2e; margin-bottom: 8px; }
.subtitle { color: #888; font-size: 14px; margin-bottom: 32px; }
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.info-card { background: #f8f9fa; border-radius: 8px; padding: 16px; }
.info-label { font-size: 12px; color: #888; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
.info-value { font-size: 18px; font-weight: 600; color: #1a1a2e; word-break: break-all; }
.badge { display: inline-block; background: #667eea; color: white; padding: 4px 12px; border-radius: 12px; font-size: 13px; font-weight: 600; margin-top: 24px; }
.footer { text-align: center; margin-top: 32px; color: #aaa; font-size: 12px; }
</style>
</head>
<body>
<div class="container">
<h1>{{ ffsdn_instance_name }}</h1>
<div class="subtitle">Static Site Showcase &mdash; deployed by AWX via Aether</div>
<div class="info-grid">
<div class="info-card">
<div class="info-label">Instance</div>
<div class="info-value">{{ ffsdn_instance_name }}</div>
</div>
<div class="info-card">
<div class="info-label">IP Address</div>
<div class="info-value">${MY_IP}</div>
</div>
<div class="info-card">
<div class="info-label">Cluster</div>
<div class="info-value">{{ ffsdn_cluster_name | default('unknown') }}</div>
</div>
<div class="info-card">
<div class="info-label">Deployed By</div>
<div class="info-value">{{ ffsdn_deployed_by | default('unknown') }}</div>
</div>
<div class="info-card">
<div class="info-label">Image</div>
<div class="info-value">{{ ffsdn_image_os | default('') }} {{ ffsdn_image_release | default('') }}</div>
</div>
<div class="info-card">
<div class="info-label">Deployed At</div>
<div class="info-value">${DEPLOY_TIME}</div>
</div>
</div>
<div style="text-align:center"><span class="badge">staticsite blueprint</span></div>
<div class="footer">
Horizontal scaling demo &mdash; each instance independently configured
</div>
</div>
</body>
</html>
SITEHTML
echo "[OK] HTML page deployed"
# Remove default pages
rm -f /var/www/html/index.nginx-debian.html
# Enable and start nginx
systemctl enable nginx
systemctl restart nginx
echo "[OK] nginx started"
echo "=== Static site setup complete ==="
- name: Push static site setup script
ansible.builtin.uri:
url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/files?path=/tmp/staticsite-setup.sh"
method: POST
client_cert: "{{ incus_cert }}"
client_key: "{{ incus_key }}"
validate_certs: false
body: "{{ site_setup_script }}"
headers:
Content-Type: "application/octet-stream"
X-Incus-type: "file"
X-Incus-mode: "0755"
status_code: [200]
- name: Execute static site setup script
ansible.builtin.uri:
url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
method: POST
client_cert: "{{ incus_cert }}"
client_key: "{{ incus_key }}"
validate_certs: false
body_format: json
body:
command: ["/bin/bash", "/tmp/staticsite-setup.sh"]
record-output: true
interactive: false
wait-for-websocket: false
environment:
DEBIAN_FRONTEND: "noninteractive"
status_code: [202]
return_content: true
register: site_setup_exec
- name: Wait for static site setup to complete (up to 3 minutes)
ansible.builtin.uri:
url: "{{ incus_api }}{{ site_setup_exec.json.operation }}/wait?timeout=180"
method: GET
client_cert: "{{ incus_cert }}"
client_key: "{{ incus_key }}"
validate_certs: false
return_content: true
timeout: 200
register: site_setup_wait
failed_when: site_setup_wait.json.metadata.status != "Success"
- name: Verify static site setup exit code
ansible.builtin.assert:
that:
- site_setup_wait.json.metadata.metadata.return | int == 0
fail_msg: "Static site setup exited with code {{ site_setup_wait.json.metadata.metadata.return }}"
success_msg: "Static site setup completed — nginx serving on port 80"
- name: Clean up setup script
ansible.builtin.uri:
url: "{{ incus_api }}/1.0/instances/{{ ffsdn_instance_name }}/exec"
method: POST
client_cert: "{{ incus_cert }}"
client_key: "{{ incus_key }}"
validate_certs: false
body_format: json
body:
command: ["/bin/rm", "-f", "/tmp/staticsite-setup.sh"]
record-output: false
interactive: false
wait-for-websocket: false
status_code: [202]
ignore_errors: true