<?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: Samuel Theophilus</title>
    <description>The latest articles on DEV Community by Samuel Theophilus (@afkzoro).</description>
    <link>https://dev.to/afkzoro</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%2F1000131%2F9f7b27f3-9fec-43d7-b49b-22cf6578e92d.jpg</url>
      <title>DEV Community: Samuel Theophilus</title>
      <link>https://dev.to/afkzoro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/afkzoro"/>
    <language>en</language>
    <item>
      <title>Deploying a Hugo Static Website to AWS S3 and Cloudflare Using Pulumi</title>
      <dc:creator>Samuel Theophilus</dc:creator>
      <pubDate>Wed, 02 Apr 2025 08:53:09 +0000</pubDate>
      <link>https://dev.to/afkzoro/deploying-a-hugo-static-website-to-aws-s3-and-cloudflare-using-pulumi-4efa</link>
      <guid>https://dev.to/afkzoro/deploying-a-hugo-static-website-to-aws-s3-and-cloudflare-using-pulumi-4efa</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pulumi"&gt;Pulumi Deploy and Document Challenge&lt;/a&gt;: Fast Static Website Deployment&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I created an automated deployment pipeline for a Hugo static website using Pulumi for infrastructure management. The solution uses AWS S3 for hosting and Cloudflare as a CDN, with GitHub Actions handling continuous deployment. This setup provides a fast, secure, and cost-effective way to host static websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Demo Link
&lt;/h2&gt;

&lt;p&gt;Check out the live site at: &lt;a href="https://afkprojects.online" rel="noopener noreferrer"&gt;https://afkprojects.online&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Repo
&lt;/h2&gt;

&lt;p&gt;The complete project is available on GitHub: &lt;a href="https://github.com/afkzoro/pulumi-hugo-s3" rel="noopener noreferrer"&gt;pulumi-hugo-s3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pulumi TypeScript for infrastructure management&lt;/li&gt;
&lt;li&gt;Hugo static site generator&lt;/li&gt;
&lt;li&gt;AWS S3 for hosting&lt;/li&gt;
&lt;li&gt;Cloudflare CDN integration&lt;/li&gt;
&lt;li&gt;GitHub Actions for CI/CD&lt;/li&gt;
&lt;li&gt;Automated SSL/TLS certificate management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Challenge
&lt;/h3&gt;

&lt;p&gt;I wanted to create a simple but effective deployment pipeline for static websites that would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost-effective for small projects&lt;/li&gt;
&lt;li&gt;Easily maintainable&lt;/li&gt;
&lt;li&gt;Secure by default&lt;/li&gt;
&lt;li&gt;Fast to deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Used Pulumi to provision AWS S3 infrastructure&lt;/li&gt;
&lt;li&gt;Integrated Cloudflare for CDN and DNS management&lt;/li&gt;
&lt;li&gt;Set up GitHub Actions for automated deployments&lt;/li&gt;
&lt;li&gt;Configured Hugo for static site generation&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;S3 Bucket Permissions&lt;/strong&gt;: Initially struggled with correct bucket policies and public access settings. Solved by carefully configuring bucket ACLs and ownership controls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CDN Integration&lt;/strong&gt;: Chose Cloudflare over AWS CloudFront for better cost efficiency and simpler setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deployment Automation&lt;/strong&gt;: Created a GitHub Actions workflow that coordinates Hugo builds with Pulumi deployments.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Using Pulumi
&lt;/h2&gt;

&lt;p&gt;Pulumi was instrumental in managing infrastructure as code. Key benefits included:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type Safety&lt;/strong&gt;: Using TypeScript provided better error catching and IDE support.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Management&lt;/strong&gt;: Pulumi handled all AWS and Cloudflare resources consistently:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;websiteBucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;aws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BucketV2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;websiteBucket&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bucketName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;forceDestroy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cloudflareRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cloudflare&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cloudflareRecord&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;zoneId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zoneId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CNAME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;websiteBucketConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;websiteEndpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;proxied&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State Management&lt;/strong&gt;: Pulumi's state management made it easy to track and update infrastructure changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Learnings
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as Code principles with Pulumi&lt;/li&gt;
&lt;li&gt;AWS S3 static website hosting configuration&lt;/li&gt;
&lt;li&gt;CDN integration and DNS management&lt;/li&gt;
&lt;li&gt;CI/CD pipeline setup with GitHub Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project demonstrates how modern IaC tools like Pulumi can simplify complex deployments while maintaining security and performance.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>pulumichallenge</category>
      <category>webdev</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Simulating Dynamic Multiple Host Networking With Vagrant</title>
      <dc:creator>Samuel Theophilus</dc:creator>
      <pubDate>Tue, 12 Mar 2024 08:19:55 +0000</pubDate>
      <link>https://dev.to/afkzoro/simulating-dynamic-multiple-host-networking-with-vagrant-514i</link>
      <guid>https://dev.to/afkzoro/simulating-dynamic-multiple-host-networking-with-vagrant-514i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;For network testing scenarios where deploying physical machines is impractical, &lt;a href="https://www.vagrantup.com/"&gt;Vagrant&lt;/a&gt; offers a solution. This tool allows the creation of multiple virtual hosts within a controlled, private network, enabling you to simulate real-world network interactions and test connectivity between systems.&lt;/p&gt;

&lt;p&gt;In this article, you’ll explore the technical aspects of using Vagrant for network simulation and learn about the advantages of using it for interconnected systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A working Vagrant installation. See the &lt;a href="https://developer.hashicorp.com/vagrant/docs/installation"&gt;installation&lt;/a&gt; guide on their official website.&lt;/li&gt;
&lt;li&gt;A working Virtualbox installation. Check their official &lt;a href="https://www.virtualbox.org/wiki/Downloads"&gt;website&lt;/a&gt; to install it.&lt;/li&gt;
&lt;li&gt;A fair understanding of Linux. You can check this &lt;a href="https://www.digitalocean.com/community/tutorial-series/getting-started-with-linux"&gt;Linux&lt;/a&gt; tutorial series on Digital Ocean.&lt;/li&gt;
&lt;li&gt;An internet connection to download any necessary dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 - Downloading the box
&lt;/h3&gt;

&lt;p&gt;A vagrant box is a copy of a specific operating system. Vagrant makes these copies available on the cloud for reproducing virtual environments.&lt;/p&gt;

&lt;p&gt;For this tutorial, you are using a Eurolinux CentOS box. To download this box, enter the following commands in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant box add eurolinux-vagrant/centos-stream-9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command downloads the CentOS Stream 9 box image from &lt;a href="https://app.vagrantup.com/boxes/search"&gt;Vagrant Cloud&lt;/a&gt; (a repository for pre-build Vagrant boxes). The locally stored box enables you to create multiple virtual environments without downloading it again. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Provisioning the virtual machine
&lt;/h3&gt;

&lt;p&gt;Create a folder named &lt;strong&gt;netsim&lt;/strong&gt; and move into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;netsim
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;netsim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a virtual machine you’ll need a Vagrantfile.&lt;/p&gt;

&lt;p&gt;A Vagrantfile is a plain text file written in Ruby that tells Vagrant exactly what kind of virtual machine to create and configure. It’s a blueprint for your development environment.&lt;/p&gt;

&lt;p&gt;Create a Vagrantfile using this Command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Vagrantfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tutorial demonstrates using Vim to add configuration details to the file, but you can use any editor you prefer.&lt;/p&gt;

