Open to cloud engineering roles

I build things
on the cloud

Cloud engineer with production experience building financial transaction systems. I design and deploy infrastructure on AWS — from serverless pipelines to containerized applications on ECS Fargate.

$ aws s3 ls
www.enochenagbem.cloud
world-explorer-bucket
image-processor-input
$ aws ecs list-clusters
job-tracker-cluster ACTIVE
$ aws route53 list-hosted-zones
enochenagbem.cloud 2 records
$ _
EC2
S3
Lambda
RDS
CloudFront
SNS
IAM
VPC
CloudWatch
ECS
ECR
Route 53
Nginx
Let's Encrypt
Selected Projects

Seven projects, fourteen AWS services,
all defined in code.

01

World Explorer

Static Website Hosting

S3 CloudFront

An interactive travel website hosted on S3 and distributed globally via CloudFront. No servers — just HTML, CSS, and JS served from 400+ edge locations with sub-100ms load times.

Architecture
User Global
HTTPS
AWS Global Edge Network
CloudFront CDN 400+ edge locations
cache miss
AWS Region (us-east-2)
S3 Bucket Static origin
Why these technologies
S3 over EC2 for hosting

Static files don't need a running server. S3 costs fractions of a cent per GB, scales automatically, and has 99.999999999% durability. EC2 would mean paying for an idle server 24/7 just to serve HTML.

CloudFront over serving directly from S3

S3 alone serves from one region. CloudFront caches content at 400+ edge locations globally, cutting latency from ~200ms to under 50ms. It also provides HTTPS, which S3 website hosting alone doesn't support with custom domains.

Website endpoint vs REST endpoint

S3 has two URL formats. The website endpoint supports index.html routing and custom error pages. The REST endpoint doesn't. Using the wrong one as a CloudFront origin breaks page navigation entirely.

S3 website endpoints vs REST endpoints — critical for CloudFront origins
CloudFront cache invalidation and default root object configuration
Custom 404 error page routing through S3 + CloudFront
02

Image Processing Pipeline

Event-Driven Serverless

S3 Lambda SNS

Upload an image to S3 and walk away. Lambda automatically resizes it to three dimensions, saves processed versions to an output bucket, and emails you a notification via SNS. Zero servers, fully event-driven.

Architecture
Input
S3 Bucket uploads/ prefix
S3 event
Compute
Lambda 256MB / 30s timeout
Output
S3 (3 sizes)
SNS Email
IAM role scoped to: s3:GetObject (input), s3:PutObject (output), sns:Publish (notifications)
Why these technologies
Lambda over EC2 for processing

Image resizing is bursty — you might get 100 uploads in a minute, then nothing for hours. Lambda scales to zero when idle (no cost) and handles 1,000 concurrent executions without configuration. EC2 would sit idle 99% of the time, costing ~$8/month for nothing.

S3 events over polling

S3 event notifications trigger Lambda the instant a file lands. The alternative — a cron job polling S3 every minute — adds latency, wastes compute, and misses uploads between polls. Event-driven is the cloud-native pattern.

SNS over SES for notifications

SNS is a pub/sub service — one publish fans out to email, SMS, or other services. SES is for transactional email at scale. For simple notifications to myself, SNS is simpler to set up and doesn't require domain verification.

Event-driven design — S3 notifications invoke Lambda with zero polling
IAM least-privilege — Lambda role scoped to only required S3 + SNS actions
Debugged S3 URL-encoding issue (unquote_plus) using CloudWatch Logs
03

Job Application Tracker

Full-Stack on EC2 + RDS

EC2 RDS FastAPI

A production web app for tracking job applications — dashboard with donut charts, kanban board, table view, CSV export. Built with Python FastAPI, deployed on EC2 with a managed RDS PostgreSQL database and systemd for zero-downtime.

Architecture
Browser Port 8000
HTTP
Private VPC
Public Subnet
EC2 (t2.micro) FastAPI + Uvicorn
port 5432
Private Subnet
RDS PostgreSQL No public access
Security groups: EC2 allows port 8000 (public) + SSH (my IP). RDS allows port 5432 from EC2 SG only.
Why these technologies
EC2 over Lambda for the app server

This is a stateful web app with server-rendered templates, WebSocket-like interactions, and persistent database connections. Lambda has a 15-minute timeout and cold starts that would break the user experience. EC2 gives full control over the runtime.

RDS over self-managed PostgreSQL on EC2

Running PostgreSQL on EC2 means managing backups, patches, failover, and monitoring yourself. RDS handles all of that automatically. The tradeoff is cost (~$15/month vs ~$0 on EC2), but the operational burden of self-managing a database isn't worth it.

Private RDS with security group isolation

RDS has no public IP. Only the EC2 security group can reach port 5432. Even if someone gets the database credentials, they can't connect from outside the VPC. This is defense in depth — multiple security layers.

Security groups as firewalls — RDS only accepts traffic from the EC2 security group
systemd service for persistent deployment — survives reboots and auto-restarts
Full deployment pipeline: Git push, SSH, clone, configure environment, start service
04

Containerized CI/CD Pipeline

Docker + ECS Fargate + GitHub Actions

ECS ECR CI/CD

Took the Job Tracker from manual EC2 deployment to a fully automated container pipeline. Docker image builds on every push, gets stored in ECR, and deploys to ECS Fargate — zero SSH, zero downtime, zero servers to manage.

Architecture
git push Developer
webhook
CI/CD Pipeline
GitHub Actions Build + test + push
image
AWS
ECR
ECS Fargate
Each commit SHA is used as the image tag for full traceability. Rollback = redeploy a previous tag.
Why these technologies
ECS Fargate over EC2 for containers

EC2 means patching the OS, monitoring disk space, managing Docker daemon, and scaling manually. Fargate removes all of that — you define CPU/memory and AWS handles the rest. The tradeoff is less control over the host, but for a web app that's a good trade.

ECR over Docker Hub

ECR is private by default and in the same AWS network as ECS, so image pulls are fast and free. Docker Hub has rate limits on free accounts (100 pulls/6 hours) which can break CI/CD pipelines.

GitHub Actions over Jenkins or CodePipeline

GitHub Actions lives where the code lives — no separate CI server to manage. AWS CodePipeline would add another AWS service to maintain. Jenkins would need its own EC2 instance. GitHub Actions is free for public repos and has official AWS actions.

Docker multi-layer caching — dependencies installed before code for fast rebuilds
GitHub Actions CI/CD — auto deploys on every push to main, zero manual steps
Evolution from manual EC2 + systemd to serverless Fargate containers
05

Terraform Infrastructure

Infrastructure as Code

Terraform ECS ECR

Took everything I built by hand in the AWS Console and defined it as code. One command creates the entire infrastructure — ECR, ECS Fargate, IAM roles, security groups, CloudWatch logging. One command tears it all down. Version-controlled, reviewable, reproducible.

Architecture
.tf files 8 files, 7 resources
plan → apply
Terraform creates on AWS
ECS Cluster
ECS Service
Task Definition
ECR Repository
IAM Role + Policy
Security Group
CloudWatch Logs
State file tracks every resource. terraform destroy removes all 7 in the correct dependency order.
Why these technologies
Terraform over CloudFormation

CloudFormation is AWS-only. Terraform works with AWS, GCP, Azure, and 3,000+ providers. If I ever work with multi-cloud or non-AWS services, the same tool and language apply. The tradeoff is that CloudFormation has tighter AWS integration and catches some errors earlier.

IaC over console clicking

The console is fine for learning, but infrastructure built by hand is undocumented, unreproducible, and unauditable. With Terraform, the code IS the documentation. Changes go through pull requests. If a region goes down, terraform apply rebuilds everything elsewhere in minutes.

Separate repo over embedding in the app repo

Infrastructure and application code have different lifecycles. App code changes daily; infrastructure changes rarely. Separate repos mean separate CI/CD pipelines, separate permissions, and clearer ownership. The tradeoff is managing two repos instead of one.

Declarative IaC — define what you want, Terraform figures out how to build it
Plan before apply — always preview changes before they hit production
State management — Terraform tracks resources and detects drift
06

Cloud Monitoring & Alerts

Observability + Incident Alerting

CloudWatch SNS Terraform

Built a monitoring layer on top of my ECS infrastructure. CloudWatch dashboard tracks CPU, memory, and running tasks in real-time. Four alarms watch for spikes, crashes, and application errors — and email me via SNS before users notice anything is wrong.

