Skip to content

42-Course/cloud-1

Repository files navigation

Cloud-1: Automated Deployment of Inception

"There is no cloud, it's just someone else's computer"

All mandatory requirements from the Cloud-1 subject have been successfully implemented and verified.

Quick Verification

# Test WordPress accessibility
curl -I http://51.159.150.9/  # Should return: HTTP/1.1 200 OK

# Test PHPMyAdmin accessibility
curl -I http://51.159.150.9/phpmyadmin/  # Should return: HTTP/1.1 200 OK

# Check all 4 containers running
ssh root@51.159.150.9 "docker ps"

# Verify automated deployment
ansible all -i inventory/hosts -m ping

This project automates the deployment of a WordPress stack (inspired by Inception) on a remote server using Ansible. Each service runs in a separate Docker container following the principle of 1 process = 1 container.

Table of Contents


Overview

Cloud-1 deploys a fully functional WordPress website with:

  • WordPress - Content Management System
  • MariaDB/MySQL - Database server
  • Nginx - Web server and reverse proxy
  • PHPMyAdmin - Database management interface

Key Requirements Met

  • Fully automated deployment using Ansible
  • Each process in its own container
  • Data persistence across reboots
  • Automatic restart on server reboot
  • Secure configuration (no direct database access from internet)
  • TLS/HTTPS support
  • Multi-server deployment capability

Architecture

┌─────────────────────────────────────────────────┐
│            Remote Server (Cloud)                │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │          Nginx Container                │    │
│  │      (Reverse Proxy + TLS)              │    │
│  │         Port 80/443                     │    │
│  └──────────┬──────────────────────────────┘    │
│             │                                   │
│  ┌──────────▼──────────┐  ┌─────────────────┐   │
│  │  WordPress          │  │  PHPMyAdmin     │   │
│  │  Container          │  │  Container      │   │
│  │  (PHP-FPM)          │  │                 │   │
│  └──────────┬──────────┘  └────────┬────────┘   │
│             │                      │            │
│             └──────────┬───────────┘            │
│                        │                        │
│             ┌──────────▼──────────┐             │
│             │   MariaDB           │             │
│             │   Container         │             │
│             │   (Internal only)   │             │
│             └─────────────────────┘             │
│                                                 │
│  Docker Network: inception-network              │
│  Data Volumes: /home/ubuntu/inception/data      │
└─────────────────────────────────────────────────┘

Container Architecture

Container Base Image Purpose Exposed Ports
nginx Custom (Debian/Alpine) Web server, SSL termination, reverse proxy 80, 443
wordpress Custom (PHP-FPM) WordPress application 9000 (internal)
mariadb Custom (MariaDB) Database server 3306 (internal)
phpmyadmin Custom (PHP-FPM) Database admin UI 9000 (internal)

Prerequisites

Local Machine Requirements

  • Ansible >= 2.9
    sudo apt install ansible
    # or
    pip3 install ansible
  • Python >= 3.8
  • SSH access to remote server
  • Git for version control

Remote Server Requirements

  • Ubuntu 20.04 LTS (as specified in project requirements)
  • SSH daemon running
  • Python installed (usually pre-installed)
  • Root or sudo access
  • Minimum 1GB RAM recommended
  • Open ports: 22 (SSH), 80 (HTTP), 443 (HTTPS)

Cloud Provider Setup

Using Scaleway (Recommended, Free Acces for 42Students)

  1. Subscribe to the project and you will receive an email
  2. Get your ssh connection via email. (will have your ssh keys from your intra allowing access via ssh)

Alternative Providers

  • AWS
  • Google Cloud Platform
  • DigitalOcean
  • Heroku

Warning: Monitor your cloud resource usage! You are responsible for any costs incurred.


Project Structure