&lt;p&gt;Open the file in Vim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vim Vagrantfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to insert mode by pressing &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declare &lt;code&gt;vm_memory&lt;/code&gt; and &lt;code&gt;vm_cpus&lt;/code&gt; :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;vm_memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
&lt;span class="n"&gt;vm_cpus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;vm_memory&lt;/code&gt; allocates 1024MB(1GB) of RAM to the virtual machine. &lt;code&gt;vm_cpus&lt;/code&gt; assigns a single CPU to the VM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Base Box for the development environment:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eurolinux-vagrant/centos-stream-9"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box_check_update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Vagrant.configure("2") do |config|&lt;/code&gt; initiates a configuration block within the Vagrantfile, specifying version 2 of the Vagrant configuration syntax. &lt;code&gt;config.vm.box = "eurolinux-vagrant/centos-stream-9"&lt;/code&gt; instructs Vagrant to use CentOS Stream 9 virtual machine image. &lt;code&gt;config.vm.box_check_update = false&lt;/code&gt; disables automatic box update for the virtual machine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increase memory allocation:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"virtualbox"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;#   Customize the amount of memory on the VM:&lt;/span&gt;
      &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
      &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;vb.memory&lt;/code&gt; allocates 1024MB of RAM to the virtual machine. &lt;code&gt;vb.cpus&lt;/code&gt; assigns a single CPU to the VM.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define a virtual machine:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"server-1"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line above creates a new virtual machine named &lt;code&gt;server-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Under this configuration block, equip the virtual machine with a shell script that executes during the provisioning process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;
     ip addr | grep &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;inet&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt; | awk '{print $2}'
&lt;/span&gt;&lt;span class="no"&gt;   SHELL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script retrieves the IP address of the VM and prints it to the console.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assign a static IP address to the VM:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.39"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;virtualbox__intnet: &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line above establishes a private network interface for the virtual machine, assigns a static IP address(&lt;code&gt;192.168.56.39&lt;/code&gt;), and isolates it within a VirtualBox-specific internal network.&lt;/p&gt;

&lt;p&gt;Private networks create isolated environments for virtual machines. They are ideal for testing and development in security-sensitive scenarios.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;virtualbox__intnet: "true"&lt;/code&gt; enables VirtualBox’s internal networking for that specific virtual machine. This means the network is completely isolated from the host machine or outside networks and can only communicate with other machines on the same private network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Adding a new machine
&lt;/h3&gt;

&lt;p&gt;To add a virtual machine to this private network, repeat the process in the previous step and assign a different static IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"server-2"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;
     ip addr | grep &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;inet&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt; | awk '{print $2}'
&lt;/span&gt;&lt;span class="no"&gt;   SHELL&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.56.40"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;virtualbox__intnet: &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new virtual machine named &lt;code&gt;server-2&lt;/code&gt; and provisions it with the same configurations as the first machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 - Applying DRY principles
&lt;/h3&gt;

&lt;p&gt;DRY stands for Don’t Repeat Yourself. It’s an important principle in software development that emphasizes the importance of writing reusable code to avoid unnecessary duplication.&lt;/p&gt;

&lt;p&gt;In the previous step, you duplicated the configuration setup for the first machine. This goes against the DRY principle.&lt;/p&gt;

&lt;p&gt;To make the virtual machine creation process reusable, you’re going to make some changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clear the configuration setups for both machines.&lt;/li&gt;
&lt;li&gt;Declare &lt;code&gt;vm_num&lt;/code&gt; at the top of the file and set it to &lt;code&gt;2&lt;/code&gt; :
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;vm_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Paste the script below:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;vm_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;#a lAB in the 192.168.56.0/24range&lt;/span&gt;
    &lt;span class="n"&gt;lan_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"192.168.56.&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"server-&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;
        ip addr | grep &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;inet&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt; | awk '{print $2}'
