Skip to content

Complete Ansible-based automation system for provisioning Ubuntu servers and deploying numerous Go/Node microservices with PostgreSQL, Redis, NGINX reverse proxy, SSL certificates, and automated backups.

Notifications You must be signed in to change notification settings

maasumiyaat/ignition

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Automated Infrastructure Deployment with Ansible

Deploy 25+ Go/Node.js microservices on Ubuntu 22.04 LTS with PostgreSQL, Redis, NGINX, and automated SSL.

πŸ“ Project Structure

ignition/
β”œβ”€β”€ config.yaml              # YOUR SECRETS (gitignored, never commit)
β”œβ”€β”€ config.example.yaml      # Template (commit this)
β”œβ”€β”€ inventory.ini            # Server inventory
β”œβ”€β”€ ansible.cfg              # Ansible configuration
β”œβ”€β”€ .gitignore              # Protects secrets
β”œβ”€β”€ README.md               # This file
β”œβ”€β”€ playbooks/
β”‚   β”œβ”€β”€ provision.yml       # Server provisioning
β”‚   β”œβ”€β”€ deploy.yml          # Service deployment
β”‚   β”œβ”€β”€ nginx.yml           # NGINX + SSL setup
β”‚   β”œβ”€β”€ backup.yml          # Automated backups
β”‚   └── restore.yml         # Restore from backup
└── templates/
    β”œβ”€β”€ systemd-service.j2  # Systemd unit template
    └── nginx-site.conf.j2  # NGINX config template

πŸš€ Quick Start

1. Install Ansible

# Ubuntu/Debian
sudo apt update && sudo apt install ansible

# macOS
brew install ansible

# Verify
ansible --version

2. Setup Configuration

# Copy template
cp config.example.yaml config.yaml

# Edit with your values
nano config.yaml

3. Configure Your Services

In config.yaml, each service needs:

services:
  - name: auth-service           # Service identifier
    type: go                     # 'go' or 'node'
    github_repo: auth-service    # GitHub repo name
    backend_port: 8001           # Unique port
    frontend_enabled: true       # Has frontend?
    frontend_port: 3001          # Frontend port (if enabled)
    database_enabled: true       # Needs database?
    database_name: auth_db       # Database name
    run_migrations: true         # Run migrations?

Important: Each service reads its own config.yaml from its repository. This Ansible config only handles:

  • βœ… Which repos to clone
  • βœ… Port assignments
  • βœ… Database creation
  • βœ… Service orchestration

4. Setup GitHub Deploy Key

# Generate SSH key
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/github_deploy_key

# Add public key to GitHub org
cat ~/.ssh/github_deploy_key.pub
# Go to: https://github.com/organizations/YOUR-ORG/settings/keys
# Add as deploy key with READ access only

# Add private key to config.yaml
cat ~/.ssh/github_deploy_key
# Paste entire output (including BEGIN/END lines) into config.yaml

5. Setup DNS

Create A records for each service:

api.auth-service.example.com     β†’ YOUR_SERVER_IP
app.auth-service.example.com     β†’ YOUR_SERVER_IP
api.user-service.example.com     β†’ YOUR_SERVER_IP
app.user-service.example.com     β†’ YOUR_SERVER_IP
# ... for all services

6. Deploy

# Step 1: Provision server (one time)
ansible-playbook -i inventory.ini playbooks/provision.yml -e @config.yaml

# Step 2: Deploy all services
ansible-playbook -i inventory.ini playbooks/deploy.yml -e @config.yaml

# Step 3: Setup NGINX + SSL
ansible-playbook -i inventory.ini playbooks/nginx.yml -e @config.yaml

πŸ“ Configuration Reference

Server Connection

server:
  hostname: 123.45.67.89        # Server IP or domain
  ssh_user: root                # SSH user
  ssh_key_path: ~/.ssh/id_rsa   # SSH private key path

GitHub Settings

github:
  organization: your-github-org  # GitHub organization name
  ssh_deploy_key: |              # Private deploy key
    -----BEGIN OPENSSH PRIVATE KEY-----
    ...
    -----END OPENSSH PRIVATE KEY-----

Database Credentials

database:
  postgresql:
    version: 17
    admin_user: postgres
    admin_password: "YourStrongPassword123!"  # Change this
    port: 5432
  
  redis:
    password: "AnotherStrongPassword456!"     # Change this
    port: 6379

Service Configuration

Each service in the services array:

- name: payment-service          # Unique service name
  type: node                     # 'go' or 'node'
  github_repo: payment-service   # Repo name (not full URL)
  backend_port: 8003             # Unique backend port (8001-8999)
  frontend_enabled: false        # true if has frontend
  frontend_port: 3003            # Frontend port (3001-3999) if enabled
  database_enabled: true         # true if needs PostgreSQL
  database_name: payment_db      # Database name
  run_migrations: true           # true to run migrations on deploy

Service Config Files: Each service repo should have its own config.yaml with:

  • Database connection strings
  • API keys
  • Third-party credentials
  • Service-specific settings

πŸ”§ Operations

Deploy Single Service

# Re-deploy one service after code changes
ansible-playbook -i inventory.ini playbooks/deploy.yml -e @config.yaml \
  --extra-vars "services=[{'name':'auth-service','type':'go','github_repo':'auth-service','backend_port':8001,'database_enabled':true,'database_name':'auth_db'}]"

Check Service Status

# SSH into server
ssh deployer@YOUR_SERVER_IP

# Check service status
sudo systemctl status auth-service
sudo systemctl status auth-service-frontend

# View logs
sudo journalctl -u auth-service -f
sudo journalctl -u auth-service-frontend -f

# Restart service
sudo systemctl restart auth-service

Manual Backup

ansible-playbook -i inventory.ini playbooks/backup.yml -e @config.yaml

Restore from Backup

# List backups
ssh deployer@YOUR_SERVER_IP "ls -lh /var/backups/automated/"

# Restore (will prompt for timestamp)
ansible-playbook -i inventory.ini playbooks/restore.yml -e @config.yaml

πŸ—„οΈ Database Management

# Connect to PostgreSQL
ssh deployer@YOUR_SERVER_IP
sudo -u postgres psql

# List databases
\l

# Connect to specific database
\c auth_db

# List tables
\dt

# Connect to Redis
redis-cli
AUTH your_redis_password
PING
KEYS *

🌐 Service URLs

After deployment, services are accessible at:

Backend APIs:

https://api.auth-service.example.com
https://api.user-service.example.com
https://api.payment-service.example.com

Frontend Apps:

https://app.auth-service.example.com
https://app.user-service.example.com
https://app.catalog-service.example.com

πŸ” Security Features

  • βœ… UFW firewall (ports 22, 80, 443 only)
  • βœ… SSL/TLS certificates via Let's Encrypt
  • βœ… Auto-renewal of SSL certificates
  • βœ… GitHub deploy key (read-only)
  • βœ… PostgreSQL password authentication
  • βœ… Redis password protection
  • βœ… Encrypted backups (AES-256)
  • βœ… Service isolation (dedicated user)
  • βœ… Security headers in NGINX

πŸ› οΈ Troubleshooting

Service Won't Start

# Check status
sudo systemctl status service-name

# Check logs
sudo journalctl -u service-name -n 50

# Check if port is in use
sudo lsof -i :8001

# Verify binary exists (Go services)
ls -la /home/deployer/apps/service-name/service-name

# Check service config file exists
ls -la /home/deployer/apps/service-name/config.yaml

Database Connection Issues

# Check PostgreSQL is running
sudo systemctl status postgresql

# Verify database exists
sudo -u postgres psql -l | grep service_db

# Test connection
sudo -u postgres psql -d service_db -c "SELECT 1;"

SSL Certificate Issues

# Check certificates
sudo certbot certificates

# Renew manually
sudo certbot renew --dry-run

# Check NGINX config
sudo nginx -t

DNS Not Resolving

# Check DNS
nslookup api.auth-service.example.com
dig api.auth-service.example.com

# Wait for DNS propagation (can take 5-30 minutes)

πŸ“Š Service Configuration in Repos

Each service repository should have its own config.yaml:

# Example: auth-service/config.yaml
server:
  port: 8001
  host: 0.0.0.0

database:
  host: localhost
  port: 5432
  name: auth_db
  user: postgres
  password: ${DB_PASSWORD}  # From environment or config

redis:
  host: localhost
  port: 6379
  password: ${REDIS_PASSWORD}

jwt:
  secret: ${JWT_SECRET}
  expiry: 24h

logging:
  level: info
  format: json

This separation allows:

  • βœ… Service-specific configuration in each repo
  • βœ… Infrastructure-level config in Ansible
  • βœ… Easy local development
  • βœ… Clear separation of concerns

πŸ”„ Adding New Services

  1. Add to config.yaml:
services:
  - name: new-service
    type: go
    github_repo: new-service
    backend_port: 8026           # Use next available port
    frontend_enabled: false
    database_enabled: true
    database_name: new_service_db
    run_migrations: true
  1. Create DNS records:
api.new-service.example.com β†’ YOUR_SERVER_IP
  1. Deploy:
ansible-playbook -i inventory.ini playbooks/deploy.yml -e @config.yaml
ansible-playbook -i inventory.ini playbooks/nginx.yml -e @config.yaml

πŸ“ˆ Monitoring

Service logs are available via journalctl:

# Real-time logs
sudo journalctl -u auth-service -f

# Last 100 lines
sudo journalctl -u auth-service -n 100

# Logs since specific time
sudo journalctl -u auth-service --since "1 hour ago"

# All service logs
sudo journalctl -f | grep -E '(auth|user|payment)-service'

NGINX logs:

# Access logs
sudo tail -f /var/log/nginx/api.auth-service.example.com_access.log

# Error logs
sudo tail -f /var/log/nginx/api.auth-service.example.com_error.log

πŸ”’ Security Checklist

  • config.yaml is gitignored
  • Strong database passwords (20+ chars)
  • GitHub deploy key is read-only
  • SSH key has passphrase
  • UFW firewall enabled
  • SSL certificates active
  • Backups are encrypted
  • Services run as non-root user
  • Each service has its own config.yaml with secrets

πŸ“š Additional Resources

🀝 Support

For issues:

  1. Check service logs: sudo journalctl -u service-name -f
  2. Verify configuration: cat /home/deployer/apps/service-name/config.yaml
  3. Test connectivity: curl http://localhost:8001/health
  4. Check NGINX: sudo nginx -t

⚠️ Remember:

  • Never commit config.yaml to Git
  • Keep backup encryption keys safe
  • Rotate database passwords regularly
  • Monitor service logs for issues

About

Complete Ansible-based automation system for provisioning Ubuntu servers and deploying numerous Go/Node microservices with PostgreSQL, Redis, NGINX reverse proxy, SSL certificates, and automated backups.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages