Initial Phoenix Sankofa Cloud setup
- Complete project structure with Next.js frontend - GraphQL API backend with Apollo Server - Portal application with NextAuth - Crossplane Proxmox provider - GitOps configurations - CI/CD pipelines - Testing infrastructure (Vitest, Jest, Go tests) - Error handling and monitoring - Security hardening - UI component library - Documentation
This commit is contained in:
26
scripts/ansible/inventory.example
Normal file
26
scripts/ansible/inventory.example
Normal file
@@ -0,0 +1,26 @@
|
||||
# Ansible Inventory Example
|
||||
# Copy to inventory and customize with your hosts
|
||||
|
||||
[proxmox_site_1]
|
||||
pve1 ansible_host=10.1.0.10 site=us-east-1
|
||||
pve2 ansible_host=10.1.0.11 site=us-east-1
|
||||
pve3 ansible_host=10.1.0.12 site=us-east-1
|
||||
|
||||
[proxmox_site_2]
|
||||
pve4 ansible_host=10.2.0.10 site=eu-west-1
|
||||
pve5 ansible_host=10.2.0.11 site=eu-west-1
|
||||
pve6 ansible_host=10.2.0.12 site=eu-west-1
|
||||
|
||||
[proxmox_site_3]
|
||||
pve7 ansible_host=10.3.0.10 site=apac-1
|
||||
pve8 ansible_host=10.3.0.11 site=apac-1
|
||||
|
||||
[proxmox:children]
|
||||
proxmox_site_1
|
||||
proxmox_site_2
|
||||
proxmox_site_3
|
||||
|
||||
[proxmox:vars]
|
||||
ansible_user=root
|
||||
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
|
||||
|
||||
126
scripts/ansible/site-playbook.yml
Normal file
126
scripts/ansible/site-playbook.yml
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
# Ansible Playbook for Multi-Site Deployment
|
||||
# Deploys agents and configures Proxmox sites
|
||||
|
||||
- name: Deploy Hybrid Cloud Control Plane to Multiple Sites
|
||||
hosts: all
|
||||
become: yes
|
||||
vars:
|
||||
cloudflare_tunnel_token: "{{ vault_cloudflare_tunnel_token }}"
|
||||
site_name: "{{ inventory_hostname | regex_replace('^pve[0-9]+', 'site') }}"
|
||||
prometheus_enabled: true
|
||||
|
||||
tasks:
|
||||
- name: Ensure system is up to date
|
||||
package:
|
||||
name:
|
||||
- curl
|
||||
- wget
|
||||
- git
|
||||
- jq
|
||||
state: present
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Install cloudflared
|
||||
block:
|
||||
- name: Check if cloudflared is installed
|
||||
command: which cloudflared
|
||||
register: cloudflared_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Download cloudflared
|
||||
get_url:
|
||||
url: "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-{{ ansible_architecture | replace('x86_64', 'amd64') | replace('aarch64', 'arm64') }}"
|
||||
dest: /usr/local/bin/cloudflared
|
||||
mode: '0755'
|
||||
when: cloudflared_check.rc != 0
|
||||
|
||||
- name: Create cloudflared directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /etc/cloudflared
|
||||
- /etc/cloudflared/tunnel-configs
|
||||
- /var/log/cloudflared
|
||||
|
||||
- name: Copy tunnel configuration
|
||||
template:
|
||||
src: tunnel-config.j2
|
||||
dest: /etc/cloudflared/tunnel-configs/{{ site_name }}.yaml
|
||||
mode: '0644'
|
||||
vars:
|
||||
node_name: "{{ inventory_hostname }}"
|
||||
|
||||
- name: Create tunnel credentials file
|
||||
copy:
|
||||
content: '{"AccountTag":"","TunnelSecret":"","TunnelID":"","TunnelName":"{{ site_name }}-tunnel"}'
|
||||
dest: /etc/cloudflared/{{ site_name }}-tunnel.json
|
||||
mode: '0600'
|
||||
|
||||
- name: Create cloudflared systemd service
|
||||
template:
|
||||
src: cloudflared.service.j2
|
||||
dest: /etc/systemd/system/cloudflared-tunnel.service
|
||||
mode: '0644'
|
||||
vars:
|
||||
site_name: "{{ site_name }}"
|
||||
notify: restart cloudflared
|
||||
|
||||
- name: Install Prometheus exporter
|
||||
block:
|
||||
- name: Install Python pip
|
||||
package:
|
||||
name: python3-pip
|
||||
state: present
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Install pve_exporter
|
||||
pip:
|
||||
name: pve_exporter
|
||||
state: present
|
||||
when: prometheus_enabled | bool
|
||||
|
||||
- name: Create pve_exporter systemd service
|
||||
template:
|
||||
src: pve-exporter.service.j2
|
||||
dest: /etc/systemd/system/pve-exporter.service
|
||||
mode: '0644'
|
||||
when: prometheus_enabled | bool
|
||||
notify: restart pve-exporter
|
||||
|
||||
- name: Enable and start services
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
enabled: yes
|
||||
state: started
|
||||
daemon_reload: yes
|
||||
loop:
|
||||
- cloudflared-tunnel
|
||||
- pve-exporter
|
||||
when: item != "pve-exporter" or prometheus_enabled | bool
|
||||
|
||||
- name: Verify cloudflared is running
|
||||
systemd:
|
||||
name: cloudflared-tunnel
|
||||
register: cloudflared_status
|
||||
|
||||
- name: Display tunnel status
|
||||
debug:
|
||||
msg: "Cloudflare tunnel is {{ cloudflared_status.status.ActiveState }}"
|
||||
|
||||
handlers:
|
||||
- name: restart cloudflared
|
||||
systemd:
|
||||
name: cloudflared-tunnel
|
||||
state: restarted
|
||||
daemon_reload: yes
|
||||
|
||||
- name: restart pve-exporter
|
||||
systemd:
|
||||
name: pve-exporter
|
||||
state: restarted
|
||||
daemon_reload: yes
|
||||
|
||||
16
scripts/ansible/templates/cloudflared.service.j2
Normal file
16
scripts/ansible/templates/cloudflared.service.j2
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Cloudflare Tunnel for {{ site_name }}
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/cloudflared tunnel --config /etc/cloudflared/tunnel-configs/{{ site_name }}.yaml run
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
16
scripts/ansible/templates/pve-exporter.service.j2
Normal file
16
scripts/ansible/templates/pve-exporter.service.j2
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Proxmox VE Prometheus Exporter
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=/usr/local/bin/pve_exporter --web.listen-address=0.0.0.0:9221
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
50
scripts/ansible/templates/tunnel-config.j2
Normal file
50
scripts/ansible/templates/tunnel-config.j2
Normal file
@@ -0,0 +1,50 @@
|
||||
# Cloudflare Tunnel Configuration for {{ site_name }}
|
||||
# Generated by Ansible
|
||||
|
||||
tunnel: {{ site_name }}-tunnel
|
||||
credentials-file: /etc/cloudflared/{{ site_name }}-tunnel.json
|
||||
|
||||
ingress:
|
||||
# Proxmox Web UI
|
||||
- hostname: {{ node_name }}.yourdomain.com
|
||||
service: https://{{ node_name }}.local:8006
|
||||
originRequest:
|
||||
noHappyEyeballs: true
|
||||
connectTimeout: 30s
|
||||
tls:
|
||||
skipVerify: true
|
||||
httpHostHeader: {{ node_name }}.local:8006
|
||||
|
||||
# Proxmox API
|
||||
- hostname: {{ node_name }}-api.yourdomain.com
|
||||
service: https://{{ node_name }}.local:8006
|
||||
originRequest:
|
||||
noHappyEyeballs: true
|
||||
connectTimeout: 30s
|
||||
tls:
|
||||
skipVerify: true
|
||||
httpHostHeader: {{ node_name }}.local:8006
|
||||
|
||||
# Prometheus Exporter
|
||||
- hostname: {{ node_name }}-metrics.yourdomain.com
|
||||
service: http://localhost:9221
|
||||
originRequest:
|
||||
noHappyEyeballs: true
|
||||
connectTimeout: 30s
|
||||
|
||||
# Catch-all rule (must be last)
|
||||
- service: http_status:404
|
||||
|
||||
# Logging
|
||||
loglevel: info
|
||||
logfile: /var/log/cloudflared/{{ site_name }}-tunnel.log
|
||||
|
||||
# Metrics
|
||||
metrics: 0.0.0.0:9090
|
||||
|
||||
# Health check
|
||||
health-probe:
|
||||
enabled: true
|
||||
path: /health
|
||||
port: 8080
|
||||
|
||||
Reference in New Issue
Block a user