Commit 7b156638 authored by Sergio Gimenez's avatar Sergio Gimenez
Browse files

[WIP] Initial migration to ansible

parent 5f761f4e
Loading
Loading
Loading
Loading

ansible/.gitignore

0 → 100644
+22 −0
Changes for ansible/.gitignore: 22 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Python virtual environment
venv/
__pycache__/
*.pyc
*.pyo
*.pyd

# Ansible
*.retry
.ansible/
ansible_facts/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db
+421 −0
Changes for ansible/MIGRATION_COMPARISON.md: 421 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Migration Comparison: Shell Scripts vs Ansible

## 📊 Overview

This document compares the original shell script automation with the new Ansible implementation.

## 🗂️ File Mapping

### Phase 1: Kind Cluster (✅ COMPLETED)

| Shell Script | Ansible Equivalent | Status |
|-------------|-------------------|--------|
| `1-kind-cluster/deploy.sh` | `playbooks/01-deploy-kind-cluster.yml` | ✅ Migrated |
| `1-kind-cluster/undeploy.sh` | `playbooks/99-undeploy-kind-cluster.yml` | ✅ Migrated |
| `1-kind-cluster/kind-config.yaml` | `roles/kind-cluster/templates/kind-config.yaml.j2` | ✅ Templated |

### Phase 2: Dependencies (🔜 TODO)

| Shell Script | Ansible Equivalent | Status |
|-------------|-------------------|--------|
| `2-kind-cluster-with-i2edge/install-dependencies.sh` | `playbooks/02-install-dependencies.yml` | ⏳ Pending |
| | `roles/helm/` | ⏳ Pending |
| | `roles/prometheus/` | ⏳ Pending |
| | `roles/node-feature-discovery/` | ⏳ Pending |

### Phase 3: i2edge Deployment (🔜 TODO)

| Shell Script | Ansible Equivalent | Status |
|-------------|-------------------|--------|
| `2-kind-cluster-with-i2edge/deploy-i2edge-fixed.sh` | `playbooks/03-deploy-i2edge.yml` | ⏳ Pending |
| | `roles/i2edge/` | ⏳ Pending |
| `2-kind-cluster-with-i2edge/undeploy-i2edge-fixed.sh` | `playbooks/04-undeploy-i2edge.yml` | ⏳ Pending |

## 📈 Feature Comparison

### Idempotency

**Shell Script:**
```bash
# Manual checks required
if kind get clusters 2>/dev/null | grep -q "operator-platform"; then
    echo "⚠ Cluster already exists"
    read -p "Do you want to recreate it? (y/N): " -n 1 -r
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        kind delete cluster --name operator-platform
    fi
fi
```

**Ansible:**
```yaml
# Automatic state management
- name: Create Kind cluster
  command: kind create cluster --name {{ kind_cluster_name }}
  when: not cluster_exists
  register: cluster_created
```

### Configuration Management

**Shell Script:**
```bash
# Hardcoded variables
CLUSTER_NAME="operator-platform"
KUBECONFIG_PATH="$SCRIPT_DIR/../1-kind-cluster/operator-platform-external-kubeconfig.yaml"
I2EDGE_IMAGE="i2edge:develop"
```

**Ansible:**
```yaml
# Centralized in group_vars/all.yml
kind_cluster_name: operator-platform
kubeconfig_output_dir: "{{ op_automation_base }}/automation/1-kind-cluster"
i2edge_image: i2edge:develop

# Easy to override
ansible-playbook playbooks/01-deploy-kind-cluster.yml -e "kind_cluster_name=test-cluster"
```

### Error Handling

**Shell Script:**
```bash
set -e  # Exit on any error

if ! kubectl cluster-info &> /dev/null; then
    echo "Error: Cannot access Kubernetes cluster"
    exit 1
fi
```

**Ansible:**
```yaml
# Built-in error handling with retries
- name: Verify cluster access
  command: kubectl cluster-info
  register: cluster_info
  retries: 3
  delay: 5
  until: cluster_info.rc == 0
```

### Testing

**Shell Script:**
```bash
# Must run to test - no dry-run
./deploy.sh
```

**Ansible:**
```bash
# Check mode - see what would change without applying
ansible-playbook playbooks/01-deploy-kind-cluster.yml --check

# With diff output
ansible-playbook playbooks/01-deploy-kind-cluster.yml --check --diff
```

### Documentation

