This project implements zero-downtime deployments for FastAPI applications using Ansible and Nginx with a blue/green deployment strategy.
- Vagrant 2.2+
- Ansible 2.9+
- VirtualBox 6.0+
- Python 3.6+
- Load Balancer:
lb.example.com(Nginx) - Blue Environment:
blue.example.com - Green Environment:
green.example.com
.
├── playbooks/
│ ├── deploy.yml # Deploys application
│ ├── setup_loadbalancer.yml # Configures Nginx
│ ├── switch.yml # Switches traffic
│ └── cleanup.yml # Cleans old deployments
├── templates/
│ ├── fastapi.service.j2 # Systemd service template
│ └── loadbalancer.conf.j2 # Nginx config template
├── inventory/
│ └── production # Inventory file
└── app/
├── blue/ # Blue deployment files
└── green/ # Green deployment files
# Create all VMs
vagrant up
# Configure load balancer
ansible-playbook -i inventory/production playbooks/setup_loadbalancer.ymlansible-playbook -i inventory/production playbooks/deploy.yml \
-e "target_group=blue deployment_color=blue"ansible-playbook -i inventory/production playbooks/deploy.yml \
-e "target_group=green deployment_color=green"# Directly access green environment
curl http://green.example.com:8000
# Or through load balancer with test header
curl -H "X-Deployment: green" http://lb.example.comansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=green"ansible-playbook -i inventory/production playbooks/cleanup.yml \
-e "old_deployment_group=blue old_deployment_color=blue"# Switch back to blue
ansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=blue"
# Clean up green if needed
ansible-playbook -i inventory/production playbooks/cleanup.yml \
-e "old_deployment_group=green old_deployment_color=green"Check current traffic distribution:
vagrant ssh lb
sudo tail -f /var/log/nginx/access.log | awk '{print $6}' | sort | uniq -cValidate Nginx config:
vagrant ssh lb
sudo nginx -tView service status:
# On blue/green nodes
systemctl status fastapi-blue
systemctl status fastapi-greenSet in inventory/production:
[all:vars]
app_port=8000
domain=example.comFor canary releases:
ansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=green blue_weight=90 green_weight=10"ansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=green blue_weight=50 green_weight=50"ansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=green blue_weight=10 green_weight=90"ansible-playbook -i inventory/production playbooks/switch.yml \
-e "deployment_color=green blue_weight=0 green_weight=100"- Always test new deployments before switching traffic
- Monitor both environments during cutover
- Keep previous deployment until new one is verified stable
- Use low DNS TTL if using DNS-based switching
- Implement health checks in your application
Nginx fails to reload:
- Check syntax:
sudo nginx -t - Verify ports are open
- Ensure DNS resolution works
Service fails to start:
- Check logs:
journalctl -u fastapi-blue - Verify Python dependencies
- Check port availability
This README provides:
1. Clear step-by-step deployment instructions
2. Rollback procedures
3. Maintenance commands
4. Customization options
5. Troubleshooting tips
6. Best practices
The workflow ensures zero-downtime deployments with proper testing and rollback capabilities.