{
  "profile": {
    "name": "Juan Mónigo",
    "headline": "IT Infrastructure Analyst",
    "tagline": "Linux, networking and automation. Infrastructure deployed with one command and documented as code.",
    "summary": "IT Infrastructure technician with hands-on experience in support, networking, Linux and Python automation. I focus on shipping efficient solutions, providing effective technical support, and keeping infrastructure secure and running. Driven by innovation and continuous improvement.",
    "location": "Montevideo, Uruguay",
    "email": "jmonigo.work@gmail.com",
    "phone": "(598) 97 968 471",
    "linkedin": "https://www.linkedin.com/in/juan-monigo",
    "github": "https://github.com/frankfrot30",
    "open_to_work": true,
    "status": "Open to opportunities"
  },
  "experience": [
    {
      "company": "Thot Computación",
      "role": "Dispatch Department",
      "location": "Montevideo, Uruguay",
      "period": "Aug 2026 — present",
      "duration": "2 mos",
      "current": true,
      "bullets": [
        "Picking, checking and dispatching IT equipment orders, making sure every shipment leaves complete and on time.",
        "Daily coordination with sales and logistics to prioritise deliveries and solve issues before they reach the customer.",
        "The same approach I bring to infrastructure: clear processes, verification before delivery and end-to-end traceability."
      ],
      "stack": []
    },
    {
      "company": "Slantis LLC",
      "role": "IT COORDINATOR",
      "location": "Montevideo",
      "period": "Feb 2026 — Mar 2026",
      "duration": "1 mo",
      "current": false,
      "bullets": [
        "Point of contact for onboarding/offboarding processes.",
        "End-user support, Ubiquiti and MikroTik."
      ],
      "stack": [
        "Ubiquiti",
        "MikroTik"
      ]
    },
    {
      "company": "Kópel Sánchez",
      "role": "Technology & Innovation Advisor",
      "location": "Montevideo, Uruguay",
      "period": "Nov 2024 — Feb 2026",
      "duration": "1 yr 3 mos",
      "current": false,
      "bullets": [
        "Linux systems administration and cloud services (AWS / Google Cloud).",
        "Rolled out digital locking and access-control solutions.",
        "Technical support for 150+ internal users on Google Workspace and in-house systems.",
        "Tuned internal LAN networks (Ubiquiti and MikroTik) and documented the infrastructure."
      ],
      "stack": [
        "Linux",
        "AWS",
        "Google Cloud",
        "Google Workspace",
        "Redes LAN",
        "Ubiquiti",
        "MikroTik",
        "Control de accesos"
      ]
    }
  ],
  "education": [
    {
      "kind": "course",
      "institution": "Taller de informática",
      "title": "PC Maintenance & Repair Technician",
      "status": "Completed",
      "period": "October 2022 — December 2022",
      "detail": [
        "Software installation, hardware repair, preventive maintenance."
      ],
      "in_progress": false
    },
    {
      "kind": "degree",
      "institution": "Universidad ORT Uruguay",
      "title": "IT Infrastructure Analyst",
      "status": "Graduated",
      "period": "2023 — 2025",
      "detail": [],
      "in_progress": false
    },
    {
      "kind": "degree",
      "institution": "Universidad ORT Uruguay",
      "title": "Server & Application Administrator",
      "status": "Graduated",
      "period": "2023 — 2025",
      "detail": [],
      "in_progress": false
    },
    {
      "kind": "degree",
      "institution": "UDELAR",
      "title": "Computer Engineering",
      "status": "In progress",
      "period": "2020 — present",
      "detail": [],
      "in_progress": true
    }
  ],
  "skills": [
    {
      "name": "Linux (Debian / Ubuntu)",
      "category": "Systems",
      "level": 88,
      "band": "expert",
      "note": "Daily administration, hardening, systemd"
    },
    {
      "name": "Proxmox VE",
      "category": "Systems",
      "level": 85,
      "band": "expert",
      "note": "Virtualisation, cloud-init templates, GPU passthrough"
    },
    {
      "name": "Windows Server",
      "category": "Systems",
      "level": 78,
      "band": "advanced",
      "note": "Active Directory, GPO, file services"
    },
    {
      "name": "Bash",
      "category": "Systems",
      "level": 82,
      "band": "advanced",
      "note": "Provisioning and maintenance scripting"
    },
    {
      "name": "PowerShell",
      "category": "Systems",
      "level": 75,
      "band": "advanced",
      "note": "Automation across Windows and Proxmox"
    },
    {
      "name": "Docker",
      "category": "Containers & orchestration",
      "level": 85,
      "band": "expert",
      "note": "Multi-stage images, compose, registries"
    },
    {
      "name": "Kubernetes (kubeadm)",
      "category": "Containers & orchestration",
      "level": 70,
      "band": "advanced",
      "note": "HA clusters, kube-vip, Calico, RBAC"
    },
    {
      "name": "MetalLB / ingress-nginx",
      "category": "Containers & orchestration",
      "level": 70,
      "band": "advanced",
      "note": "Exposing services on bare-metal LAN"
    },
    {
      "name": "Longhorn",
      "category": "Containers & orchestration",
      "level": 66,
      "band": "solid",
      "note": "Replicated distributed storage"
    },
    {
      "name": "Python",
      "category": "IaC & automation",
      "level": 86,
      "band": "expert",
      "note": "Automation, scraping, APIs, bots"
    },
    {
      "name": "Terraform",
      "category": "IaC & automation",
      "level": 82,
      "band": "advanced",
      "note": "Provisioning on Proxmox and cloud"
    },
    {
      "name": "cloud-init",
      "category": "IaC & automation",
      "level": 69,
      "band": "solid",
      "note": "Reproducible VM templates"
    },
    {
      "name": "Ansible",
      "category": "IaC & automation",
      "level": 72,
      "band": "advanced",
      "note": "Server fleet configuration"
    },
    {
      "name": "GitHub Actions",
      "category": "IaC & automation",
      "level": 70,
      "band": "advanced",
      "note": "CI/CD, image build and publish"
    },
    {
      "name": "Google Workspace",
      "category": "Cloud",
      "level": 85,
      "band": "expert",
      "note": "Administration for 150+ users"
    },
    {
      "name": "AWS",
      "category": "Cloud",
      "level": 68,
      "band": "solid",
      "note": "EC2, S3, IAM, VPC"
    },
    {
      "name": "Google Cloud",
      "category": "Cloud",
      "level": 79,
      "band": "advanced",
      "note": "Compute Engine, IAM, storage"
    },
    {
      "name": "LAN / VLAN / routing",
      "category": "Networking",
      "level": 82,
      "band": "advanced",
      "note": "Internal network segmentation and tuning"
    },
    {
      "name": "pfSense",
      "category": "Networking",
      "level": 85,
      "band": "expert",
      "note": "Firewall, captive portal, HAProxy"
    },
    {
      "name": "DNS / DHCP",
      "category": "Networking",
      "level": 82,
      "band": "advanced",
      "note": "Internal network services"
    },
    {
      "name": "WireGuard",
      "category": "Networking",
      "level": 80,
      "band": "advanced",
      "note": "Site-to-site and road-warrior VPN"
    },
    {
      "name": "RADIUS / 802.1X",
      "category": "Networking",
      "level": 78,
      "band": "advanced",
      "note": "WPA2-Enterprise network authentication"
    },
    {
      "name": "Hardening de Linux",
      "category": "Security",
      "level": 75,
      "band": "advanced",
      "note": "Minimal surface, key-only SSH, scoped sudo"
    },
    {
      "name": "Control de accesos",
      "category": "Security",
      "level": 78,
      "band": "advanced",
      "note": "Digital locking and physical access"
    },
    {
      "name": "Wazuh / SIEM",
      "category": "Security",
      "level": 72,
      "band": "advanced",
      "note": "Detection and active response"
    },
    {
      "name": "Gestión de vulnerabilidades",
      "category": "Security",
      "level": 72,
      "band": "advanced",
      "note": "CVE scanning and remediation"
    },
    {
      "name": "Git",
      "category": "Development",
      "level": 80,
      "band": "advanced",
      "note": "Branching, review, CI workflow"
    },
    {
      "name": "Django",
      "category": "Development",
      "level": 76,
      "band": "advanced",
      "note": "Management apps, ORM, admin, deployment"
    },
    {
      "name": "SQL (MySQL / MariaDB)",
      "category": "Development",
      "level": 72,
      "band": "advanced",
      "note": "Modelling, queries, backups"
    },
    {
      "name": "HTML / CSS / JS",
      "category": "Development",
      "level": 72,
      "band": "advanced",
      "note": "Interfaces without heavy frameworks"
    }
  ],
  "languages": [
    {
      "name": "Spanish",
      "level": "Native",
      "dots": 5
    },
    {
      "name": "English",
      "level": "Upper intermediate — technical and conversational",
      "dots": 5
    }
  ],
  "projects": [
    {
      "slug": "k8s-ha-proxmox",
      "title": "HA Kubernetes cluster on Proxmox",
      "summary": "Highly available kubeadm cluster, scalable to N nodes, provisioned with Terraform and bootstrapped with a single command.",
      "body": [
        "Terraform clones N Debian machines from a cloud-init template on Proxmox VE and a single script turns them into a production-shaped Kubernetes cluster.",
        "The control plane sits behind a VIP managed by kube-vip in ARP mode: if a node dies another one takes the IP and the cluster keeps answering, with no external load balancer.",
        "On top of it sit the addons that make a bare-metal cluster actually usable: CNI, LoadBalancer, ingress, metrics and replicated storage."
      ],
      "highlights": [
        "Default topology of 3 control-plane + 2 workers, fully parameterised",
        "kube-vip for control-plane HA without an external load balancer",
        "Calico CNI with NetworkPolicies, MetalLB in L2 mode and ingress-nginx",
        "Longhorn as the default StorageClass, replicated across nodes",
        "Debian cloud-init template built by the script itself: zero manual steps"
      ],
      "stack": [
        "Terraform",
        "Proxmox VE",
        "Kubernetes",
        "kubeadm",
        "kube-vip",
        "Calico",
        "MetalLB",
        "ingress-nginx",
        "Longhorn",
        "containerd",
        "cloud-init"
      ],
      "area": "infra",
      "year": "2026",
      "status": "done",
      "repo": "",
      "demo": "",
      "url": "/proyectos/k8s-ha-proxmox/"
    },
    {
      "slug": "portal-cautivo-pfsense",
      "title": "pfSense captive portal with vouchers",
      "summary": "Migrated a WPA2-Enterprise (802.1X / RADIUS) WiFi to WPA2 with a pre-shared key plus a captive portal as a second factor, reusing the existing RADIUS as the user store and adding guest vouchers.",
      "body": [
        "The WiFi ran WPA2-Enterprise with RADIUS. It worked, but it locked out guests and every device that could not speak 802.1X.",
        "The migration moved the network to WPA2 with a pre-shared key and added the pfSense captive portal as a second factor: knowing the WiFi key is not enough to get online, each device also has to authenticate. The portal queries the same RADIUS server as before, so nobody had to change their password.",
        "Guests got a voucher system with expiry, and the portal pages (login, error and logout) were hand-written so the experience would not look like a router form."
      ],
      "highlights": [
        "Two factors to get on the network: the WiFi key plus a portal login",
        "Authentication against the existing RADIUS, no credential migration",
        "Expiring vouchers for guests",
        "Custom responsive login, error and logout pages",
        "Works with devices that cannot do 802.1X (IoT, consoles, TVs)"
      ],
      "stack": [
        "pfSense",
        "FreeRADIUS",
        "WPA2-PSK",
        "802.1X",
        "HTML",
        "CSS",
        "Redes WiFi"
      ],
      "area": "redes",
      "year": "2025",
      "status": "live",
      "repo": "",
      "demo": "",
      "url": "/proyectos/portal-cautivo-pfsense/"
    },
    {
      "slug": "bot-busqueda-laboral",
      "title": "Job-hunting bot with fit scoring",
      "summary": "Collects job posts from several boards, de-duplicates against SQLite, scores how well each one fits the profile and emails only what is worth reading.",
      "body": [
        "The problem was never finding openings, it was re-reading the same hundred. The bot queries several boards in parallel with per-role queries and stores everything seen in SQLite, so each run only surfaces what is new.",
        "Before notifying it applies a local 0-100 fit filter that looks at the role in the title, the technologies, the seniority (penalising senior, lead and manager) and geographic eligibility for remote work. Anything below the threshold is dropped for free.",
        "Only the candidates that clear the filter optionally go through the Claude API for a commented score and a draft application."
      ],
      "highlights": [
        "Persistent de-duplication in SQLite: never shows the same post twice",
        "Free local scoring before spending any AI tokens",
        "A --solo-buscar dry-run mode to calibrate thresholds with no side effects",
        "Email notifications",
        "Cover letter and email draft generation for the best matches"
      ],
      "stack": [
        "Python",
        "SQLite",
        "Claude API",
        "SMTP",
        "YAML",
        "requests"
      ],
      "area": "automatizacion",
      "year": "2025",
      "status": "live",
      "repo": "",
      "demo": "",
      "url": "/proyectos/bot-busqueda-laboral/"
    },
    {
      "slug": "premiadent",
      "title": "Premiadent: appointment management with IaC deployment",
      "summary": "Django application for appointments and patients, with its infrastructure deployed by Terraform on Proxmox and a vulnerability audit of the stack.",
      "body": [
        "Web application to manage appointments, patients and accounts, built on Django and its ORM over a purpose-built relational model.",
        "Deployment is not manual: Terraform provisions the infrastructure on Proxmox and leaves the environment reproducible from scratch.",
        "The deployed stack then went through a reconnaissance and CVE-scanning exercise, with its own findings and remediation report."
      ],
      "highlights": [
        "Purpose-built domain model: accounts, patients and appointments",
        "Infrastructure declared in Terraform on Proxmox",
        "Recon, CVE scanning and a remediation report",
        "Later migration of the deployment to Kubernetes"
      ],
      "stack": [
        "Django",
        "Python",
        "SQL",
        "Terraform",
        "Proxmox",
        "Docker"
      ],
      "area": "dev",
      "year": "2025",
      "status": "live",
      "repo": "",
      "demo": "",
      "url": "/proyectos/premiadent/"
    },
    {
      "slug": "wazuh-cloudflare",
      "title": "Active response: Wazuh blocking at Cloudflare",
      "summary": "Integration wiring Wazuh alerts to Cloudflare to block attacking IPs at the edge, before they ever reach the server.",
      "body": [
        "Detecting an attack but being unable to stop it until the next day is only half the job. This integration closes the loop: when Wazuh triggers one of the configured rules, an active response script writes the source IP to Cloudflare Workers KV, and a Worker returns a 403 for every request coming from that IP.",
        "Blocking happens at Cloudflare's edge, so malicious traffic doesn't even consume bandwidth or CPU cycles on the origin server.",
        "Blocks are temporary and become permanent for repeat offenders. The script skips internal IPs to avoid locking ourselves out during testing."
      ],
      "highlights": [
        "Wazuh active response wired to Cloudflare Workers KV",
        "Edge blocking, without touching the origin firewall",
        "Temporary blocks that escalate to permanent for repeat offenders",
        "Allowlist and protection against blocking its own public IP",
        "Fed by fail2ban and the WAF on the Caddy reverse proxies"
      ],
      "stack": [
        "Wazuh",
        "Cloudflare Workers",
        "Workers KV",
        "Python",
        "fail2ban",
        "Caddy",
        "Coraza WAF",
        "Docker"
      ],
      "area": "seguridad",
      "year": "2025",
      "status": "live",
      "repo": "",
      "demo": "",
      "url": "/proyectos/wazuh-cloudflare/"
    },
    {
      "slug": "migracion-k8s",
      "title": "Migrating a monolithic app to Kubernetes",
      "summary": "Containerised an application that ran straight on a VM and moved it to Kubernetes manifests, with persistent storage and ingress.",
      "body": [
        "The application lived hand-installed on a VM: it worked, but every change was unrepeatable and every restore was a lost afternoon.",
        "The work was writing its Dockerfile, defining Deployment, Service and Ingress, solving state with persistent volumes and leaving the deployment versioned in Git."
      ],
      "highlights": [
        "Containerised a hand-installed application",
        "Versioned Deployment, Service and Ingress",
        "State solved with persistent volumes",
        "Repeatable deployment from scratch"
      ],
      "stack": [
        "Docker",
        "Kubernetes",
        "YAML",
        "Ingress",
        "PersistentVolumes"
      ],
      "area": "infra",
      "year": "2026",
      "status": "done",
      "repo": "",
      "demo": "",
      "url": "/proyectos/migracion-k8s/"
    },
    {
      "slug": "cv-web",
      "title": "This site: an interactive CV in Django",
      "summary": "The site you are reading. Django + PostgreSQL in two unprivileged Proxmox LXCs, supervised by systemd, with content editable from the admin and no JavaScript frameworks or trackers.",
      "body": [
        "The CV is not written into the HTML: it lives in the database and is edited from the Django admin, so fixing a date does not require a deploy.",
        "It runs in an unprivileged LXC container on Proxmox, with systemd supervising gunicorn. The unit is hardened: shell-less user, read-only filesystem except two paths, no capabilities and a restricted syscall filter. PostgreSQL lives in a second container that only accepts encrypted connections from the application.",
        "The terminal on the front page is not a frontend toy: every command travels to a Django endpoint that resolves it against the same models that render the page, and it is covered by tests.",
        "It uses no JavaScript frameworks, remote fonts, analytics or trackers: code and styles come from the server itself, with a CSP that only allows the same origin. It is published behind Cloudflare and two Caddy reverse proxies in high availability."
      ],
      "highlights": [
        "Unprivileged LXC created from a script, not from the GUI",
        "Hardened systemd unit: no capabilities, read-only filesystem",
        "PostgreSQL in its own container: TLS, scram-sha-256 and 5432 open to a single IP",
        "Bilingual content in the database, editable without redeploying",
        "Terminal with a server-side command engine, covered by tests",
        "Deploy that validates before reloading: on failure the previous version stays up"
      ],
      "stack": [
        "Django",
        "Python",
        "PostgreSQL",
        "Proxmox LXC",
        "systemd",
        "gunicorn",
        "WhiteNoise",
        "Caddy",
        "Cloudflare",
        "Bash",
        "HTML",
        "CSS",
        "JavaScript"
      ],
      "area": "dev",
      "year": "2026",
      "status": "live",
      "repo": "",
      "demo": "",
      "url": "/proyectos/cv-web/"
    }
  ],
  "meta": {
    "lang": "en",
    "source": "https://cv.juanmonigo.com"
  }
}