Architecture
ECS Fargate
Container CPU + Memory + Logs
metrics
CloudWatch
Dashboard
4 Alarms
alarm fires
Notification
SNS Topic
Email Alert
Log metric filter scans application logs for "ERROR" → creates custom metric → alarm fires when error count spikes.
Why these technologies
CloudWatch over third-party monitoring (Datadog, New Relic)

CloudWatch is native to AWS — zero agents to install, metrics flow automatically from ECS. Third-party tools cost $15-30+/month per host and require agent configuration. For a single-service setup, CloudWatch gives you everything you need at near-zero cost.

SNS over polling the console manually

Without alerts, you'd have to check the console to know something's wrong. SNS pushes notifications to you the moment an alarm fires — email, SMS, or even triggering a Lambda for auto-remediation. You know about problems before your users do.

Log metric filters over custom application metrics

You could instrument your code to emit custom metrics, but that requires code changes. Metric filters scan existing logs with zero code changes — just define a pattern like "ERROR" and CloudWatch counts matches automatically. It's the fastest path from logs to actionable alerts.

CloudWatch metrics vs logs — metrics are numbers you alarm on, logs are text you search through
Alarm evaluation — why 2 consecutive periods prevents false positives from single spikes
Metric filters bridge logs into metrics — turning text patterns into countable, alarmable numbers
07

Portfolio Infrastructure

Custom Domain + HTTPS + Auto-Deploy

Route 53 Nginx SSL

This portfolio isn't hosted on Netlify or Vercel — I built the hosting infrastructure myself. Custom domain registered, DNS managed through Route 53, served by Nginx on a Linux VPS with free HTTPS from Let's Encrypt. Auto-deploys from GitHub every 5 minutes via cron.

Architecture
git push GitHub
cron pull
Linux VPS (Contabo)
Nginx
+
Let's Encrypt
HTTPS
AWS
Route 53 DNS enochenagbem.cloud
Certbot auto-renews SSL every 90 days. Cron pulls from GitHub every 5 minutes. Zero manual deployment.
Why these technologies
Self-hosted VPS over Netlify or Vercel

Netlify deploys in one click, but you learn nothing about infrastructure. Hosting on a VPS means configuring Nginx, managing SSL certificates, writing deploy scripts, and understanding how DNS routes traffic to a server. That's the actual job.

Let's Encrypt over paid SSL certificates

Let's Encrypt provides free, automated, and trusted SSL certificates. Paid certs ($50-200/year) offer the same encryption with no practical security difference. Certbot automates renewal every 90 days — set it and forget it.

Cron-based deploy over webhook CI/CD

A GitHub webhook would trigger instant deploys, but requires exposing an endpoint and handling authentication. A 5-minute cron job is simpler, secure (pull-based, not push-based), and good enough for a portfolio — updates are live within minutes of a push.

Nginx server blocks — virtual hosting, SSL termination, and static file serving
DNS management — A records, CNAME records, nameserver delegation from registrar to Route 53
Linux server administration — SSH, cron, systemd, file permissions, firewall
Enoch Enagbem
About

I learn by shipping.

M.S. in Computer Science from Virginia Commonwealth University (3.8 GPA), B.S. from Valley View University. Before pivoting to cloud, I spent a year at EFT Corporation building backend systems for live financial transactions — authentication, audit logging, and SQL optimization across thousands of daily operations.

That production background shapes how I approach cloud. I don't just deploy services — I think about security groups, IAM least-privilege, private subnets, and why architecture choices matter. Every project here is live. This portfolio itself runs on a Linux VPS with Nginx, Let's Encrypt SSL, and Route 53 DNS — auto-deployed from GitHub. Currently teaching Java and Python to 30+ students at Project STEM.

AWS Services

EC2S3RDSLambdaCloudFrontRoute 53SNSIAMVPCCloudWatchECS FargateECR

Languages & Tools

PythonJavaSQLFastAPISpring BootPostgreSQLDockerTerraformGitGitHub ActionsLinuxNginx

Concepts

Event-Driven ArchitectureServerlessCI/CDContainerizationInfrastructure as CodeLeast PrivilegeMicroservices
Contact

Let's build something.

I'm looking for entry-level Cloud Engineer and DevOps roles. If you think I'd be a good fit, reach out.