Skip to content

Field to Cloud: Cloud Engineering for Telecoms Engineers

Hands-on, lab-based course for a telecoms field engineer with little to no Linux/cloud background. Linux → networking → AWS → Terraform → containers → CI/CD → observability → capstone.

Quick links: Progress tracker · Lab control (start/stop) · Architecture & operations

A hands-on, lab-driven course that takes a telecoms field engineer with little to no Linux experience to a working junior cloud/DevOps engineer level. Every module pairs short theory with labs run on a real AWS environment that you (the instructor) provision with Terraform — so the infrastructure is part of the syllabus.

Who this is for

  • Student: telecoms field engineer. Strong on physical layer, RF, transmission, cabling, PSTN/mobile networks. Little/no Linux, no cloud, no code.
  • Instructor: you, using your own AWS account. Your live projects (e.g. a CloudFront + S3 PWA with a Terraform-provisioned publish pipeline) are used as show-and-tell artefacts throughout — the student sees production infra, not toy diagrams.

The telecoms background is an asset, not a gap. The course deliberately maps every new concept to something the student already knows (OSI, circuits vs packets, NOC vs SRE, truck-roll vs redeploy).

Course map

# Module Outcome Approx time
0 Orientation & skills assessment Tailored learning path; lab access working 2 h
1 Linux systems administration LPIC-1-equivalent working knowledge 12–16 h
2 Networking, DNS, HTTPS & app architecture OSI→cloud mapping, TLS, DNS, 3-tier design 6–8 h
3 AWS core IAM, EC2, VPC, S3, CloudFront; reads your real infra 8–10 h
4 Terraform Writes and applies IaC; understands state 6–8 h
5 Containers & a taste of Kubernetes Builds/runs images with Podman; k8s concepts 6–8 h
6 CI/CD with GitHub Actions Pipeline + self-hosted runner in Podman 6–8 h
7 Monitoring, alerting & SRE Prometheus + Grafana dashboards, SLI/SLO, alerts 8–10 h
8 Capstone 3-tier app: Terraform + CI/CD + monitoring, end to end 8–12 h

Total ≈ 60–80 hours. Run it as ~10 weeks of two evening sessions + one weekend lab, or an intensive 3 weeks.

The lab environment (what you provision)

terraform/ in this repo builds the whole training environment in your AWS account:

  • A dedicated training VPC (public subnet, IGW, locked-down security groups — SSH/HTTP only from your admin IP).
  • lab-box (Ubuntu 24.04): the student's daily driver. Linux labs, Podman, GitHub Actions runner, capstone app.
  • monitor-box (Ubuntu 24.04): where the student deploys Prometheus + Grafana in module 7 (deliberately not pre-installed — installing it is the lab).
  • Optional course website: S3 + CloudFront hosting the course itself as an interactive MkDocs site (publish/) — which doubles as a live demo of the exact static-hosting pattern you already run in production.

  • A serverless progress tracker (Lambda + DynamoDB, token-protected) serving a tickable checklist of every lab/checkpoint at <course-site>/progress/ — the student's ticks sync across devices; you can watch completion at a glance.

Everything is tagged Project = cloud-course for easy cost tracking and teardown.

Quick start (instructor)

cd terraform
cp terraform.tfvars.example terraform.tfvars   # set your admin IP + key name
terraform init
terraform plan
terraform apply
terraform output                                # SSH commands for both boxes

Teardown between sessions to save money:

terraform destroy            # full teardown, ~5 min to rebuild
# or stop instances only:
aws ec2 stop-instances --instance-ids $(terraform output -raw lab_box_id) $(terraform output -raw monitor_box_id)

Cost guardrails

  • 2 × t3.medium on-demand in eu-west-2 ≈ $0.10/h combined while running; stop instances between sessions and the compute cost rounds to pennies.
  • Budget alert: create an AWS Budget at e.g. $20/month before starting — this is itself a 5-minute teaching moment in module 3.
  • The optional course website (S3+CloudFront) costs effectively nothing at this scale.

Publishing the course as an interactive website

cd publish
./publish.sh          # builds MkDocs site and syncs to the S3 bucket Terraform created

The student then browses the course at the CloudFront URL, with search, dark mode, progress-friendly navigation and copy-paste-able code blocks. In module 3 you reveal that the site they've been learning from is hosted on the exact architecture they're studying — the course eats its own dog food.

