This repository contains a full-stack Infrastructure-as-Code (IaC) solution to provision and manage a highly available K3s cluster on Oracle Cloud Infrastructure (OCI). It combines Terraform for infrastructure provisioning and Ansible (with dynamic inventory) for configuration management.
The setup is optimized for the OCI Always Free Tier (ARM-based Ampere A1 instances).
The project automates the deployment of:
- Network:
- 1 Virtual Cloud Network (VCN) & Public Subnet.
- Custom Security Lists for K3s (6443), SSH (22), and Web (80/443).
- Compute (K3s Cluster):
- 3 ARM-based Instances (
VM.Standard.A1.Flex):k3s-master: 2 OCPUs, 12 GB RAM.k3s-worker-1: 1 OCPU, 6 GB RAM.k3s-worker-2: 1 OCPU, 6 GB RAM.
- Distributed across Fault Domains for resilience.
- 3 ARM-based Instances (
- Load Balancer:
- 1 Flexible Load Balancer serving as the cluster entry point.
- Configuration Management:
- Ansible Dynamic Inventory: Real-time querying of Terraform state to manage nodes without static host files.
- Governance:
- A budget safety net ($1 threshold) with email alerts.
- OCI Account & API Credentials.
- Terraform (
>= 1.5.0). - Ansible (
>= 2.10). - Python 3 (for the dynamic inventory script).
- OCI CLI Configured.
# Initialize and apply
terraform init
terraform applyThe project includes an advanced dynamic inventory script that reads live from Terraform outputs.
Note: If your SSH key has a passphrase, you must add it to your session's SSH agent first:
# Start the agent and add your private key
eval $(ssh-agent -s)
ssh-add ~/.ssh/oci_key
# Test connectivity to all nodes
ansible all -m ping# Example: Run the connectivity test playbook
ansible-playbook ansible/ping.yml
# Install and Configure K3s Cluster
ansible-playbook ansible/site.ymlThe k3s_server role automatically configures your local ~/.kube/k3s.yaml to connect to the master node's Public IP. You can use kubectl directly from your local machine.
# Set KUBECONFIG
export KUBECONFIG=~/.kube/k3s.yaml
# Verify nodes
kubectl get nodes- Dynamic Inventory: Located at
ansible/terraform_inventory.py. It parsesterraform output -jsonand groups hosts into[master],[workers], and[load_balancer]. - Configuration:
ansible.cfgis pre-configured to use the dynamic inventory and set the default SSH user toubuntu.
node_public_ips: Map of node names to public IPs.load_balancer_ip: Public IP of the entry point.
A budget named Always-Free-Safety-Budget is created at the tenancy level. If spend reaches $1, an alert is sent to alert_email.
terraform destroyThis project is licensed under the MIT License.