βοΈ Cloud Engineer | Enterprise IT Professional
Building cloud infrastructure, testing resilience, troubleshooting failures, and documenting the engineering behind it. βοΈπ οΈ
AWS β’ Terraform β’ Infrastructure as Code β’ High Availability β’ Amazon EKS β’ Kubernetes β’ Linux β’ Docker β’ CI/CD β’ Cloud Troubleshooting
π Explore My ProjectsIβm an enterprise IT professional with 18 years of experience supporting users and business-critical technology environments, including more than 21 years with Allstate. My background includes technical troubleshooting, incident resolution, customer support, documentation, access management, Microsoft 365, Active Directory, and enterprise IT operations.
Building on that foundation, Iβve expanded my hands-on experience into cloud engineering and DevOps through projects using AWS, Terraform, Infrastructure as Code, Linux, Docker, Kubernetes, Amazon EKS, Amazon ECR, CI/CD, automation, monitoring, autoscaling, databases, and highly available cloud architectures.
My approach is centered on understanding how systems connect and what happens when they fail. Rather than stopping when something deploys successfully, I test behavior, troubleshoot failures, validate recovery, and document what I learn. This allows me to apply the troubleshooting mindset developed throughout my IT career to increasingly complex cloud and DevOps environments.
My goal is to combine my enterprise IT experience with modern cloud engineering practices to build reliable, secure, scalable, and maintainable systems while continuing to deepen my expertise in cloud operations and automation.
This portfolio is built with HTML and CSS, maintained in GitHub, stored in Amazon S3, and delivered securely through Amazon CloudFront. Amazon Route 53 provides DNS routing for the custom domain, while AWS Certificate Manager provides the TLS certificate used for HTTPS.
AWS Certificate Manager secures both mandyreed.com and www.mandyreed.com with HTTPS. Source code and version history are maintained in GitHub.
Hands-on cloud and DevOps projects focused on architecture, automation, troubleshooting, resilience, and understanding how the pieces connect. GitHub shows the build. Medium tells the story. π
Built. Tested. Broken on purpose. Recovered. Monitored. Destroyed. π
Built a production-inspired, highly available AWS architecture entirely with Terraform across two Availability Zones. Designed separate public, private application, and private database tiers using an Application Load Balancer, Auto Scaling Group, private EC2 instances, NAT Gateways, Multi-AZ Amazon RDS MySQL, IAM, Systems Manager Session Manager, Secrets Manager, and CloudWatch. Connected to RDS from the private application tier and used SQL to create, query, and update sample data. Then deliberately terminated an EC2 instance to validate Auto Scaling recovery, ALB target health, persistent database data, and CloudWatch visibility throughout the failure and recovery cycle.
I built an Auto Scaling architecture with Terraform. Then one tiny space broke everything. π
Built a highly available AWS web architecture with Terraform using an Application Load Balancer, Auto Scaling Group, private EC2 instances across two Availability Zones, Launch Templates, secure administration through AWS Systems Manager Session Manager, and an encrypted S3 remote backend for Terraform state. Troubleshot repeated Target Group health check failures to a formatting error in EC2 User Data that prevented Apache from installing, then corrected the Launch Template and used Auto Scaling Instance Refresh to roll the fix across the fleet. Validated self-healing by deliberately terminating a healthy EC2 instance and watching the Auto Scaling Group restore desired capacity.
π» View GitHub βοΈ Read the StoryI put Kubernetes on AWS. Then I started deleting Pods. βΈοΈπ
Moved my Kubernetes learning from a local environment into AWS by deploying and operating a containerized application on Amazon EKS. Built a managed EKS cluster with private EC2 worker nodes across two Availability Zones, pushed versioned Docker images to Amazon ECR, exposed the application through a Kubernetes LoadBalancer Service, and tested scaling, self-healing, and rolling updates. Added resource requests and limits, Metrics Server, and Horizontal Pod Autoscaling, then generated CPU load to watch the application automatically scale. Enabled EKS API and audit logging in CloudWatch to add AWS-native operational visibility and followed the complete path between Kubernetes workloads and the AWS infrastructure underneath them.
π» View GitHub βοΈ Read the StoryI put WordPress and MySQL on Kubernetes. Then MySQL fought back. βοΈ
Built a multi-tier WordPress and MySQL application on Kubernetes, moving beyond individual Kubernetes resources to explore how application and database workloads communicate as part of a larger system. Worked with Deployments, Services, labels and selectors, persistent application data, and Kubernetes networking while troubleshooting communication between WordPress and MySQL. The project reinforced that a healthy Pod does not automatically mean a healthy application, and that troubleshooting Kubernetes means following the complete path between workloads, Services, configuration, storage, and the application itself.
π» View GitHub βοΈ Read the StoryKubernetes said desired state. I said prove it. βΈοΈ
Built my first hands-on Kubernetes application using MicroK8s on Ubuntu in WSL2, progressing from a standalone nginx Pod to a declaratively managed application with Deployments, ReplicaSets, multiple Pods, and a stable ClusterIP Service. Practiced scaling, labels and selectors, EndpointSlices, rolling updates, and desired-state reconciliation while intentionally deleting Pods to observe Kubernetes self-healing. Finished by moving the application into reusable YAML and troubleshooting an immutable Deployment selector while rebuilding the environment declaratively.
π» View GitHub βοΈ Read the StoryWordPress, MySQL, Docker Swarm, EFS... what could possibly go wrong? π
Built a multi-service WordPress and MySQL application on a three-node Docker Swarm running across AWS EC2. Used Docker Stack, overlay networking, Docker Secrets, and Amazon EFS shared storage to explore container orchestration, persistent data, service communication, and resiliency. Troubleshot networking, SSH, Docker service health, memory pressure, and storage issues while testing service recovery and worker-node rescheduling.
π» View GitHub βοΈ Read the StoryI built a Docker Swarm. Then I started killing containers. π³π
Built a three-node Docker Swarm across AWS EC2 instances to practice multi-node container orchestration, replicated and global services, scaling, self-healing, Docker Stack, overlay networking, and routing mesh. Tested resiliency by intentionally removing containers and draining a worker node to validate desired-state recovery, task rescheduling, and traffic routing across the cluster.
π» View GitHub βοΈ Read the StoryIt started with one manually deployed Jenkins server. Then I decided Terraform should do the work. π
Deployed a Jenkins server on AWS using Terraform, progressing from a manual proof of concept to reusable Infrastructure as Code. Provisioned EC2, Security Groups, and private S3 artifact storage, automated Jenkins installation with User Data, and implemented an IAM Role and Instance Profile with least-privilege S3 permissions. Validated temporary AWS credentials and tested artifact upload and download before safely destroying the Terraform-managed infrastructure.
π» View GitHub βοΈ Read the StoryWhat happens when you start deleting Jenkins containers on purpose? Turns out, quite a lot. π³π
Built and managed Jenkins in Docker while exploring container lifecycle, persistent storage, Docker Compose, and custom image creation. Tested data persistence by intentionally removing and recreating Jenkins containers, then built a custom Jenkins image using a Dockerfile and verified the customization with curl inside the running container.
π» View GitHub βοΈ Read the StorySame project. Different engineer. π³
Rebuilt one of my first Docker projects using a Dockerfile and a repeatable image build instead of manually configuring a running container. Practiced Docker image versioning, layer caching, container lifecycle management, host-to-container port mapping, networking, and inspection while running multiple versions of the application side by side. Troubleshot Docker Engine availability, port and container-name conflicts, application connectivity, and container behavior while validating each stage of the rebuild.
π» View GitHub βοΈ Read the StoryBuilding a portfolio was easy. Getting DNS, HTTPS, caching, and a custom domain to cooperate was the adventure. π
Designed and deployed this cloud engineering portfolio using Amazon S3, CloudFront, Route 53, and AWS Certificate Manager. Configured a custom domain with DNS routing and HTTPS/TLS, maintained source control through GitHub, and troubleshot deployment, caching, domain registration, DNS, and content delivery issues.
π» View GitHub βοΈ Read the StoryWhat if a GitHub push could hand work directly to generative AI? Naturally, I had to find out. π€
Built a CI/CD-style workflow using GitHub, Amazon S3, and Amazon Bedrock.
π» View GitHub βοΈ Read the StoryOne audio file went into AWS. Several services later, the cloud was speaking another language. π
Created an AWS pipeline using Amazon Transcribe, Translate, Polly, Lambda, and S3.
π» View GitHub βοΈ Read the StoryUpload an image and let AWS figure out what it is. That sounded like a perfectly reasonable experiment. π
Built an image-processing workflow using Amazon Rekognition, DynamoDB, Lambda, and S3.
π» View GitHub βοΈ Read the StoryBecause apparently reading text myself was too easy, I taught AWS to say it out loud. π
Created a serverless text-to-speech solution using Amazon Polly, Lambda, API Gateway, and S3.
π» View GitHub βοΈ Read the StoryThe goal was simple: push code and let the pipeline handle the deployment. Much nicer than clicking everything manually. π
Built and deployed a static website using Amazon S3, CloudFront, and CodePipeline.
π» View GitHub βοΈ Read the StoryTeaching the cloud when to sleep. π΄βοΈ
Built a serverless AWS automation project using AWS Lambda to stop EC2 instances programmatically, reinforcing event-driven cloud operations, IAM permissions, Python-based automation, and the value of automating repetitive infrastructure tasks.
π» View GitHub βοΈ Read the StoryNo README? No entry. Sometimes automation needs boundaries. π
Created a GitHub Actions workflow that validates required repository files and logs results to Amazon CloudWatch.
π» View GitHub βοΈ Read the StoryThe technical skills matter, but the strongest lessons come from understanding what the system is doing, why it failed, and how it recovered. π
A successful deployment does not automatically mean the application actually works. Terraform can successfully create infrastructure while the application running inside it is still unhealthy. I validate the infrastructure and the application path.
Terraform became easier to understand when I stopped viewing resources as isolated blocks and started following values between them. VPC IDs, subnet IDs, Security Groups, Target Groups, Launch Templates, IAM roles, and Auto Scaling Groups connect individual resources into a complete architecture.
Troubleshooting gets easier when I understand how every service connects. Whether the path crosses an ALB, Target Group, EC2 and Apache, or Docker, ECR, Kubernetes and AWS load balancing, following the request from beginning to end helps isolate the failing layer.
One leading space before a User Data shebang was enough to stop Apache from installing, fail ALB health checks, and cause Auto Scaling to repeatedly replace unhealthy instances. Small configuration mistakes can have architecture-wide effects.
Private instances do not automatically require inbound SSH. AWS Systems Manager Session Manager gave me secure diagnostic access without public IP addresses, port 22, or SSH key management. Least privilege matters more when I validate that it actually works.
Docker Swarm, Kubernetes, and EC2 Auto Scaling all reinforced the same idea at different layers: define the state you want, deliberately change reality, and observe how the platform responds. When I terminated a healthy EC2 instance, Auto Scaling restored the desired capacity without manual intervention.
EKS helped make the boundary much clearer. Kubernetes manages workloads, desired state, Services, rolling updates, and Pod autoscaling, while AWS provides the compute, networking, load balancing, container registry, managed control plane, and logging underneath it.
Kubernetes can scale application Pods while EC2 Auto Scaling changes infrastructure capacity. Understanding which layer is scaling, why it is scaling, and what signal drives the change makes the behavior much easier to reason about.
Containers may be disposable, but application data is not. Shared storage, database placement, and recovery behavior need to be considered as part of the architecture.
An EC2 instance can be running while the application inside it is unusable, just as a Kubernetes Pod can show Running while the complete application path is broken. Health needs to be evaluated at the layer that actually matters to the application.
Versioned ECR images made Kubernetes releases easier to follow, while Launch Template versions made infrastructure changes explicit. After correcting EC2 User Data, Instance Refresh rolled the new Launch Template configuration across the Auto Scaling Group.
Building cloud resources is fun. Knowing how to safely tear them down is part of understanding the full lifecycle, especially when environments include networking, NAT, load balancing, Auto Scaling, EC2, EKS, ECR, and CloudWatch resources.