Skip to content

kbcasurf/oci-free-tier-provision

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Oracle Cloud Infrastructure (OCI) Free Tier Docker Swarm Deployment

A complete Infrastructure-as-Code solution for deploying a production-ready Docker Swarm cluster on Oracle Cloud Infrastructure's Always Free tier, featuring automatic provisioning, secure networking, and integrated monitoring with Traefik and Portainer.

🚀 Features

  • Fully Automated Deployment: One-command infrastructure provisioning and Swarm initialization
  • OCI Free Tier Optimized: Maximizes the Always Free ARM A1.Flex instance (4 OCPUs, 24GB RAM)
  • Production-Ready Stack: Docker Swarm with Traefik reverse proxy and Portainer management UI
  • Secure by Default: Pre-configured security lists, private networking, and SSL/TLS support
  • Infrastructure as Code: Complete Terraform configuration with state management
  • Automatic Environment Configuration: Dynamic .env file generation with instance details

📋 Prerequisites

Required Software

  • Terraform >= 1.5.0 (Installation Guide)
  • OCI CLI configured (Setup Instructions)
  • SSH Client with key pair generation capability
  • jq for JSON processing: sudo apt-get install jq (optional but recommended)

OCI Account Requirements

  • Oracle Cloud Infrastructure account with Free Tier access
  • Administrative access to create resources in a compartment
  • API keys configured for Terraform authentication

🏗️ Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                    Oracle Cloud Infrastructure                   │
│                         (Home Region)                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐  │
│  │               Virtual Cloud Network (VCN)                │  │
│  │                    10.0.0.0/16                           │  │
│  ├─────────────────────────────────────────────────────────┤  │
│  │                                                          │  │
│  │  ┌────────────────────────────────────────────────┐     │  │
│  │  │          Public Subnet (10.0.0.0/24)           │     │  │
│  │  │                                                │     │  │
│  │  │  ┌──────────────────────────────────────┐     │     │  │
│  │  │  │         ARM A1.Flex Instance         │     │     │  │
│  │  │  │          (Ubuntu 24.04 LTS)          │     │     │  │
│  │  │  │      4 OCPUs | 24GB RAM | 200GB     │     │     │  │
│  │  │  │                                      │     │     │  │
│  │  │  │  ┌─────────────────────────────┐    │     │     │  │
│  │  │  │  │     Docker Swarm Manager    │    │     │     │  │
│  │  │  │  ├─────────────────────────────┤    │     │     │  │
│  │  │  │  │   Traefik  │    Portainer  │    │     │     │  │
│  │  │  │  │  (Reverse  │  (Management  │    │     │     │  │
│  │  │  │  │   Proxy)   │      UI)      │    │     │     │  │
│  │  │  │  └─────────────────────────────┘    │     │     │  │
│  │  │  └──────────────────────────────────────┘     │     │  │
│  │  └────────────────────────────────────────────────┘     │  │
│  │                                                          │  │
│  │  Security List Rules:                                   │  │
│  │  • Ingress: SSH (22), HTTP (80), HTTPS (443)           │  │
│  │  • Egress: All traffic allowed                          │  │
│  └─────────────────────────────────────────────────────────┘  │
│                                                                 │
│  Network Components:                                            │
│  • Internet Gateway (for public access)                        │
│  • NAT Gateway (for outbound connections)                      │
│  • Service Gateway (for OCI services access)                   │
└─────────────────────────────────────────────────────────────────┘

🛠️ Project Structure

oci-free-tier-provision/
├── LICENSE                    # GNU GPLv3 license
├── README.md                  # This file
├── infra/                     # Network infrastructure configuration
│   ├── deploy.sh             # Automated deployment script
│   ├── main.tf               # VCN, subnet, and security configurations
│   ├── outputs.tf            # Infrastructure outputs (subnet ID, etc.)
│   ├── terraform.tfstate     # Terraform state file (auto-generated)
│   ├── terraform.tfvars      # Variable values (create from template)
│   └── variables.tf          # Variable definitions
├── vm/                        # Compute instance configuration
│   ├── deploy.sh             # VM deployment and env update script
│   ├── main.tf               # ARM A1.Flex instance configuration
│   ├── outputs.tf            # Instance outputs (IPs, etc.)
│   ├── terraform.tfstate     # Terraform state file (auto-generated)
│   ├── terraform.tfvars      # Variable values (create from template)
│   └── variables.tf          # Variable definitions
└── swarm-deploy/              # Docker Swarm deployment scripts
    ├── deploySwarm.sh        # Swarm initialization script
    ├── installDocker.sh      # Docker installation script
    ├── portainer.yaml        # Portainer stack configuration
    └── traefik.yaml          # Traefik stack configuration