Extras in this repo

  • grafana/fieldapp-service-health.json — pre-built reference dashboard for module 7 (golden signals, SLO gauge, error-budget + burn-rate, blackbox, TLS expiry). Import into Grafana or hand it over after the student builds their own.
  • field-to-cloud-syllabus.pdf (+ scripts/make_syllabus.py to regenerate) — printable one-page syllabus with sign-off line.
  • progress/index.html — the progress tracker page; publish.sh injects the API URL and ships it to <course-site>/progress/. Reveal the student's access token once with terraform output -raw progress_token and send it to him privately.
  • scripts/create-github-repo.sh — one-shot: create the devops-course GitHub repo and push this content.

Teaching notes

  • Show/tell your production infra early and often. Module 3 includes a guided read-only tour of your own account: the CloudFront distribution, S3 origin, Route 53 zone, Terraform state for your PWA. Nothing lands like "this is live, real users hit this".
  • The student types everything. No copy-paste for module 1. Muscle memory first.
  • Break things on purpose. Each module has a "sabotage" section — you break the lab, they fix it. Field engineers are natural troubleshooters; use it.
  • Quizzes are inline with collapsible answers; use them as session warm-ups.

CI/CD & multi-engineer workflow

Two engineers share the AWS account, so state is remote and locked, and CI runs on all three OSes.

  • Commit convention (required): every commit must be [feature|bugfix|hotfix]/<branch-or-ticket>: <description> (branch names will become JIRA/ticket numbers). Enforced locally by .githooks/commit-msg and in CI by the Commit convention workflow — run ./scripts/install-hooks.sh once to activate the hooks.
  • Versioning (required on merges to main): every merge to main is auto-tagged (semver patch bump via scripts/version-bump.sh) and released on GitHub; commits on feature branches are not tagged. The terraform-apply.yml version job runs before apply, so every deployed resource carries appVersion=<tag>. Local merges are tagged by .githooks/post-merge.

  • Terraform remote state: S3 + DynamoDB locking (terraform/backend.tf). Bootstrap once: ./scripts/bootstrap-aws.sh (creates bucket, lock table, GitHub OIDC role, AND auto-registers the GitHub repo variables via gh — no manual secrets/variables, OIDC-only auth).

  • Auth: OIDC only. Workflows assume github-actions-cloud-course via vars.AWS_DEPLOY_ROLE_ARN; no static AWS keys anywhere.
  • Workflows (.github/workflows/):
  • terraform-plan.yml — plan on PRs and manual dispatch, on ubuntu / macOS / Windows runners.
  • terraform-apply.yml — apply on push to main or manual dispatch; pick the runner (ubuntu-latest / macos-latest / windows-latest / self-hosted); destroy=true input for teardown; bound to the production environment for reviewer approval.
  • publish-course-site.yml — build the MkDocs site and sync to S3+CloudFront.
  • Versioning: every merge to main is auto-tagged (semver patch bump via scripts/version-bump.sh) and released on GitHub; the apply workflow injects app_version=<tag> into terraform so every resource carries an appVersion=<release> tag — nothing on main is unversioned. PR plans use the latest tag so they match production.
  • Tags: the AWS provider stamps project, environment, deployedBy, deployedVia, vcs, appVersion, ManagedBy on everything via default_tags (see terraform/variables.tf). deployedBy is derived from the AWS caller identity (the IAM user or role whose credentials ran the apply) and appVersion from the git tag — so the tags are correct no matter which mechanism deploys: CI, local terraform, or podman.
  • Automatic tagging: terraform/modules/tags/ + provider default_tags stamp every resource with project, environment, deployedBy (from the AWS caller identity), deployedVia, vcs, appVersion (from the nearest git tag) — identical in CI, local CLI, and podman. Pure terraform, no wrapper scripts.
  • Cost control: a $10/month AWS budget (devops-course-wd3esa-monthly) is scoped to deployedBy=wd3esa + project=devops-course tags and alerts at 30/50/80/90% to both engineers' email.
  • Run from your machine (no self-hosted runner needed):
    gh workflow run terraform-apply.yml --field runner=ubuntu-latest
    gh workflow run terraform-apply.yml --field runner=self-hosted --field destroy=true
    
  • Self-hosted runner (optional): ci/runner/register-runner.sh registers a runner labeled cloud-course on macOS or WSL2/Windows (see docs/engineer-onboarding.md for full AWS + GitHub access setup for both engineers).
  • No secrets required: repo variables (TF_STATE_BUCKET, TF_LOCK_TABLE, AWS_DEPLOY_ROLE_ARN) are registered automatically by scripts/bootstrap-aws.sh. CI uses OIDC — no AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY secrets exist by design.

See docs/engineer-onboarding.md for step-by-step AWS + GitHub access on macOS and Windows (WSL2 Ubuntu + Podman).