&lt;/span&gt;&lt;span class="no"&gt;      SHELL&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="n"&gt;lan_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;virtualbox__intnet: &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a breakdown of what the script does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;(1..vm_num) .each do |n|&lt;/code&gt; is a loop that iterates over a range from 1 to &lt;code&gt;vm_num&lt;/code&gt; , where vm_num is the total number of VMs you want to create. For each iteration, n is the current number in the range.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lan_ip = "192.168.56.#{n+10}"&lt;/code&gt; sets the LAN IP address for each VM. The IP addresses start from “192.168.56.11” and increment by 1 for each VM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.vm.define "server-#{n}" do |config|&lt;/code&gt; defines a new VM with the name “server-n”, where &lt;strong&gt;&lt;code&gt;n&lt;/code&gt;&lt;/strong&gt; is the current number in the range.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.vm.provision :shell, :inline =&amp;gt; "ip addr | grep \"inet\" | awk '{print $2}'"&lt;/code&gt;provisions the VM using a shell script. The script retrieves the IP address of the VM.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.vm.network "private_network", ip: lan_ip, virtualbox__intnet: "true"&lt;/code&gt; set up a private network for the VM and assigns it the &lt;code&gt;lan_ip&lt;/code&gt; defined earlier. The &lt;code&gt;virtualbox__intnet: "true"&lt;/code&gt; option specifies that the network should be a VirtualBox internal network as explained in the previous steps.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;end&lt;/code&gt; terminates the definition for the current VM. The loop then moves on to the next number in the range, until all VMs have been defined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the complete Vagrantfile, after all the necessary configurations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# -*- mode: ruby -*-&lt;/span&gt;
&lt;span class="c1"&gt;# vi: set ft=ruby :&lt;/span&gt;

&lt;span class="n"&gt;vm_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eurolinux-vagrant/centos-stream-9"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box_check_update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;

  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"virtualbox"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;#   Customize the amount of memory on the VM:&lt;/span&gt;
      &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
      &lt;span class="n"&gt;vb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

   &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;vm_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;#a lAB in the 192.168.56.0/24range&lt;/span&gt;
    &lt;span class="n"&gt;lan_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"192.168.56.&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"server-&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;
        ip addr | grep &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt;inet&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="sh"&gt; | awk '{print $2}'
&lt;/span&gt;&lt;span class="no"&gt;      SHELL&lt;/span&gt;
      &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="n"&gt;lan_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;virtualbox__intnet: &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you have less than 8 gigs of RAM, consider lowering the virtual machine’s memory to 512MB.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save and exit the file.&lt;/p&gt;

&lt;p&gt;Then, run the &lt;code&gt;vagrant up&lt;/code&gt; command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;vagrant&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates the virtual environments as configured in the Vagrantfile.&lt;/p&gt;

&lt;p&gt;The provisioning process prints the IP addresses of both machines to the console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foekow5b3h6sxljocizmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foekow5b3h6sxljocizmd.png" alt="server-1" width="497" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhh13bk3uas080xuo2v8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhh13bk3uas080xuo2v8e.png" alt="server-2" width="421" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 - Testing their connectivity
&lt;/h3&gt;

&lt;p&gt;You’ve fully set up the virtual machines. To test the connection between them, you’ll need to run a ping test on each machine. If configured successfully, they would operate on the same private network, accessible only to each other.&lt;/p&gt;

&lt;p&gt;Login to &lt;code&gt;server-1&lt;/code&gt; and send 4 packets to &lt;code&gt;server-2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant ssh server-1
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 192.168.56.11 &lt;span class="nt"&gt;-c&lt;/span&gt; 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A solid connection ensures zero packet loss. To verify, log in to server-2 and send 4 packets to server-1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;vagrant ssh server-2
&lt;span class="nv"&gt;$ &lt;/span&gt;ping 192.168.56.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, you’ve set up a multi-host environment for development with Vagrant. Additionally, you utilized private networking within these environments.&lt;/p&gt;

&lt;p&gt;Private networks safeguard your environment from external threats and ensure secure communication.&lt;/p&gt;

&lt;p&gt;If you enjoyed this article or have any questions, kindly indicate in the comments.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>automation</category>
      <category>networking</category>
      <category>infrastructureascode</category>
    </item>
  </channel>
</rss>