📖 Step-by-Step Deployment Guide

Step 1: Initial Setup

  1. Clone the Repository

    git clone https://github.com/yourusername/oci-free-tier-provision.git
    cd oci-free-tier-provision
  2. Generate SSH Keys for VM Access

    # Generate a new SSH key pair for VM access
    ssh-keygen -t rsa -b 4096 -f ~/.ssh/oci_vm_key -C "your-email@example.com"
    
    # Set appropriate permissions
    chmod 600 ~/.ssh/oci_vm_key
    chmod 644 ~/.ssh/oci_vm_key.pub

Step 2: Configure OCI Authentication

  1. Create API Keys (if not already done)

    # Generate OCI API key pair
    mkdir -p ~/.oci
    openssl genrsa -out ~/.oci/oci_api_key.pem 2048
    openssl rsa -pubout -in ~/.oci/oci_api_key.pem -out ~/.oci/oci_api_key_public.pem
    
    # Generate fingerprint
    openssl rsa -pubout -outform DER -in ~/.oci/oci_api_key.pem | openssl md5 -c
  2. Upload Public Key to OCI Console

    • Log in to OCI Console
    • Navigate to Profile → User Settings → API Keys
    • Click "Add API Key" and paste the contents of ~/.oci/oci_api_key_public.pem
    • Note the fingerprint displayed
  3. Gather Required OCIDs

    • Tenancy OCID: Profile → Tenancy → Copy OCID
    • User OCID: Profile → User Settings → Copy OCID
    • Compartment OCID: Identity → Compartments → Select compartment → Copy OCID

Step 3: Configure Terraform Variables

  1. Create Environment File (.env in project root)

    cat > .env << 'EOF'
    # OCI Authentication
    export TF_VAR_tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaaxxxxxxxxxxxxxxxx"
    export TF_VAR_user_ocid="ocid1.user.oc1..aaaaaaaaxxxxxxxxxxxxxxxx"
    export TF_VAR_fingerprint="12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef"
    export TF_VAR_private_key_path="~/.oci/oci_api_key.pem"
    export TF_VAR_compartment_id="ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxx"
    export TF_VAR_region="sa-saopaulo-1"  # Change to your home region
    
    # SSH Keys
    export TF_VAR_ssh_public_key="~/.oci/oci_api_key.pem"  # For OCI API auth
    export TF_VAR_ssh_public_key2="$(cat ~/.ssh/oci_vm_key.pub)"  # For VM SSH access
    EOF
    
    # Set secure permissions
    chmod 600 .env
  2. Create Terraform Variable Files

    infra/terraform.tfvars:

    compartment_id   = "ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxx"
    region           = "sa-saopaulo-1"  # Your home region
    ssh_public_key   = "~/.oci/oci_api_key.pem"
    ssh_public_key2  = "ssh-rsa AAAAB3NzaC... your@email.com"  # Content of oci_vm_key.pub

    vm/terraform.tfvars:

    # Same content as infra/terraform.tfvars
    compartment_id   = "ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxxxxxxx"
    region           = "sa-saopaulo-1"
    ssh_public_key   = "~/.oci/oci_api_key.pem"
    ssh_public_key2  = "ssh-rsa AAAAB3NzaC... your@email.com"

Step 4: Deploy Infrastructure

  1. Deploy Network Infrastructure

    cd infra/
    
    # Option 1: Manual deployment
    source ../.env
    terraform init
    terraform plan  # Review the changes
    terraform apply
    
    # Option 2: Automated deployment (updates .env automatically)
    bash deploy.sh
  2. Deploy Virtual Machine

    cd ../vm/
    
    # Option 1: Manual deployment
    source ../.env
    terraform init
    terraform plan  # Review the changes
    terraform apply
    
    # Option 2: Automated deployment (updates .env and deploySwarm.sh)
    bash deploy.sh
  3. Verify Deployment

    # Source updated environment
    source ../.env
    
    # Test SSH connection
    ssh -i ~/.ssh/oci_vm_key ubuntu@$TF_VAR_instance_public_ip

