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.pyto regenerate) — printable one-page syllabus with sign-off line.progress/index.html— the progress tracker page;publish.shinjects the API URL and ships it to<course-site>/progress/. Reveal the student's access token once withterraform output -raw progress_tokenand send it to him privately.scripts/create-github-repo.sh— one-shot: create thedevops-courseGitHub 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-msgand in CI by theCommit conventionworkflow — run./scripts/install-hooks.shonce 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. Theterraform-apply.ymlversion job runs before apply, so every deployed resource carriesappVersion=<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 viagh— no manual secrets/variables, OIDC-only auth). - Auth: OIDC only. Workflows assume
github-actions-cloud-courseviavars.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=trueinput for teardown; bound to theproductionenvironment 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 injectsapp_version=<tag>into terraform so every resource carries anappVersion=<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,ManagedByon everything viadefault_tags(seeterraform/variables.tf).deployedByis derived from the AWS caller identity (the IAM user or role whose credentials ran the apply) andappVersionfrom the git tag — so the tags are correct no matter which mechanism deploys: CI, local terraform, or podman. - Automatic tagging:
terraform/modules/tags/+ providerdefault_tagsstamp every resource withproject,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 todeployedBy=wd3esa+project=devops-coursetags 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.shregisters a runner labeledcloud-courseon macOS or WSL2/Windows (seedocs/engineer-onboarding.mdfor 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 byscripts/bootstrap-aws.sh. CI uses OIDC — noAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYsecrets exist by design.
See docs/engineer-onboarding.md for step-by-step AWS + GitHub access on
macOS and Windows (WSL2 Ubuntu + Podman).