cloud-1/
├── README.md                    # This file
├── site.yml                     # Main playbook for deploying WordPress stack
├── provision.yml                # Playbook for provisioning cloud instances
├── inventory/
│   └── hosts                    # Ansible inventory file (static or dynamic)
├── roles/
│   └── docker/
│       └── tasks/
│           └── main.yml         # Tasks to install Docker and docker-compose
├── files/                       # Files to be copied to remote server
│   ├── docker-compose.yml       # Docker compose configuration
│   ├── .env                     # Environment variables (DO NOT COMMIT!)
│   └── nginx.conf               # Nginx configuration
├── Inception/                   # Original Inception project (reference)
│   └── srcs/
│       ├── docker-compose.yml
│       └── requirements/
│           ├── nginx/
│           ├── wordpress/
│           └── mariadb/
└── docs/                        # Additional documentation
    ├── SECURITY.md              # Security best practices
    └── TROUBLESHOOTING.md       # Common issues and solutions

Key Files Explained

  • site.yml: Main Ansible playbook that orchestrates the deployment
  • provision.yml: Creates and configures cloud instances (not needed in my case)
  • roles/docker/: Ansible role that installs Docker and dependencies
  • inventory/hosts: Defines target servers for deployment
  • files/: Contains configuration files copied to remote server

Quick Start

1. Install Dependencies

# Install Ansible
sudo apt install ansible

# Install Scaleway collection (if using Scaleway)
ansible-galaxy collection install scaleway.scaleway

2. Configure Inventory

Edit inventory/hosts with your server IP:

[scaleway-wordpress]
your.server.ip.address ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

3. Prepare Configuration Files

Create files/ directory with necessary configurations:

mkdir -p files
# Copy docker-compose.yml, .env, nginx.conf to files/

4. Deploy

# Check connectivity
ansible scaleway-wordpress -i inventory/hosts -m ping

# Run deployment (dry-run)
ansible-playbook site.yml -i inventory/hosts --check

# Actual deployment
ansible-playbook site.yml -i inventory/hosts

5. Access Your Site

Open browser: http://your.server.ip.address


Detailed Setup

Step 1: Provision Server (Optional)

If you want to automate server creation:

  1. Edit provision.yml:

    vars:
      scaleway_api_token: "YOUR_API_TOKEN"
      scaleway_project_id: "YOUR_PROJECT_ID"
      ssh_key_name: "your_ssh_key_name"
  2. Run provisioning:

    ansible-playbook provision.yml

Security Note: Never commit API tokens to version control. Use environment variables or Ansible Vault.

Step 2: Configure Environment Variables

Create files/.env with your configuration:

# Database Configuration
MYSQL_ROOT_PASSWORD=secure_root_password_here
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=secure_wp_password_here

# WordPress Configuration
WORDPRESS_DB_HOST=mariadb:3306
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wpuser
WORDPRESS_DB_PASSWORD=secure_wp_password_here

# Domain Configuration
DOMAIN_NAME=your.domain.com

Important: Add .env to .gitignore to prevent credential leaks!

Step 3: Configure Ansible Inventory

Static Inventory (inventory/hosts)

[scaleway-wordpress]
192.168.1.100 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

[scaleway-wordpress:vars]
ansible_python_interpreter=/usr/bin/python3

Dynamic Inventory (Advanced)

For dynamic cloud inventories, use provider plugins (AWS, GCP, Scaleway).

Step 4: Customize Docker Compose

Edit files/docker-compose.yml to match your requirements. See the Inception project reference for container configurations.

Step 5: Run Deployment

# Syntax check
ansible-playbook site.yml -i inventory/hosts --syntax-check

# Dry run (check mode)
ansible-playbook site.yml -i inventory/hosts --check

# Lint the playbook
ansible-lint site.yml

# Deploy
ansible-playbook site.yml -i inventory/hosts

# Deploy with increased parallelism
ansible-playbook site.yml -i inventory/hosts -f 10

Configuration

Ansible Variables

Key variables in site.yml:

vars:
  project_name: "inception"                    # Project name for Docker compose
  docker_compose_path: "/home/ubuntu/inception" # Installation directory

Docker Role Variables

Defined in roles/docker/tasks/main.yml:

  • Installs Docker CE, docker-compose
  • Adds user to docker group
  • Enables Docker service on boot

Networking

The docker-compose setup creates an internal network where containers communicate using service names:

  • WordPress connects to mariadb:3306
  • PHPMyAdmin connects to mariadb:3306
  • Nginx proxies to wordpress:9000 and phpmyadmin:9000

Deployment Workflow

Full Deployment Process

  1. Provision Infrastructure (if automated)

    ansible-playbook provision.yml
  2. Install Dependencies (Docker, docker-compose)

    • Handled by docker role
    • Updates system packages
    • Installs Docker from official repository
  3. Deploy Application

    ansible-playbook site.yml -i inventory/hosts
    • Creates project directory
    • Copies docker-compose.yml, .env, configs
    • Launches containers
    • Waits for service availability
    • Enables auto-restart on boot
  4. Verify Deployment

    # SSH to server
    ssh ubuntu@your.server.ip
    
    # Check containers
    docker ps
    
    # Check logs
    docker-compose -f /home/ubuntu/inception/docker-compose.yml logs

Update Workflow

To update an existing deployment:

# Pull latest changes
git pull

# Re-run playbook (Ansible is idempotent)
ansible-playbook site.yml -i inventory/hosts

# Or use tags for specific tasks
ansible-playbook site.yml -i inventory/hosts --tags "docker-compose"

Rollback Procedure

# SSH to server
ssh ubuntu@your.server.ip

# Stop containers
cd /home/ubuntu/inception
docker-compose down

# Restore backup (if available)
# ... restore commands ...

# Restart with old configuration
docker-compose up -d

Security Considerations

Critical Security Practices

  1. Credentials Management

    • Never commit .env files
    • Use Ansible Vault for sensitive data:
      ansible-vault encrypt files/.env
      ansible-playbook site.yml --ask-vault-pass
  2. Network Security

    • Database not exposed to internet (internal Docker network only)
    • Use firewall rules (ufw, iptables)
    • Only open necessary ports (80, 443, 22)
  3. SSH Security

    • Disable password authentication
    • Use SSH keys only
    • Consider changing default SSH port
    • Use fail2ban for brute force protection
  4. TLS/HTTPS

    • Use Let's Encrypt for free SSL certificates
    • Configure in nginx.conf
    • Redirect HTTP to HTTPS
  5. Docker Security

    • Run containers as non-root users
    • Use official base images
    • Keep images updated
    • Scan for vulnerabilities

See docs/SECURITY.md for detailed security guide.


Troubleshooting

Common Issues

1. Ansible Connection Failed

# Test connectivity
ansible scaleway-wordpress -i inventory/hosts -m ping

# Check SSH manually
ssh -i ~/.ssh/id_rsa ubuntu@your.server.ip

# Verify SSH key
ssh-add -l

2. Docker Containers Not Starting

# SSH to server
ssh ubuntu@your.server.ip

# Check container status
docker ps -a

# View logs
docker-compose -f /home/pulgamecanica/inception/docker-compose.yml logs

# Restart containers
docker-compose -f /home/pulgamecanica/inception/docker-compose.yml restart

3. WordPress Not Accessible

# Check nginx is running
docker ps | grep nginx

# Test from server
curl http://localhost

# Check firewall
sudo ufw status

4. Database Connection Issues

# Check MariaDB container
docker ps | grep mariadb

# Test database connection
docker exec -it <mariadb_container_id> mysql -u wpuser -p

# Verify environment variables
docker-compose -f /home/pulgamecanica/inception/docker-compose.yml config

Debugging Tips

# Run playbook in verbose mode
ansible-playbook site.yml -i inventory/hosts -vvv

# Check specific task
ansible-playbook site.yml -i inventory/hosts --start-at-task="Task name"

# Syntax check
ansible-playbook site.yml --syntax-check

# Lint playbook
ansible-lint site.yml

Learning Resources

Ansible

Docker

WordPress

Cloud Providers

Networking & Security


Remember: Always monitor your cloud resources. Turn off services you're not using to avoid unexpected charges!

About

Ansible automation of a Wordpress installation

Topics

Resources

Stars

Watchers

Forks