<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: muhirwaJD</title>
    <description>The latest articles on DEV Community by muhirwaJD (@muhirwajd).</description>
    <link>https://dev.to/muhirwajd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3219545%2F16e2fafe-7424-4ca5-a976-0e93db16ff7f.JPG</url>
      <title>DEV Community: muhirwaJD</title>
      <link>https://dev.to/muhirwajd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muhirwajd"/>
    <language>en</language>
    <item>
      <title>Snapshots</title>
      <dc:creator>muhirwaJD</dc:creator>
      <pubDate>Wed, 02 Jul 2025 09:59:24 +0000</pubDate>
      <link>https://dev.to/muhirwajd/snapshots-3boc</link>
      <guid>https://dev.to/muhirwajd/snapshots-3boc</guid>
      <description>&lt;h2&gt;
  
  
  🔁 RDS Snapshot Replication Across AWS Regions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🧠 Inspiration
&lt;/h3&gt;

&lt;p&gt;In real-world applications, ensuring disaster recovery and high availability across regions is a top priority. I wanted to explore how &lt;strong&gt;Amazon RDS Snapshots&lt;/strong&gt; can be used to &lt;strong&gt;replicate database state across AWS regions&lt;/strong&gt;, and how to do it &lt;strong&gt;completely using CLI and infrastructure best practices&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠 What I Built
&lt;/h3&gt;

&lt;p&gt;I built a working solution that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a manual &lt;strong&gt;snapshot&lt;/strong&gt; of a running RDS MySQL instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copies&lt;/strong&gt; that snapshot securely to another AWS region using CLI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restores&lt;/strong&gt; the snapshot as a brand-new RDS instance in the target region&lt;/li&gt;
&lt;li&gt;Configures &lt;strong&gt;EC2 to securely connect&lt;/strong&gt; to the restored DB instance for verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project mimics &lt;strong&gt;real-world cross-region disaster recovery&lt;/strong&gt;, entirely using &lt;strong&gt;AWS CLI and IAM best practices&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;✅ &lt;strong&gt;RDS Snapshot&lt;/strong&gt;: I initiated a manual snapshot of my running MySQL database in &lt;code&gt;eu-west-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🔐 &lt;strong&gt;Cross-Region Copy&lt;/strong&gt;: I securely copied the snapshot to &lt;code&gt;us-east-1&lt;/code&gt;, providing the right &lt;strong&gt;KMS key&lt;/strong&gt; and permissions.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Restoration&lt;/strong&gt;: The snapshot was restored as a new database in the destination region.&lt;/li&gt;
&lt;li&gt;🔓 &lt;strong&gt;Security Group Linking&lt;/strong&gt;: I configured the database's SG to only allow &lt;strong&gt;port 3306 from my EC2&lt;/strong&gt; instance — a critical security and connectivity setup.&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;Testing&lt;/strong&gt;: I used EC2 to connect to the new database using MySQL CLI and verified everything worked.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🔍 Challenges I Faced
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;❌ &lt;strong&gt;Cross-region encryption&lt;/strong&gt;: Required specifying a new &lt;strong&gt;KMS key&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;⛔ &lt;strong&gt;IAM Denial&lt;/strong&gt;: A Service Control Policy (SCP) was &lt;strong&gt;explicitly denying&lt;/strong&gt; the snapshot copy action.&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Connectivity issues&lt;/strong&gt;: Even with "All traffic" allowed, the DB was unreachable until I &lt;strong&gt;restricted access only to port 3306&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;🔐 &lt;strong&gt;Understanding SSH &amp;amp; IAM policies&lt;/strong&gt;: Took time to troubleshoot security-related errors cleanly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ What I Learned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How RDS snapshots and cross-region copy logic works in detail&lt;/li&gt;
&lt;li&gt;How to set up secure security groups for EC2-to-RDS communication&lt;/li&gt;
&lt;li&gt;How to debug common AWS CLI and IAM permission errors&lt;/li&gt;
&lt;li&gt;Importance of &lt;strong&gt;precise permissions over broad “Allow all” settings&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  💻 Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amazon RDS (MySQL)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS CLI&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EC2 (Ubuntu)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IAM, KMS, VPC, SG&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux terminal &amp;amp; MySQL client&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📈 What's Next?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🧠 Automate the snapshot + copy process using &lt;strong&gt;AWS Lambda&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧪 Add a backup validation pipeline for real-world DR simulation&lt;/li&gt;
&lt;li&gt;📦 Set up &lt;strong&gt;CloudWatch Alarms&lt;/strong&gt; to monitor cross-region syncs&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://github.com/muhirwaJD/snapshot-replication.git" rel="noopener noreferrer"&gt;GitHub - muhirwaJD/snapshot-replication&lt;/a&gt;&lt;/p&gt;

