open to junior cloud / devops roles

Karim
El Atfy

Junior Cloud & DevOps Engineer · Politecnico di Milano

I build and ship infrastructure on Azure with Terraform, containers and CI/CD. Most of what I know comes from real work: a client collaboration where I made a manual deploy safe to repeat, and six Azure labs I built one layer at a time.

AZ-104
azure administrator
6
azure iac labs
1
real client case study
Milan/Varese
remote · hybrid
01 featured case study real collaboration

FlowLedger: making a manual deploy safe to repeat

An early-stage SaaS was deploying by hand and had just been burned by it. I gave the two founders a delivery setup they could keep running on their own: reproducible, gated by CI, and watched by alerts.

role External Cloud/DevOps contributor team 2 founders year 2026 sanitized: pseudonym, no real code or secrets
the incident that started it

A Friday change added a new setting, STORAGE_PROVIDER=s3. It worked locally, but the variable was never set on the production server. The container started, /health returned 200, and everything looked fine. Invoice uploads failed anyway and customers got 500s. With nothing watching, the team found out 35 minutes later from a customer, and the rollback that followed was manual and improvised. Most of this project exists to make that one class of problem hard to repeat.

what i did
01

Reproducible local environment

One command brings up the API, PostgreSQL and Redis in Docker Compose, each with a healthcheck. A /health liveness probe, and a /ready probe that returns 503 and names the dependency that is down.

02

CI that gates every merge

GitLab CI runs the tests, builds the image, and scans for committed secrets (Gitleaks) and known vulnerabilities (Trivy). The same checks are mirrored to GitHub Actions so the public repo is gated too.

03

A deploy path in version control

A declarative Jenkinsfile deploys to staging, runs a smoke test, then stops at a manual approval gate before production. The deploy lives in the repo, not in one founder's memory.

04

Runbooks for the bad days

Written deploy and rollback runbooks, an incident template and a lightweight change-management flow. Rollback is one command back to a previous tagged image, so recovery does not depend on the new code building.

05

A first layer of observability

Prometheus scrapes a /metrics endpoint, Grafana draws the dashboard, and Alertmanager routes four alerts: service down, high 5xx rate, unexpected restart and high latency.

06

Decisions written down

Every choice is recorded as a short ADR that says what we did and why, so the setup is a deliberate design the team can question later, not something nobody dares touch.

the running system
FlowLedger runtime and observability architectureClients reach the FastAPI app, which uses PostgreSQL and Redis. Prometheus scrapes the app metrics every 15 seconds and feeds a Grafana dashboard and Alertmanager alerts routed to Slack.RUNTIMEOBSERVABILITYHTTPSQLcachescrapeClientFastAPI app/health · /ready · /metricsPostgreSQLRedisPrometheusevery 15sGrafanaAlertmanageralerts → Slack
key decisions
ADR 001

Compose on a VM, not Kubernetes

A two-founder team can maintain Docker Compose on a single VM. The goal was reproducibility, not scale, so Kubernetes was ruled out from the start.

ADR 002

Security checks on every merge request

A broken test, a leaked secret or a fixable HIGH or CRITICAL vulnerability blocks the merge. The common mistakes get caught without anyone remembering to look.

ADR 003

Keep Jenkins for deploys

Jenkins already had the credentials and network access to the servers. Moving deploys onto CI runners would spread deploy secrets wider for no real gain, so Jenkins keeps the ship job.

ADR 004

Add basic observability

During the outage both health and readiness were green. A rise in 5xx responses was the only signal that could see the failure, so that became an alert.

two gates

GitLab CI decides whether a change may merge. Jenkins decides whether a build may ship. Two systems, kept in step by the same pinned tools and the same config files.

merge gateGitLab CI, mirrored to GitHub Actions · runs on every merge request
test build image gitleaks trivy merge allowed
ship gateJenkins · staging first, then a human, then production
checkout test build trivy deploy staging smoke test manual approval production
the dashboard the team watches
Grafana dashboard showing API up, requests per second, 5xx error rate, p95 latency, request rate by status, and latency percentiles
The Grafana view built for the team: uptime, request rate, the 5xx error rate that would have caught the July incident, and latency percentiles. The red lines mark the same thresholds the alerts fire on.
outcome
minutes
to see a 5xx spike, down from 35
one command
rollback to a tagged image
4 alerts
down, 5xx, restart, latency
2 gates
merge in CI, ship in Jenkins

The July incident class is now visible in a couple of minutes through the 5xx rate, instead of after half an hour. Every release is tagged, so a rollback is one command to a known-good version. Delivery is boring, reversible and written down, which is exactly what a small team needed.

02 the stack

Six Azure labs, built one layer at a time

Alongside the client work, I taught myself Azure and Terraform by building. Each lab is deployed for real and adds one capability the last one did not have, from a single VM up to a GitOps-driven Kubernetes platform.

built through 2025 and 2026 · Terraform across all six · deployed and torn down on real Azure
L1
level 1 · foundation

Azure Terraform Linux VM

A first Terraform deployment: one ARM64 Linux VM on Azure with custom networking, NSG rules, SSH key access and automated Nginx provisioning through cloud-init.

+Adds the baseline: resource group, VNet, subnet, SSH access and a repeatable path from code to a running VM.

TerraformAzureLinuxcloud-initNSGNginxARM64
L2
level 2 · core infrastructure

Secure Two-Tier Infrastructure

A segmented environment with separate management and workload subnets (10.0.1.0/24 and 10.0.2.0/24), subnet-scoped NSGs and two ARM64 Ubuntu VMs. SSH to the web VM is restricted to the management subnet only.

+Adds subnet separation, least-privilege access paths and multi-VM provisioning that keeps the Terraform readable.