Step 5: Install Docker and Initialize Swarm

  1. Install Docker on the VM

    cd ../swarm-deploy/
    
    # Install Docker (run from your local machine)
    cat installDocker.sh | ssh -i ~/.ssh/oci_vm_key ubuntu@$TF_VAR_instance_public_ip "bash -s"
    
    # Note: You may need to reconnect SSH for group changes to take effect
  2. Configure Portainer Domain (Optional)

    Edit swarm-deploy/portainer.yaml line 117:

    - "traefik.http.routers.portainer.rule=Host(`portainer.yourdomain.com`)"
  3. Deploy Docker Swarm Stack

    # Deploy Swarm, Traefik, and Portainer
    cat deploySwarm.sh | ssh -i ~/.ssh/oci_vm_key ubuntu@$TF_VAR_instance_public_ip "bash -s"

Step 6: Post-Deployment Configuration

  1. Verify Swarm Status

    ssh -i ~/.ssh/oci_vm_key ubuntu@$TF_VAR_instance_public_ip
    
    # Inside the VM:
    docker node ls
    docker service ls
    docker stack ls
  2. Access Portainer (if domain configured)

    • Navigate to: https://portainer.yourdomain.com
    • Create admin account on first access
  3. Configure DNS (for custom domains)

    • Add A record pointing to $TF_VAR_instance_public_ip
    • For Cloudflare users: Enable proxy for SSL termination

🔧 Advanced Configuration

Customizing Instance Specifications

Edit vm/main.tf to adjust resources:

shape_config {
  ocpus         = 4     # 1-4 for free tier
  memory_in_gbs = 24    # 1-24 for free tier
}

source_details {
  boot_volume_size_in_gbs = 200  # Up to 200GB free
}

Network Configuration

Modify infra/main.tf for different network settings:

vcn_cidrs = ["10.0.0.0/16"]      # VCN CIDR block
cidr_block = "10.0.0.0/24"       # Subnet CIDR block

Security Rules

Add custom security rules in infra/main.tf:

ingress_security_rules {
  protocol    = "6"  # TCP
  source      = "0.0.0.0/0"
  description = "Custom App"
  tcp_options { 
    max = 8080 
    min = 8080 
  }
}

Enable Let's Encrypt SSL

Uncomment the certificate resolver lines in swarm-deploy/traefik.yaml:

- "--certificatesresolvers.letsencryptresolver.acme.httpchallenge=true"
- "--certificatesresolvers.letsencryptresolver.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencryptresolver.acme.email=your_email@here.com"
- "--certificatesresolvers.letsencryptresolver.acme.storage=/etc/traefik/letsencrypt/acme.json"

🧹 Cleanup Instructions

To completely remove all resources:

# 1. Destroy VM first
cd vm/
terraform destroy -auto-approve

# 2. Destroy network infrastructure
cd ../infra/
terraform destroy -auto-approve

# 3. Clean up local files (optional)
rm -f terraform.tfstate* .terraform.lock.hcl
rm -rf .terraform/

🔍 Troubleshooting

Common Issues and Solutions

  1. "Out of capacity" error for A1.Flex instances

    • Try different availability domains
    • Deploy during off-peak hours
    • Consider using a different region
  2. SSH connection refused

    • Verify security list allows port 22
    • Check if correct SSH key is being used
    • Ensure instance is fully booted (wait 2-3 minutes)
  3. Terraform state issues

    • Run terraform refresh to sync state
    • Check .env file is sourced: source .env
    • Verify all OCIDs are correct
  4. Docker Swarm initialization fails

    • Ensure Docker is installed: docker --version
    • Check if user is in docker group: groups
    • Verify advertise address matches instance IP

Useful Commands

# Check OCI CLI configuration
oci iam region list --output table

# Validate Terraform configuration
terraform validate

# Show Terraform execution plan
terraform plan

# View instance details
terraform show -json | jq '.values.root_module.resources[] | select(.type=="oci_core_instance")'

# Monitor instance boot
ssh -i ~/.ssh/oci_vm_key ubuntu@$TF_VAR_instance_public_ip "sudo tail -f /var/log/cloud-init-output.log"

📚 Additional Resources

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

⚠️ Important Notes

  • Free Tier Limitations: Idle compute instances may be reclaimed after 7 days if CPU utilization is below 20%
  • Region Lock: Always Free resources are only available in your home region
  • No SLA: Oracle provides no service level agreements for Always Free resources
  • Email Restrictions: Port 25 (SMTP) is blocked by default on OCI instances

Created with ❤️ for the DevOps community. Happy deploying!

About

Terraform scripts to automate 4GB 24GB RAM ARM64 VM provision in OCI Free Tier + Scripts to configure Docker Swarm, Traefi and Portainer.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors