<?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: Femi</title>
    <description>The latest articles on DEV Community by Femi (@oofemi).</description>
    <link>https://dev.to/oofemi</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%2F3870568%2F4a913260-4184-4308-b879-4b39d49abd6d.jpeg</url>
      <title>DEV Community: Femi</title>
      <link>https://dev.to/oofemi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oofemi"/>
    <language>en</language>
    <item>
      <title>Tool-Chain Automation: Using Ansible to Deploy Terraform and Web Content</title>
      <dc:creator>Femi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 20:45:15 +0000</pubDate>
      <link>https://dev.to/oofemi/tool-chain-automation-using-ansible-to-deploy-terraform-and-web-content-1579</link>
      <guid>https://dev.to/oofemi/tool-chain-automation-using-ansible-to-deploy-terraform-and-web-content-1579</guid>
      <description>&lt;p&gt;Automation doesn't stop at OS updates. Today, I expanded my Ansible master playbook to handle two very different, but equally important, tasks:&lt;/p&gt;

&lt;p&gt;​Software Provisioning: Used the unarchive module to fetch, unzip, and install Terraform from a remote URL directly into /usr/local/bin. &lt;/p&gt;

&lt;p&gt;No manual downloads, no mess.&lt;br&gt;
​Content Orchestration: Deployed a custom HTML site across my web tier using the copy module, ensuring strict Linux permissions (0644) were applied automatically.&lt;/p&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%2F0q4gk51ur24ruvz8nc50.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%2F0q4gk51ur24ruvz8nc50.png" alt=" " width="500" height="548"&gt;&lt;/a&gt;&lt;br&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%2F1wfmvjq3kjai4qtjcb93.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%2F1wfmvjq3kjai4qtjcb93.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
​By combining package management (apt/dnf), remote resource fetching, and file distribution, I've created a single point of truth for my entire workstation and server fleet.&lt;br&gt;
​IaC isn't just about the servers; it's about the tools we use to build them! 🛠️"&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>ansible</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Surgical Automation: Mastering Ansible Tags for Multi-Tier Deployments</title>
      <dc:creator>Femi</dc:creator>
      <pubDate>Tue, 14 Apr 2026 15:57:38 +0000</pubDate>
      <link>https://dev.to/oofemi/surgical-automation-mastering-ansible-tags-for-multi-tier-deployments-2bkc</link>
      <guid>https://dev.to/oofemi/surgical-automation-mastering-ansible-tags-for-multi-tier-deployments-2bkc</guid>
      <description>&lt;p&gt;​Today, I implemented Ansible Tags to solve this.&lt;br&gt;
​By tagging my tasks ( tags: apache, tags: db), I now have 'surgical' control over my infrastructure. I can:&lt;br&gt;
​Update just the Web tier: ansible-playbook master.yml --tags "apache"&lt;br&gt;
​Deploy only Database changes: ansible-playbook master.yml --tags "db"&lt;/p&gt;

&lt;p&gt;​Skip the long update processes: ansible-playbook master.yml --skip-tags "always"&lt;/p&gt;

&lt;p&gt;​I also maintained my Multi-OS logic, ensuring my tags work seamlessly across both Ubuntu and CentOS nodes.&lt;/p&gt;

&lt;p&gt;​This taught me a valuable lesson in 'Developer Experience' (DX)—making my automation tools easy and fast.&lt;br&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%2Fzm69erbn9ua6asnq9wfj.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%2Fzm69erbn9ua6asnq9wfj.png" alt=" " width="577" height="652"&gt;&lt;/a&gt;&lt;br&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%2Fmte61axjs8p12kmp0lyi.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%2Fmte61axjs8p12kmp0lyi.png" alt=" " width="638" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>devops</category>
      <category>automation</category>
      <category>cloud</category>
    </item>
    <item>
      <title>From Scripts to Infrastructure-as-Code: Building a Multi-Tier Ansible Playbook</title>
      <dc:creator>Femi</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:35:15 +0000</pubDate>
      <link>https://dev.to/oofemi/from-scripts-to-infrastructure-as-code-building-a-multi-tier-ansible-playbook-9l2</link>
      <guid>https://dev.to/oofemi/from-scripts-to-infrastructure-as-code-building-a-multi-tier-ansible-playbook-9l2</guid>
      <description>&lt;p&gt;There is a moment in every DevOps journey where it just 'clicks.' For me, it was today.&lt;br&gt;
I’ve spent the last week moving away from manual configuration to a fully automated, role-based infrastructure. Instead of one long list of tasks, I’ve organized my environment into logical groups:&lt;br&gt;
Web Tier: Automated Apache + PHP setup (handling Ubuntu/CentOS differences).&lt;br&gt;
Database Tier: MariaDB provisioning.&lt;br&gt;
File Tier: Samba deployment using the agnostic package module.&lt;/p&gt;

&lt;p&gt;The best part? It’s completely smart. Using Ansible facts, the playbook detects the OS and adjusts package names and managers (apt vs. dnf) on the fly. No more 'permission denied' errors or broken dependencies—just clean, idempotent automation.&lt;/p&gt;

&lt;p&gt;Key Lesson Learned: Formatting is everything in YAML! Managing multiple 'plays' in one file requires strict attention to indentation and host grouping.&lt;br&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%2Fut27a93xckw5twqqfp32.jpg" 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%2Fut27a93xckw5twqqfp32.jpg" alt=" " width="710" height="919"&gt;&lt;/a&gt;&lt;br&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%2F5cliwb3j99wcqpc5bboj.jpg" 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%2F5cliwb3j99wcqpc5bboj.jpg" alt=" " width="580" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>ubuntu</category>
      <category>devops</category>
      <category>automation</category>
    </item>
    <item>
      <title>Smart Playbooks: Handling Ubuntu and CentOS in one go with Ansible</title>
      <dc:creator>Femi</dc:creator>
      <pubDate>Sat, 11 Apr 2026 21:57:55 +0000</pubDate>
      <link>https://dev.to/oofemi/smart-playbooks-handling-ubuntu-and-centos-in-one-go-with-ansible-3jo4</link>
      <guid>https://dev.to/oofemi/smart-playbooks-handling-ubuntu-and-centos-in-one-go-with-ansible-3jo4</guid>
      <description>&lt;p&gt;One of the biggest hurdles in automation is environmental drift—specifically when your fleet isn't running the same OS.&lt;br&gt;
​I recently tackled this in an enterprise environment. I wanted to deploy a web stack, but my nodes are a mix of Ubuntu 24.04 and CentOS. Since Ubuntu uses apt and Apache is called apache2, while CentOS uses dnf and Apache is called httpd, a simple script wouldn't cut it.&lt;/p&gt;

&lt;p&gt;​Enter Ansible Conditionals.&lt;br&gt;
​By using the when statement tied to the ansible_distribution fact, I built a 'smart' playbook that:&lt;br&gt;
​Detects the OS automatically.&lt;br&gt;
​Runs apt tasks for Ubuntu and dnf for CentOS.&lt;br&gt;
​Installs the correct package names for each.&lt;/p&gt;

&lt;p&gt;​It’s a small logic jump, but it’s the difference between a playbook that works on one machine and a playbook that works on a thousand.&lt;/p&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%2Fe1rh081g3x0xddnjlyhb.jpg" 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%2Fe1rh081g3x0xddnjlyhb.jpg" alt=" " width="800" height="1319"&gt;&lt;/a&gt;&lt;br&gt;
​Next up on my journey: Implementing Handlers to make these updates even more efficient! 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>automation</category>
      <category>linux</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>The proof-of- work with Ansible</title>
      <dc:creator>Femi</dc:creator>
      <pubDate>Fri, 10 Apr 2026 21:11:19 +0000</pubDate>
      <link>https://dev.to/oofemi/the-proof-of-work-with-ansible-2jm1</link>
      <guid>https://dev.to/oofemi/the-proof-of-work-with-ansible-2jm1</guid>
      <description>&lt;p&gt;Seeing "changed=1" is the most satisfying feeling in DevOps. 🚀&lt;br&gt;
​I just finished building a playbook that handles the full onboarding of a new admin user across multiple Ubuntu servers simultaneously.&lt;/p&gt;

&lt;p&gt;​The stack:&lt;br&gt;
​Control Node: Ubuntu 24.04 (Brown)&lt;br&gt;
​Managed Nodes: 3x Ubuntu VMs&lt;br&gt;
​Orchestration: Ansible&lt;br&gt;
​Security: SHA-512 Hashing &amp;amp; SSH Key injection&lt;/p&gt;

&lt;p&gt;​By moving away from manual useradd commands, I’m ensuring that my infrastructure is consistent, secure, and easily reproducible. Every error today was just a lesson in how the Linux shadow file works under the hood.&lt;br&gt;
​Moving one step closer to a full automation  🐧💻&lt;/p&gt;

&lt;p&gt;​#Ansible #DevOps #SysAdmin #Tech&lt;br&gt;
 #Infrastructure&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ansible</category>
      <category>automation</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