</description>
      <category>awschallenge</category>
      <category>database</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Terraform, Ansible and Jenkins</title>
      <dc:creator>muhirwaJD</dc:creator>
      <pubDate>Wed, 02 Jul 2025 09:54:52 +0000</pubDate>
      <link>https://dev.to/muhirwajd/terraform-ansible-and-jenkins-jm0</link>
      <guid>https://dev.to/muhirwajd/terraform-ansible-and-jenkins-jm0</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;AutoJenkins: CI/CD Deployment with Terraform &amp;amp; Ansible on AWS&lt;/strong&gt;
&lt;/h2&gt;




&lt;h2&gt;
  
  
  🌍 Website / Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://your_ec_public_ip:8080/" rel="noopener noreferrer"&gt;http://YOUR_EC2_PUBLIC_IP:8080&lt;/a&gt; &lt;em&gt;(replace with real IP)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Short Description
&lt;/h2&gt;

&lt;p&gt;We automated the full deployment of Jenkins on AWS using Infrastructure as Code (IaC) with &lt;strong&gt;Terraform&lt;/strong&gt; and &lt;strong&gt;Ansible&lt;/strong&gt;. In just one command, an EC2 instance is created, secured, configured with SSH, and provisioned with a fully working Jenkins CI server — without ever logging into the instance.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Inspiration
&lt;/h2&gt;

&lt;p&gt;Manually launching cloud infrastructure and setting up CI/CD tools is time-consuming and error-prone. We wanted a &lt;strong&gt;fully automated, repeatable solution&lt;/strong&gt; that reflects real-world DevOps practices, using industry-standard tools like Terraform and Ansible.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 What It Does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Terraform&lt;/strong&gt; provisions:

&lt;ul&gt;
&lt;li&gt;A new AWS EC2 Ubuntu instance&lt;/li&gt;
&lt;li&gt;A security group with SSH &amp;amp; Jenkins ports open&lt;/li&gt;
&lt;li&gt;An SSH key for secure access&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Ansible&lt;/strong&gt; configures the instance by:

&lt;ul&gt;
&lt;li&gt;Installing OpenJDK 17&lt;/li&gt;
&lt;li&gt;Adding the Jenkins APT repo &amp;amp; GPG key&lt;/li&gt;
&lt;li&gt;Installing Jenkins&lt;/li&gt;
&lt;li&gt;Ensuring the Jenkins service is enabled and running&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 How We Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Used &lt;strong&gt;Terraform&lt;/strong&gt; to define infrastructure as code in &lt;code&gt;main.tf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Used &lt;strong&gt;Ansible&lt;/strong&gt; to define the configuration in &lt;code&gt;playbook.yaml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Automatically passed the EC2 public IP from Terraform to Ansible&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ran everything from a single terminal with:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; inventory playbook.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Debugged service failures by parsing logs with Ansible (not SSH)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Challenges We Ran Into
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Jenkins failed to start with Java 11. We read logs via &lt;code&gt;journalctl&lt;/code&gt; using Ansible and discovered Jenkins now requires &lt;strong&gt;Java 17+&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;EC2 SSH keys had to be managed properly to avoid permission errors&lt;/li&gt;
&lt;li&gt;Jenkins port (8080) had to be opened in the security group&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Accomplishments We're Proud Of
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zero SSH login required throughout the project&lt;/li&gt;
&lt;li&gt;Clean separation of infrastructure (Terraform) and config (Ansible)&lt;/li&gt;
&lt;li&gt;Used proper logging and error handling via Ansible&lt;/li&gt;
&lt;li&gt;Debugged systemd failures using &lt;code&gt;journalctl&lt;/code&gt; inside playbooks&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 What’s Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;DNS and HTTPS (via Route 53 + Let’s Encrypt)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Integrate &lt;strong&gt;GitHub Webhooks&lt;/strong&gt; to trigger Jenkins jobs automatically&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;S3 and CloudWatch&lt;/strong&gt; for backups and monitoring&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Built With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;☁️ AWS EC2&lt;/li&gt;
&lt;li&gt;🧱 Terraform&lt;/li&gt;
&lt;li&gt;⚙️ Ansible&lt;/li&gt;
&lt;li&gt;🐧 Ubuntu 22.04&lt;/li&gt;
&lt;li&gt;💻 Jenkins&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  👥 Team
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Muhirwa&lt;/strong&gt; — DevOps Engineer &amp;amp; Builder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/muhirwaJD/Terraform-and-Ansible.git" rel="noopener noreferrer"&gt;GitHub - muhirwaJD/Terraform-and-Ansible&lt;/a&gt;&lt;/p&gt;




</description>
      <category>terraform</category>
      <category>ansible</category>
      <category>cloudcomputing</category>
      <category>awschallenge</category>
    </item>
    <item>
      <title>Cloudwatch Monitoring</title>
      <dc:creator>muhirwaJD</dc:creator>
      <pubDate>Wed, 02 Jul 2025 09:11:17 +0000</pubDate>
      <link>https://dev.to/muhirwajd/cloudwatch-monitoring-4o9b</link>
      <guid>https://dev.to/muhirwajd/cloudwatch-monitoring-4o9b</guid>
      <description>&lt;h1&gt;
  
  
  🛠️ Node.js Logging to CloudWatch from Dockerized EC2 App
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🧩 Project Overview
&lt;/h2&gt;

&lt;p&gt;In this project, I built a lightweight Node.js web server using Morgan middleware to log HTTP requests. I deployed it on an EC2 instance, containerized the app with Docker, and then configured AWS CloudWatch to stream logs both from a file (for traditional deployment) and directly from Docker (for container-based monitoring).&lt;/p&gt;

&lt;p&gt;This dual setup gave me deep visibility into application traffic using two popular logging strategies—and helped me better understand how to monitor apps in cloud-native environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What I Built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ A Node.js app with HTTP request logging using Morgan&lt;/li&gt;
&lt;li&gt;✅ Dockerized version of the app using a custom Dockerfile&lt;/li&gt;
&lt;li&gt;✅ Deployed on an Ubuntu EC2 instance&lt;/li&gt;
&lt;li&gt;✅ Implemented two types of logging to CloudWatch:

&lt;ul&gt;
&lt;li&gt;File-based logging with CloudWatch Agent (for non-containerized apps)&lt;/li&gt;
&lt;li&gt;Docker log driver for real-time streaming (for containerized apps)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Why This Matters
&lt;/h2&gt;

&lt;p&gt;Logging is critical for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📈 Monitoring traffic and diagnosing issues&lt;/li&gt;
&lt;li&gt;🔒 Ensuring app health and security&lt;/li&gt;
&lt;li&gt;🔍 Auditing activity for compliance or troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project taught me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to configure IAM roles securely for EC2 and CloudWatch&lt;/li&gt;
&lt;li&gt;How to write logs to both file and console for hybrid observability&lt;/li&gt;
&lt;li&gt;How to use Docker's native log drivers to stream data to AWS CloudWatch&lt;/li&gt;
&lt;li&gt;The differences and use cases between classic agent-based logging vs container-native logging&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Key Learnings
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker logs can be streamed directly to CloudWatch without writing to disk&lt;/li&gt;
&lt;li&gt;Morgan allows dual streaming (file + console), which is perfect for hybrid setups&lt;/li&gt;
&lt;li&gt;CloudWatch Agent requires precise file paths and log group names to function&lt;/li&gt;
&lt;li&gt;IAM roles must be attached to EC2 instances with the correct policies (&lt;code&gt;CloudWatchAgentServerPolicy&lt;/code&gt;, &lt;code&gt;AmazonSSMManagedInstanceCore&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Real-time log monitoring helps identify traffic patterns and potential issues instantly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express / Morgan middleware&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;AWS EC2 (Ubuntu)&lt;/li&gt;
&lt;li&gt;AWS CloudWatch Logs&lt;/li&gt;
&lt;li&gt;AWS IAM Roles&lt;/li&gt;
&lt;li&gt;CloudWatch Agent&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 How to Try It Yourself
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Clone the Node.js app with Morgan logging&lt;/li&gt;
&lt;li&gt;Build the Docker image and run it&lt;/li&gt;
&lt;li&gt;Either:

&lt;ul&gt;
&lt;li&gt;Use CloudWatch Agent to stream from a file, or&lt;/li&gt;
&lt;li&gt;Use Docker's awslogs driver for direct streaming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Monitor traffic logs in CloudWatch in real time!&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📸 Screenshots
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Terminal output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyazsptwcvex03fjjreed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyazsptwcvex03fjjreed.png" alt="Logs sent to terminal" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatch Log Group + Stream&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhvra9dttelqf09fy8mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhvra9dttelqf09fy8mp.png" alt="Logs sent to cloudwatch" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: You'll see the IPs hidden ofc. Sorry hackers, these IPs are not for you 🙃&lt;/p&gt;

</description>
      <category>cloudwatch</category>
      <category>cloudcomputing</category>
      <category>cloudflarechallenge</category>
      <category>awschallenge</category>
    </item>
  </channel>
</rss>
