The job all 3 written
Cloud Engineer, DevOps Engineer, SRE, Platform Engineer, Solutions Architect: what each title really means, and how to read an advert.
1 Five job titles, and what each one is really asked to do
Five job titles keep appearing on the same adverts, they overlap
on paper, and companies use them differently from each other. The honest starting point is
that no single person does all five jobs, and most adverts are written by
someone who is not sure which one they are hiring for either.
The five roles, and what each one is really asked to do
Cloud Engineer
Builds and runs the infrastructure a company's software runs on.
- Provisions compute, storage, networking: EC2, S3, VPCs, load balancers
- Infrastructure as Code: Terraform, CloudFormation, Pulumi
- Cost, capacity and picking the right managed service over the DIY one
- Usually tied to one cloud vendor's specific services
The closest thing to "traditional sysadmin, but for
the cloud." Deep on one vendor's console and CLI, less on the pipeline that
deploys onto it.
DevOps Engineer
Builds the pipeline that gets a developer's code into production.
- CI/CD: build, test, deploy, automatically, on every change
- Containers and orchestration: Docker, Kubernetes
- The cultural half of the job: fewer handoffs between "dev" and "ops"
- Some cloud and IaC work, but the pipeline is the actual centre
Automation and process, more than infrastructure
design. The title is also the most overloaded of the five: some companies
mean "Cloud Engineer" when they say it, others mean it literally.
Site Reliability Engineer (SRE)
Applies software engineering to keep production up and fast.
- SLOs, SLAs and error budgets: reliability as a number, not a feeling
- On-call, incident response, blameless postmortems
- Writes real code: tooling, automation, sometimes the product itself
- Google-originated discipline with a specific, published methodology
The most rigorously defined title of the five,
and also the most casually misused. An advert that says "SRE" but describes plain
server admin with no mention of error budgets is not really hiring for the role.
Platform Engineer
Builds the internal product that other engineers use to ship.
- Self-service infrastructure: a developer clicks a button, not files a ticket
- Golden paths: a paved, supported way to deploy a new service
- Treats other engineers as the customer of the platform team
- Heavy Kubernetes, IaC and internal tooling
DevOps thinking, aimed inward, at a company's
own engineers rather than at any one pipeline. The newest of the five titles, and the
fastest growing.
Solutions Architect
Designs the system, often before a customer or team writes any of it.
- Maps a business requirement onto specific cloud services
- Diagrams, cost estimates, and trade-off decisions, in advance
- Frequently customer-facing, at a cloud vendor or a consultancy
- Broad knowledge of an entire cloud platform's service catalogue
Breadth over depth, and design over hands-on-keyboard.
The role that talks to the business most directly of the five.
The one distinction that explains most of the confusion
Put the five on a line from "builds infrastructure" to "builds process" to "designs
systems," and most of the ambiguity in job adverts is really just two roles' worth of
responsibilities badly split across one title. A Cloud Engineer and a
DevOps Engineer at a small company are frequently the same person with
whichever title the company's pay bands happened to have. An SRE and a
Platform Engineer at a large company can be different teams doing
genuinely different work. A Solutions Architect is the one role here that
is reliably distinct, because it is defined by who it talks to, not which tool it uses.
Where this course spends its time. The five roles share a floor:
shell, Git, containers, cloud fundamentals, IAM, networking, IaC, CI/CD, Kubernetes,
observability. That floor is most of this course, and it is genuinely shared -- a
Platform Engineer and an SRE both need to read a Terraform plan and know why a security
group with 0.0.0.0/0 on port 22 is a problem. The parts of each role that
diverge (SRE's error-budget maths, Solutions Architect's cost-and-design work) are
covered explicitly in their own lessons rather than assumed.
Reading an advert by its vocabulary, not its title
The fix is the same one the AI Engineer course uses: count the signals in the
responsibilities, not the job title at the top.
Reading an advert by its vocabulary, not its title
ran at build time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54# Which role does this advert actually describe? Count the signals, don't read the title.
declare -a SIGNALS_CLOUD=(vpc ec2 terraform iac "cost optimization" "well-architected" networking)
declare -a SIGNALS_DEVOPS=("ci/cd" jenkins "github actions" pipeline docker kubernetes automation)
declare -a SIGNALS_SRE=(slo sla "error budget" "on-call" incident postmortem toil)
declare -a SIGNALS_PLATFORM=("self-service" "golden path" "internal platform" "developer experience" backstage)
declare -a SIGNALS_ARCHITECT=(diagram "well-architected framework" stakeholder "cost estimate" migration "target architecture")
# Lowercase, and turn every run of punctuation into a single space, so "SLAs,"
# still matches "sla". Only the START of each word is anchored (a leading space),
# not the end, so "stakeholder" still matches inside the real plural
# "stakeholders" -- but "sla" cannot match starting midway through "translate",
# because that position in the haystack is never a word start.
normalize() {
printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -c '[:alnum:]/ ' ' ' | tr -s ' '
}
score() {
local haystack=" $(normalize "$1")"
shift
local n=0
local needle
for word in "$@"; do
needle=" $(normalize "$word")"
case "$haystack" in
*"$needle"*) n=$((n + 1)) ;;
esac
done
echo "$n"
}
# An advert titled one thing, describing another -- deliberately, the same trick
# the AI Engineer course's first lesson pulls with a "Machine Learning Engineer" ad.
# It also contains "translate," a genuine trap for a careless substring match on "sla".
advert="Senior DevOps Engineer. You will define our target architecture across three
regions, produce cost estimates for migration, and work directly with stakeholders
to translate business requirements into a well-architected framework review."
cloud=$(score "$advert" "${SIGNALS_CLOUD[@]}")
devops=$(score "$advert" "${SIGNALS_DEVOPS[@]}")
sre=$(score "$advert" "${SIGNALS_SRE[@]}")
platform=$(score "$advert" "${SIGNALS_PLATFORM[@]}")
architect=$(score "$advert" "${SIGNALS_ARCHITECT[@]}")
echo "advert title says: DevOps Engineer"
printf '%-12s %s\n' "cloud:" "$cloud"
printf '%-12s %s\n' "devops:" "$devops"
printf '%-12s %s\n' "sre:" "$sre"
printf '%-12s %s\n' "platform:" "$platform"
printf '%-12s %s\n' "architect:" "$architect"
check "the title is misleading; the words say Solutions Architect" "$architect" "5"
check "and it scores above the title's own role" "$([ "$architect" -gt "$devops" ] && echo yes)" "yes"
check "the DevOps signal count is zero" "$devops" "0"
check "no false match of 'sla' inside 'translate'" "$sre" "0"
What it printed, when the build ran it
advert title says: DevOps Engineer
cloud: 1
devops: 0
sre: 0
platform: 0
architect: 5
ok the title is misleading; the words say Solutions Architect
ok and it scores above the title's own role
ok the DevOps signal count is zero
ok no false match of 'sla' inside 'translate'
On "years of experience" and long requirements lists. The same
warning applies here as in every tech hiring market: a list of fifteen tools is a wish
list written by committee, not quota. If you match the responsibilities and roughly
half the tools, you are a real candidate for the role, whatever title is printed at the
top of the posting.
What this course covers, and what it does not
- Covered properly, and run for real: the shell, Git, containers,
cloud fundamentals, AWS (compute, storage, serverless) against a free local stand-in,
Terraform, CI/CD pipeline design, Kubernetes manifests, an observability stack, and
security fundamentals -- the floor all five roles share.
- Covered as concepts, with the real command shown: anywhere a step
would need a paid account, a live cluster, or hardware this machine does not have (a
second physical region, a GPU node, a company's actual production traffic), the panel
says so on itself and is marked as shown, not run.
- Not covered: a specific vendor's certification exam content,
multi-cloud in depth (this course is AWS-first, since it is the market leader and the
one with a viable free local emulator), and on-premises data centre hardware.
2 How to read a cloud/DevOps job advert
A cloud/DevOps advert is often a merged list from three different
people: what the team uses today, what they used two years ago and have not fully retired,
and what the hiring manager read about last week. Counting every listed tool as a hard
requirement will talk you out of applying to jobs you can actually do.
An advert, scored two ways
Scoring yourself two ways
ran at build time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61# A real-shaped advert: four responsibilities, five "required" tools, three "nice to have".
# One candidate. Score the same advert two different ways and compare.
RESP="deploy applications through a CI/CD pipeline;write Terraform to provision AWS infrastructure;monitor production systems and respond to incidents;automate repetitive operational tasks"
REQUIRED="aws;terraform;docker;linux;git"
NICE="kubernetes;golang;datadog"
CAN_DO="deploy applications through a CI/CD pipeline;write Terraform to provision AWS infrastructure;monitor production systems and respond to incidents;automate repetitive operational tasks"
KNOWS="terraform;docker;linux;git"
count_matches() {
# args: candidate-list;items;target-list;items -- semicolon separated, count overlap
local list1="$1" list2="$2"
local n=0
local IFS=';'
local old_ifs="$IFS"
read -ra items1 <<< "$list1"
for item in "${items1[@]}"; do
case ";$list2;" in
*";$item;"*) n=$((n + 1)) ;;
esac
done
IFS="$old_ifs"
echo "$n"
}
count_total() {
local IFS=';'
read -ra items <<< "$1"
echo "${#items[@]}"
}
resp_have=$(count_matches "$RESP" "$CAN_DO")
resp_total=$(count_total "$RESP")
req_have=$(count_matches "$REQUIRED" "$KNOWS")
req_total=$(count_total "$REQUIRED")
nice_have=$(count_matches "$NICE" "$KNOWS")
nice_total=$(count_total "$NICE")
# Naive score: every listed item (required + nice-to-have) counted equally.
naive_have=$((req_have + nice_have))
naive_total=$((req_total + nice_total))
naive_pct=$((naive_have * 100 / naive_total))
# Honest score: 70% the responsibilities you can actually do, 30% the required
# tools, nice-to-haves excluded entirely. Integer maths throughout (this is bash),
# rounded down, which only ever makes the honest score look more conservative.
resp_pct=$((resp_have * 100 / resp_total))
req_pct=$((req_have * 100 / req_total))
honest_pct=$(((resp_pct * 70 + req_pct * 30) / 100))
echo "naive score: ${naive_pct}% <- counts nice-to-haves as requirements"
echo "honest score: ${honest_pct}% <- weights the actual work over the tool list"
echo
echo "missing required tools: kubernetes is NOT required, so nothing missing there"
echo "matched every responsibility: yes"
check "the naive score looks discouraging" "$([ "$naive_pct" -lt 70 ] && echo yes)" "yes"
check "the honest score says apply" "$([ "$honest_pct" -ge 85 ] && echo yes)" "yes"
check "all four responsibilities are met" "$resp_have" "$resp_total"
check "one required tool (aws) is the only real gap" "$((req_total - req_have))" "1"
What it printed, when the build ran it
naive score: 50% <- counts nice-to-haves as requirements
honest score: 94% <- weights the actual work over the tool list
missing required tools: kubernetes is NOT required, so nothing missing there
matched every responsibility: yes
ok the naive score looks discouraging
ok the honest score says apply
ok all four responsibilities are met
ok one required tool (aws) is the only real gap
Notice what moved the score: not learning a new tool, but changing which numbers get
weighted. The candidate above has never touched AWS specifically and still scores 90%+
honestly, because every responsibility is already a yes, and AWS
knowledge transfers fast from any other cloud. A hiring manager filtering resumes by
keyword would reject this candidate; one reading for responsibility match would not.
The tells that a listed tool is not really a hard requirement
- It appears once, in a bullet list, with no elaboration elsewhere in the
posting. A tool the team actually lives in gets mentioned in the "about the
role" prose too, not only the bullet list.
- It is a specific vendor product for a generic need. "Experience
with Datadog" usually means "experience with an observability platform" -- Grafana,
New Relic and CloudWatch experience all count, in practice.
- The years-of-experience number is oddly specific ("6+ years
Kubernetes" when Kubernetes itself is younger than that at some companies) -- a sign the
number was copied from a template, not chosen deliberately.
What is not negotiable
Weighting responsibilities over tools is not the same as ignoring the posting.
Three things in a cloud/DevOps advert are worth taking literally every time:
- On-call expectations. If the posting mentions a rotation, ask about
its frequency and page volume before accepting, not after.
- "Which cloud." AWS, Azure and GCP overlap conceptually but not in
their consoles, CLIs or specific service names. Transferable in weeks, but real enough
to mention honestly if you have never used the specific one named.
- Compliance-driven environments (healthcare, finance, government).
These usually mean real constraints -- specific certifications, audit trails, change
approval processes -- that are worth understanding before, not after, you start.
3 What counts as proof you can do the job
Nobody hires you because you deployed something once. They hire
you because you showed evidence you can be trusted when it breaks -- and in this job,
almost everything eventually breaks. Evidence has a specific shape, and a screenshot of a
working app does not have it.
Why "I deployed an app to AWS" does not persuade anyone
The standard cloud/DevOps portfolio project is a small app, deployed to a cloud
provider once, usually by clicking through a console. It fails to persuade for a specific
reason: it proves you can follow a tutorial, not that you can operate a system
under pressure. Nobody asks how it was deployed a second time, what happens when
a dependency changes, or how you would find out it was down at 3am.
What an interviewer for this job is actually trying to find out:
- Can you reproduce it? If the answer involves remembering which
buttons you clicked, it is not infrastructure, it is a memory of infrastructure.
- Do you know the blast radius? What breaks, and for whom, if this
one thing goes down or is misconfigured.
- Do you know how you would find out something is wrong? Before a
customer tells you.
- Can you undo it? A rollback plan that exists before the incident,
not one invented during it.
A small project with Terraform (not console clicks), a documented rollback step, one
alert that actually fires on a real condition, and a paragraph on what you would do if
it paged you at 3am beats five console-deployed apps that each work once. Almost nobody
writes the rollback plan or the 3am paragraph, which is exactly why doing so stands out.
Scoring a project against what actually counts
The same "score it two ways" trick as the previous lesson, aimed at portfolio projects
instead of job adverts. A rubric with no framework needed: a checklist, and a way of
counting.
Scoring a portfolio project against what actually counts
ran at build time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# A rubric for "is this project actually evidence," not a framework -- a checklist.
CRITERIA="provisioned_with_code;has_a_rollback_step;has_one_real_alert;documents_a_failure;cost_is_known"
# Project A: the common portfolio project. Clicked through the AWS console,
# took a screenshot, wrote "deployed to AWS!" in the README.
PROJECT_A=""
# Project B: smaller in scope, but every box below is genuinely true of it.
PROJECT_B="provisioned_with_code;has_a_rollback_step;documents_a_failure"
score() {
local have="$1"
local total=0 got=0
local IFS=';'
read -ra all <<< "$CRITERIA"
for c in "${all[@]}"; do
total=$((total + 1))
case ";$have;" in
*";$c;"*) got=$((got + 1)) ;;
esac
done
echo "$got/$total"
}
score_a=$(score "$PROJECT_A")
score_b=$(score "$PROJECT_B")
echo "Project A (console-clicked, screenshot in README): $score_a"
echo "Project B (Terraform, rollback step, one honest failure writeup): $score_b"
echo
echo "Project A is not smaller in effort. It is missing the parts that were never about effort."
check "project A scores zero on the rubric that actually matters" "$score_a" "0/5"
check "project B clears more than half the rubric with less total work" "$score_b" "3/5"
What it printed, when the build ran it
Project A (console-clicked, screenshot in README): 0/5
Project B (Terraform, rollback step, one honest failure writeup): 3/5
Project A is not smaller in effort. It is missing the parts that were never about effort.
ok project A scores zero on the rubric that actually matters
ok project B clears more than half the rubric with less total work
The failure writeup is the highest-leverage part
Of everything on the rubric, "documents a failure" does the most work in an interview,
for the same reason an evaluation set does in the AI Engineer course: almost nobody writes
it down, so having one is unusually credible. It does not need to be dramatic. "I set the
security group too wide, a scan found it within an hour, here is the diff that fixed it
and the rule I added so it cannot happen again" is a better answer to "tell me about a
time something went wrong" than a war story with no receipts.
What a real project's pipeline would include
A project that deploys itself on every push is a stronger version of the same evidence.
The shape below is what that looks like as a real GitHub Actions workflow. It is
printed here and not executed, because running it for real needs a GitHub
repository, a runner and real cloud credentials -- none of which exist inside this
course's build. Part 10 covers pipelines properly, with real syntax checked the way every
other panel in this course is checked.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# What a real deploy pipeline looks like. NOT RUN HERE:
# a GitHub-hosted runner and real cloud credentials do not exist inside this build.
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Terraform apply
run: |
terraform init
terraform apply -auto-approve
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
This needs a real GitHub-hosted runner and real AWS credentials via secrets, neither of which this build has. Part 10 covers pipeline files in depth, with syntax and structure checked for real.
On certifications. An AWS or Kubernetes certification proves you sat
an exam, not that you can operate the thing under real conditions. It is not worthless --
it is a reasonable signal that you know the vocabulary and the service catalogue -- but
it is not a substitute for the rubric above, and interviewers who have done this job
know the difference.