This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This repository contains Infrastructure as Code (Ansible-based) for deploying and managing a distributed Jitsi video conferencing platform across multiple cloud providers (AWS and Oracle Cloud). The infrastructure uses a multi-shard architecture with HAProxy load balancing, Consul service discovery, and Nomad container orchestration.
- Core/Signal nodes: Run Prosody (XMPP), Jicofo (conference focus), and Jitsi Meet web frontend
- JVB (Jitsi Videobridge) nodes: Handle media routing and bridging
- HAProxy mesh: Global load balancers that route conference traffic to appropriate shards using stick tables synchronized across regions
- Jibri nodes: Recording and streaming infrastructure
- Jigasi nodes: SIP gateway for telephone integration
- Consul: Service discovery and configuration management
- Nomad: Container orchestration for various services
- Primary: Oracle Cloud (using Instance Pools)
- Secondary: AWS (using EC2, ASGs)
- Cloud provider abstraction via
cloud_providervariable (aws/oracle)
- Main configuration:
config/vars.yml(symlinked from private customizations repo) - Environment-specific:
sites/$ENVIRONMENT/vars.yml - Secrets:
secrets/*.yml(vault-encrypted) - Templates: Jinja2 templates with Consul-template for runtime updates
ansible/- All Ansible playbooks and rolesansible/*.yml- 61+ playbooks for building images and configuring servicesansible/roles/- 137+ Ansible roles for various componentsansible/secrets/- Vault-encrypted secrets (not in git)ansible/config/- Symlink to private customizations repoansible/sites/- Symlink to environment-specific configs
scripts/- Utility scriptshcvlib.py- Core Python library for cloud provider interactions (AWS/Oracle)node.py- Node discovery and inventory managementrun-ansible-cmd.sh- Wrapper for running ad-hoc Ansible commandsconfigure-standalone-oracle.sh- Deploy standalone Jitsi instance
ansible.cfg- Ansible configuration with fact caching, vault integration
Jitsi Components:
prosody- XMPP signaling serverjicofo- Conference focus/controljitsi-videobridge- Media bridgejitsi-meet- Web frontendjigasi- SIP gatewayjibri-*- Recording infrastructure (5 roles)prosody-egress- Recording/egress support
Infrastructure:
consul-*- Service discovery (11 roles: server, agent, template, etc.)haproxy*- Load balancing (6 roles includinghcv-haproxy-configure)nomad*- Container orchestration (3 roles)docker*- Container runtime (4 roles)
System:
common- Base system configurationsshusers,sshmfa- SSH access managementiptables*- Firewall rules (multiple specialized roles)wavefront,vector- Observabilityvault- Secrets management
- Load secrets from
secrets/*.yml - Load config from
config/vars.ymlandsites/$ENVIRONMENT/vars.yml - Pre-tasks: Clean up old repos, gather cloud metadata, set facts
- Roles: Apply configuration in dependency order
- Post-tasks: Restart services as needed
- Playbooks use
cloud_providervariable (aws/oracle) - Oracle instances fetch metadata from
http://169.254.169.254/opc/v1/ - AWS instances use
amazon.aws.ec2_metadata_facts - Conditional role application based on provider
- Jitsi component versions can be pinned via environment variables
- Default to latest with
*wildcard - Version format examples:
- JVB:
2.1-123-g1234567-1or* - Jicofo:
1.0-456-1or* - Meet:
1.0.7890-1or*
- JVB:
- HAProxy uses stick tables to map conferences to shards
- Global mesh synchronized via peer protocol
- Tenant pinning maps tenants to specific releases via
/etc/haproxy/maps/tenant.map - Live release defined in
/etc/haproxy/maps/live.map haproxy-reloadjob must run when shards are added/removedhaproxy-recyclejob replaces instances (breaks websocket connections)
- All secrets in
ansible/secrets/*.ymlare encrypted with Ansible Vault - Vault password file:
.vault-password.txt(not in git) - Always use
--vault-password-file .vault-password.txtwith playbooks
ansible.cfg:
- Fact caching enabled in
.facts/directory (24h TTL) - SSH connection pooling (15m persist)
- Custom SSH config:
config/ssh-vpn.config - Vault password file:
.vault-password.txt
Environment variables for scripts:
ENVIRONMENT- Environment name (required)ORACLE_REGION- Oracle cloud region (required for Oracle deployments)ROLE- Node role for inventory scriptsANSIBLE_SSH_USER- SSH user (defaults to current user)ANSIBLE_TAGS- Specific tags to run (defaults to "all")
See README_HAPROXY.md for detailed HAProxy operations including:
- Deploying new regions (requires consul KV:
consul kv put releases/$ENV/live release-XXXX) - Configuration rebuilds when shards change
- Upgrade checklist and verification steps
- Tenant pinning and live release management
- Split brain monitoring and patching
- Make changes to roles/playbooks
- Lint with ansible-lint (optional but recommended)
- Test on standalone instance first using
configure-standalone-oracle.sh - Deploy to target environment using appropriate configure playbook
- Verify with monitoring (Wavefront dashboards, Consul health checks)
- For HAProxy changes: Run
haproxy-reloadjob after configuration updates
- This repository depends on a private customizations repository (symlinked as
config/andsites/) - Some external roles (docker, haproxy, consul-template, memcached, nomad, nvm) are vendored directly in the repo under
ansible/roles/ - The
hcvlib.pylibrary provides core functionality for AWS and Oracle Cloud API interactions - Build playbooks create AMIs/images, configure playbooks provision running instances
- Oracle Cloud uses OCI SDK, AWS uses boto3