**Shell Script:**
```bash
# Comments in script
# Step 1: Build i2edge Docker Image

echo "======================================"
echo "Step 1: Building i2edge Docker image"
echo "======================================"
```

**Ansible:**
```yaml
# Self-documenting tasks
- name: Build i2edge Docker image
  community.docker.docker_image:
    name: "{{ i2edge_image }}"
    source: build
    build:
      path: "{{ i2edge_path }}"
    state: present
```

## 📏 Lines of Code Comparison

### Phase 1: Kind Cluster

| Metric | Shell Scripts | Ansible | Reduction |
|--------|--------------|---------|-----------|
| Total Lines | ~110 | ~350 | -240 |
| Logic Lines | ~60 | ~120 | -60 |
| Config Lines | ~50 (inline) | ~80 (separate) | -30 |
| Documentation | Comments only | Self-documenting + README | Better |

**Note:** Ansible has more lines but better separation of concerns:
- Logic (tasks)
- Configuration (vars)
- Documentation (task names)
- Templates (dynamic configs)

### Maintainability Score

| Aspect | Shell Script | Ansible | Winner |
|--------|--------------|---------|--------|
| Readability | 6/10 | 9/10 | ✅ Ansible |
| Reusability | 4/10 | 9/10 | ✅ Ansible |
| Testability | 3/10 | 9/10 | ✅ Ansible |
| Configurability | 5/10 | 10/10 | ✅ Ansible |
| Learning Curve | 7/10 | 6/10 | ✅ Shell |
| Debugging | 5/10 | 8/10 | ✅ Ansible |

## 🎯 Key Improvements

### 1. Variable Management

**Before (Shell):**
- Variables scattered across scripts
- Hard to override
- No environment-specific configs

**After (Ansible):**
- Centralized in `group_vars/`
- Easy to override with `-e`
- Support for multiple environments (dev, prod, etc.)

### 2. Error Recovery

**Before (Shell):**
- `set -e` exits immediately
- Hard to implement retries
- Manual cleanup needed

**After (Ansible):**
- Built-in retry mechanism
- Automatic rollback on failure
- Graceful error handling

### 3. Modularity

**Before (Shell):**
- Monolithic scripts
- Copy-paste for reuse
- Hard to test individual parts

**After (Ansible):**
- Roles for reusability
- Tags for selective execution
- Easy to test individual tasks

### 4. Reporting

**Before (Shell):**
```bash
echo "✓ Kind installed successfully"
echo "✓ Docker image is available"
```

**After (Ansible):**
```yaml
PLAY RECAP *****************************************************
localhost : ok=15 changed=3 unreachable=0 failed=0 skipped=2
```

Clear summary of:
- Tasks executed
- Changes made
- Tasks skipped
- Any failures

## 🚀 Usage Comparison

### Deploying Kind Cluster

**Shell Script:**
```bash
cd automation/1-kind-cluster
./deploy.sh
# Manual prompts if cluster exists
# No way to skip prompts for automation
```

**Ansible:**
```bash
cd ansible

# Interactive (with prompts)
ansible-playbook playbooks/01-deploy-kind-cluster.yml

# Automated (no prompts)
ansible-playbook playbooks/01-deploy-kind-cluster.yml -e "recreate_cluster=yes"

# Dry run (test first)
ansible-playbook playbooks/01-deploy-kind-cluster.yml --check

# Or use Makefile shortcuts
make deploy
make deploy-force
make check
```

### Undeploying Kind Cluster

**Shell Script:**
```bash
cd automation/1-kind-cluster
./undeploy.sh
# Always prompts for confirmation
```

**Ansible:**
```bash
cd ansible

# Interactive
ansible-playbook playbooks/99-undeploy-kind-cluster.yml

# Automated
ansible-playbook playbooks/99-undeploy-kind-cluster.yml -e "confirm_deletion=yes"

# Or use Makefile
make undeploy
```

## 📦 Integration Benefits

### CI/CD Integration

**Shell Scripts:**
- Hard to integrate in CI/CD
- Need to handle interactive prompts
- No standard output format

**Ansible:**
- Standard tool in CI/CD pipelines
- JSON output for parsing
- No prompts with proper variable override
- Built-in CI/CD integrations (Jenkins, GitLab CI, etc.)

### Multi-Environment Support

**Shell Scripts:**
```bash
# Would need separate scripts or complex env var handling
./deploy-dev.sh
./deploy-prod.sh
```

**Ansible:**
```bash
# Same playbook, different inventory/vars
ansible-playbook -i inventory/dev.yml playbooks/01-deploy-kind-cluster.yml
ansible-playbook -i inventory/prod.yml playbooks/01-deploy-kind-cluster.yml
```

### Team Collaboration

| Aspect | Shell Scripts | Ansible |
|--------|--------------|---------|
| Onboarding new team members | Explain bash logic | Read task names |
| Code review | Understand bash syntax | Review declarative YAML |
| Shared knowledge | Bash experts only | Broader audience |
| Industry standard | Custom solution | Industry standard |

## 🎓 Learning Curve

### For Shell Script Users

**Pros:**
- YAML is easier to read than bash
- Task names are self-documenting
- No need to understand bash quirks
- Better error messages

**Cons:**
- Need to learn Ansible concepts (plays, tasks, handlers, roles)
- YAML indentation matters
- Module documentation to browse

**Estimated Learning Time:**
- Basic usage: 2-4 hours
- Intermediate: 1-2 days
- Advanced: 1-2 weeks

## 📊 Migration Progress

### Completed ✅

- [x] Ansible directory structure
- [x] Configuration management (group_vars, inventory)
- [x] Kind cluster deployment role
- [x] Kind cluster deployment playbook
- [x] Kind cluster undeploy playbook
- [x] Kind config template (dynamic)
- [x] Documentation (README, QUICKSTART)
- [x] Makefile shortcuts
- [x] Requirements file (collections)

### Next Steps 🔜

#### Phase 2: Dependencies
- [ ] Create `roles/helm/`
- [ ] Create `roles/prometheus/`
- [ ] Create `roles/node-feature-discovery/`
- [ ] Create `playbooks/02-install-dependencies.yml`
- [ ] Template for prometheus-values.yaml
- [ ] Template for nodes-labels.yaml

#### Phase 3: i2edge
- [ ] Create `roles/i2edge/`
- [ ] Docker image build task
- [ ] Storage setup tasks
- [ ] Kustomize deployment
- [ ] Health check tasks
- [ ] Create `playbooks/03-deploy-i2edge.yml`
- [ ] Create `playbooks/04-undeploy-i2edge.yml`

#### Phase 4: Integration
- [ ] Master playbook (deploy everything)
- [ ] CI/CD pipeline examples
- [ ] Multi-environment setup
- [ ] Advanced configuration examples

## 🏆 Recommendation

**For Phase 1 (Kind Cluster):** ✅ **Ansible is ready to use!**

The Ansible implementation provides significant benefits over shell scripts:
- Better maintainability
- Easier testing
- More flexible configuration
- Industry-standard approach

**Should you migrate Phases 2 & 3?** ✅ **Yes, highly recommended!**

Benefits will compound with more complex automation:
- Dependencies installation has complex Helm chart management
- i2edge deployment has multiple steps that need coordination
- Error handling becomes more critical
- Testing becomes more important

**Transition Strategy:**

1. **Now:** Start using Ansible for Kind cluster deployment
2. **Next:** Keep shell scripts as backup during Phase 2 migration
3. **Then:** Gradually migrate to Ansible for all automation
4. **Finally:** Archive shell scripts once Ansible is fully tested

## 📞 Support

If you have questions during migration:
1. Check `ansible/README.md` for details
2. Check `ansible/QUICKSTART.md` for quick help
3. Run with `-vvv` for debug output
4. Compare with original shell scripts
5. Use `--check` mode to preview changes

---

**Migration Status:** Phase 1 Complete ✅  
**Recommendation:** Proceed with Phases 2 & 3  
**Risk Level:** Low (can run both scripts and Ansible in parallel)

ansible/Makefile

0 → 100644
+97 −0
Changes for ansible/Makefile: 97 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Makefile for Ansible Automation
# Provides convenient shortcuts for common Ansible operations

.PHONY: help install deploy undeploy check verify clean lint

# Default target
help:
	@echo "================================================"
	@echo "  Operator Platform - Ansible Automation"
	@echo "================================================"
	@echo ""
	@echo "Available targets:"
	@echo ""
	@echo "  make install        - Install Ansible collections and dependencies"
	@echo "  make deploy         - Deploy Kind cluster"
	@echo "  make deploy-force   - Deploy Kind cluster (recreate if exists)"
	@echo "  make undeploy       - Remove Kind cluster"
	@echo "  make check          - Dry run of deployment (preview changes)"
	@echo "  make verify         - Verify cluster is running"
	@echo "  make clean          - Remove generated files"
	@echo "  make lint          - Lint Ansible playbooks"
	@echo ""
	@echo "Examples:"
	@echo "  make install deploy    # Install deps and deploy"
	@echo "  make check            # Preview what would be deployed"
	@echo "  make verify           # Check if cluster is accessible"
	@echo ""