VNetSubnet designNSGMulti-VMARM64cloud-init
L3
level 3 · private architecture

Secure Private Platform

Private-first infrastructure with no public VM IPs. Azure Bastion for admin access, Key Vault as a secret store, Log Analytics with CPU alerting, and a modular five-module Terraform structure. Real troubleshooting is documented, including subnet association concurrency.

+Adds private-by-default compute, Bastion access, secret storage and monitoring as first-class platform components.

Azure BastionKey VaultLog AnalyticsPrivate VNetTF ModulesAzure Monitor
L4
level 4 · high availability

Load Balanced Web Platform

A public Azure Standard Load Balancer in front of two private ARM64 Ubuntu backends, with Bastion admin access, health probes, NSG rules and cloud-init. Distinct Nginx pages per backend confirm traffic is actually being distributed.

+Adds the first high-availability pattern: backend pools, health probes, traffic distribution and a multi-VM dependency chain.

Load BalancerBackend PoolHealth ProbesHigh AvailabilityARM64Log Analytics
L5
level 5 · containers · devsecops

DevSecOps Container Platform

A FastAPI service in Docker, deployed to Azure Container Apps through GitHub Actions. Terraform builds the Azure side, GitHub authenticates with OIDC (no stored secrets), images go to ACR, and Checkov and Trivy scan before every deploy. Telemetry flows through OpenTelemetry to App Insights, across three Terraform state layers.

+Adds a full CI/CD pipeline with no stored credentials, supply-chain scanning and observable container deploys.

DockerFastAPIACRContainer AppsGitHub ActionsOIDCManaged IdentityCheckovTrivyApp Insights
view repository HCL · Dockerfile · YAML
L6
★ technical peaklevel 6 · kubernetes · gitops

AKS GitOps Secure Platform

AKS provisioned with three-layer Terraform, application delivery driven by Flux GitOps and packaged as Helm charts. Pods reach Key Vault through Workload Identity and the Secrets Store CSI Driver, so no secrets sit in environment variables. GitHub Actions authenticates with OIDC, images are tagged by git SHA (no "latest" in production), NetworkPolicy enforces deny-by-default, and Checkov and Trivy gate every pull request.

+Adds Kubernetes orchestration, GitOps reconciliation, pod-level identity, immutable image tags and network policy.

AKSFlux v2HelmGitOpsWorkload IdentitySecrets Store CSINetworkPolicyOIDCCheckovTrivy
view repository HCL · Helm · YAML · Python
03 tools & skills

The stack I build with

Grouped by what it does, with the tools I have actually shipped with. In-progress tracks are under certifications.

Cloud & Azure

Azure Resource Groups VNet & Subnets NSG Bastion Load Balancer Key Vault ACR Container Apps

Infrastructure as Code

Terraform Ansible cloud-init Modules Remote state Multi-layer state

Containers & Orchestration

Docker Kubernetes Helm Flux AKS NetworkPolicy Workload Identity Secrets Store CSI

CI/CD

GitHub Actions GitLab CI Jenkins Git OIDC (secretless) SHA image tags staging → prod gates smoke tests

Security / DevSecOps

Trivy SonarQube Gitleaks Checkov Managed Identity Least privilege Non-root containers

Observability

Prometheus Grafana Alertmanager App Insights Log Analytics Health & readiness probes

Languages & Data

Python FastAPI Bash PostgreSQL Redis

OS & Networking

Linux Nginx SSH hardening Subnetting Routing basics

Ways of working

Git Conventional Commits ADRs Runbooks Change management Jira-style tickets Incident postmortems
04 certifications & learning

Studying the certs that match the work

The exams I am preparing for right now, each tied to something I am already building. AZ-104 for Azure administration, CCNA for the networking underneath it.

Certifications in progress

AZ-104
Microsoft Azure Administrator
Microsoft
preparing
CCNA
Cisco Certified Network Associate
Cisco
preparing

Currently learning

Azure administration

AZ-104

Identity, governance and monitoring labs beyond the fundamentals I already use in L3 to L5.

Networking

CCNA

Routing, switching and subnetting, so I understand what my NSGs and VNets are really doing.

Kubernetes, deeper

CKA goal

Building on the AKS and GitOps work in L6 toward running and operating clusters with confidence.

05 about

How I work

I am a Computer Engineering student at Politecnico di Milano. I learn by building and shipping, then writing down what broke and what I changed. A README is not the point. The point is that the next person can run it, understand it and roll it back.

I care about the operational details that keep a deploy reliable: identity and least privilege, a rollback that actually works, private access by default, and knowing within minutes when something is wrong. Those habits show up early in my projects, even the small ones.

I am early in my career and honest about it. What I can show is real work, deployed and documented: a client collaboration that made delivery safer, and six Azure labs that each added one concrete capability.

Cloud / DevOps contributor

FlowLedger · early-stage SaaS (external)
2026

Helped a two-founder SaaS move off a manual deploy after an outage. Built a reproducible environment, CI with security scanning, a Jenkins deploy behind a manual gate, runbooks, and a first layer of monitoring and alerts.

Docker ComposeGitLab CIJenkinsTrivyGitleaksPrometheusGrafana

Administrative & Accounting Support

Furizon APS · non-profit
since 2025

Records, invoices, member data, reconciliation and reporting for a non-profit in the events and community space, kept organised alongside my studies.

Accounting SupportData ReconciliationMember ManagementReporting
06 contact

Open to junior cloud and devops roles

Looking around Milan and Varese, remote or hybrid. Good fit for junior cloud engineer, junior devops, a cloud or devops internship, or cloud operations. If the work is real infrastructure, I want to hear about it.

Italian native · English C1 · French conversational · German and Russian in progress