
Samuel OjoAfter years of managing enterprise cloud systems behind closed corporate doors, I’m taking everything...
After years of managing enterprise cloud systems behind closed corporate doors, I’m taking everything I know about infrastructure engineering and open-sourcing it. I am launching a new initiative: one live Cloud & DevOps project every week, completely documented in public. No theoretical fluff, just real-world deployments, networking configurations, and security blueprints built for engineers looking to master the cloud.
This is week 1: Linux, Git, GitHub and a first script. It was not smooth, and I think that's the useful part, so I've left the mistakes in.
The setup
azure-cloud-native-platform
What I did
1. Basic Linux in a lab folder
I made a ~/lab folder with a logs/app.log file and practised navigating, listing files, and searching with grep. For example, counting error lines in a log:
bash
printf "INFO start\nERROR disk full\nINFO retry\nERROR timeout\n" > ~/lab/logs/app.log
grep -c ERROR ~/lab/logs/app.log
2. An SSH key so GitHub trusts my machine
bash
ssh-keygen -t ed25519 -C "my-email@example.com"
cat ~/.ssh/id_ed25519.pub
I added the public key (the .pub file) in GitHub under Settings, SSH and GPG keys. Then I tested it:
bash
ssh -T git@github.com
My first attempt printed Permission denied (publickey). That wasn't a broken setup. It meant GitHub didn't know my key yet. Once I added it, I got the message I wanted: "successfully authenticated, but GitHub does not provide shell access". That message looks like an error but is the success message.
3. A script with input validation
My first script counts error lines in a log file:
`
bash
set -euo pipefail
file="${1:?Please provide a log file}"
if [[ ! -f "$file" ]]; then
echo "Error: file not found: $file" >&2
exit 1
fi
echo "ERROR lines in $file: $(grep -c ERROR "$file" || true)"
`
Three things in it that I'd like to remember:
set -euo pipefail makes the script stop on errors, undefined variables and failed pipe commands, instead of carrying on silently.${1:?message} fails with a clear message if you forget the argument.exit 1 returns a non-zero exit code. I checked it with echo $?. That number is how CI/CD pipelines know a step failed, so I expect to use this a lot later.4. Branches and pull requests
I committed the script, then practised the real team workflow: create a branch, commit, push, open a pull request on GitHub, merge, then git switch main and git pull. My history now shows a merged pull request.
What went wrong (a lot)
I recreated this error for the screenshot. The typo was real, and this is how Git reported it.
I'd never have learned how to read these error messages by only watching a tutorial.
What I learned
A "Permission denied" or "No such file" error usually has a small, boring cause.
Small, clearly named commits make history readable.
Check your work with cat, git status and git log before moving on.
Git Bash is fine for Git, but real Linux skills (permissions, services, packages) need a real Linux system.
What's next
Week 2: Bash scripting (variables, if, loops, a backup script), a networking refresh (subnets, DNS, ports), and using ShellCheck to lint my scripts.
Repo: link