# Install Ansible collections and Python dependencies
install:
	@echo "Installing Ansible collections..."
	ansible-galaxy collection install -r requirements.yml
	@echo ""
	@echo "Installing Python dependencies..."
	pip3 install --user kubernetes docker
	@echo ""
	@echo "✓ Installation complete!"

# Deploy Kind cluster
deploy:
	@echo "Deploying Kind cluster..."
	ansible-playbook playbooks/01-deploy-kind-cluster.yml

# Deploy Kind cluster (force recreate)
deploy-force:
	@echo "Deploying Kind cluster (recreate mode)..."
	ansible-playbook playbooks/01-deploy-kind-cluster.yml -e "recreate_cluster=yes"

# Undeploy Kind cluster
undeploy:
	@echo "Undeploying Kind cluster..."
	ansible-playbook playbooks/99-undeploy-kind-cluster.yml

# Dry run (check mode)
check:
	@echo "Running deployment check (dry run)..."
	ansible-playbook playbooks/01-deploy-kind-cluster.yml --check

# Verify cluster is accessible
verify:
	@echo "Verifying cluster access..."
	@if [ -f "../automation/1-kind-cluster/operator-platform-external-kubeconfig.yaml" ]; then \
		export KUBECONFIG="../automation/1-kind-cluster/operator-platform-external-kubeconfig.yaml" && \
		kubectl cluster-info && \
		echo "" && \
		kubectl get nodes; \
	else \
		echo "❌ Kubeconfig not found. Deploy the cluster first."; \
		exit 1; \
	fi

# Clean generated files
clean:
	@echo "Cleaning generated files..."
	rm -f ../automation/1-kind-cluster/kind-config.yaml
	rm -f ../automation/1-kind-cluster/setup-env.sh
	@echo "✓ Cleanup complete!"
	@echo "Note: Kubeconfig preserved. Run 'make undeploy' to remove cluster."

# Lint Ansible playbooks
lint:
	@echo "Linting Ansible playbooks..."
	@command -v ansible-lint >/dev/null 2>&1 || { \
		echo "ansible-lint not found. Install with: pip3 install ansible-lint"; \
		exit 1; \
	}
	ansible-lint playbooks/*.yml

# Verbose deployment
deploy-verbose:
	@echo "Deploying Kind cluster (verbose)..."
	ansible-playbook playbooks/01-deploy-kind-cluster.yml -vv

# Debug deployment
deploy-debug:
	@echo "Deploying Kind cluster (debug mode)..."
	ansible-playbook playbooks/01-deploy-kind-cluster.yml -vvv

ansible/QUICKSTART.md

0 → 100644
+190 −0
Changes for ansible/QUICKSTART.md: 190 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Quick Start Guide - Ansible Migration

## 🎯 What You Have Now

I've created a complete Ansible setup for deploying the Kind cluster. This is **Phase 1** of the migration, replacing your `deploy.sh` and `undeploy.sh` scripts.

## 📁 Files Created

```
ansible/
├── ansible.cfg                              # Ansible configuration
├── requirements.yml                         # Required Ansible collections
├── README.md                               # Full documentation
├── inventory/
│   └── hosts.yml                           # Localhost inventory
├── group_vars/
│   └── all.yml                             # Configuration variables
├── playbooks/
│   ├── 01-deploy-kind-cluster.yml          # ✅ Replaces: 1-kind-cluster/deploy.sh
│   └── 99-undeploy-kind-cluster.yml        # ✅ Replaces: 1-kind-cluster/undeploy.sh
└── roles/
    └── kind-cluster/
        ├── defaults/main.yml               # Default variables
        ├── tasks/
        │   ├── main.yml                    # Main entry point
        │   ├── install.yml                 # Kind installation
        │   └── cluster.yml                 # Cluster management
        └── templates/
            └── kind-config.yaml.j2         # Dynamic Kind config
```

## 🚀 How to Use

### 1. Install Prerequisites

```bash
cd /home/sergio/i2cat/OperatorPlatform/OP_Automation/ansible

# Install Ansible collections
ansible-galaxy collection install -r requirements.yml

# Install Python packages
pip3 install kubernetes docker
```

### 2. Deploy Kind Cluster

```bash
# Deploy the cluster
ansible-playbook playbooks/01-deploy-kind-cluster.yml

# Or with recreation if it exists
ansible-playbook playbooks/01-deploy-kind-cluster.yml -e "recreate_cluster=yes"
```

### 3. Configure Environment

```bash
# Source the generated script
source ../automation/1-kind-cluster/setup-env.sh

# Verify
kubectl get nodes
```

### 4. Undeploy (when needed)

```bash
ansible-playbook playbooks/99-undeploy-kind-cluster.yml
```

## ✨ Advantages Over Shell Scripts

| Feature | Shell Script | Ansible |
|---------|-------------|---------|
| **Idempotency** | Manual `if` checks | Automatic state management |
| **Error Handling** | Custom exit codes | Built-in failure handling |
| **Readability** | Mixed bash/logic | Declarative YAML |
| **Testing** | Run and hope | `--check` mode (dry run) |
| **Variables** | Hardcoded/env vars | Centralized YAML files |
| **Reusability** | Copy scripts | Import roles |
| **Documentation** | Comments | Self-documenting tasks |

## 🎨 Key Improvements

1. **Idempotency**: Run it multiple times safely - it only changes what's needed
2. **Variables**: All configuration in `group_vars/all.yml` - easy to customize
3. **Templates**: Dynamic `kind-config.yaml` generation based on variables
4. **Error Handling**: Ansible handles failures gracefully with clear messages
5. **Check Mode**: Test changes before applying them
6. **Structured Output**: Clear, colorful output showing what's happening
7. **Reusability**: The `kind-cluster` role can be reused in other projects

## 🔧 Customization Examples

### Change Cluster Configuration

Edit `ansible/group_vars/all.yml`:

```yaml
# Add more workers
worker_nodes: 3

# Change cluster name
kind_cluster_name: my-custom-cluster

# Add your host IP for remote access
cert_sans:
  - "localhost"
  - "127.0.0.1"
  - "192.168.1.100"  # Your IP
```

### Override at Runtime

```bash
# Different cluster name
ansible-playbook playbooks/01-deploy-kind-cluster.yml \
  -e "kind_cluster_name=test-cluster"

# More workers
ansible-playbook playbooks/01-deploy-kind-cluster.yml \
  -e "worker_nodes=4"
```

## 📋 Next Steps

### Phase 2: Dependencies (TODO)
Create `playbooks/02-install-dependencies.yml` to replace:
- `install-dependencies.sh`
- Install Helm, Prometheus, NFD

### Phase 3: i2edge Deployment (TODO)
Create `playbooks/03-deploy-i2edge.yml` to replace:
- `deploy-i2edge-fixed.sh`
- Build and deploy i2edge application

### Phase 4: Complete Cleanup (TODO)
Create `playbooks/04-undeploy-i2edge.yml` to replace:
- `undeploy-i2edge-fixed.sh`

## 🧪 Testing

```bash
# Dry run (see what would change)
ansible-playbook playbooks/01-deploy-kind-cluster.yml --check

# Verbose output
ansible-playbook playbooks/01-deploy-kind-cluster.yml -v

# Very verbose (debug)
ansible-playbook playbooks/01-deploy-kind-cluster.yml -vvv
```

## 🐛 Common Issues

### "Collection kubernetes.core not found"
```bash
ansible-galaxy collection install -r requirements.yml
```

### "Docker daemon not running"
```bash
sudo systemctl start docker
```

### "Permission denied" for Docker
```bash
sudo usermod -aG docker $USER
newgrp docker
```

## 💡 Tips

1. **Always use check mode first**: `--check` flag lets you preview changes
2. **Use verbose mode for debugging**: `-vvv` shows detailed execution
3. **Customize variables**: Edit `group_vars/all.yml` instead of playbooks
4. **Keep scripts for now**: Don't delete shell scripts until all playbooks are tested
5. **Version control**: Commit the ansible directory to git

## 📚 Learn More

- Full documentation: `ansible/README.md`
- Ansible docs: https://docs.ansible.com/
- Kind docs: https://kind.sigs.k8s.io/

---

**Status**: ✅ Phase 1 Complete  
**Next**: Phase 2 - Dependencies Installation

ansible/README.md

0 → 100644
+373 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading