<?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: Ezekiel Umesi</title>
    <description>The latest articles on DEV Community by Ezekiel Umesi (@ezekiel_umesi_5bd2fa6069c).</description>
    <link>https://dev.to/ezekiel_umesi_5bd2fa6069c</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%2F3304041%2Fac30ac20-ce43-4ee3-b744-cf061bc37e20.png</url>
      <title>DEV Community: Ezekiel Umesi</title>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ezekiel_umesi_5bd2fa6069c"/>
    <language>en</language>
    <item>
      <title>The Dangerous Comfort of the Checkbox: Why Compliance is Not Security</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Fri, 19 Sep 2025 01:17:07 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/the-dangerous-comfort-of-the-checkbox-why-compliance-is-not-security-nc4</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/the-dangerous-comfort-of-the-checkbox-why-compliance-is-not-security-nc4</guid>
      <description>&lt;p&gt;If you work in cloud, risk, or leadership, you know the grueling effort required to align an environment with frameworks like SOC 2, ISO 27001, HIPAA, or PCI DSS. Teams spend months configuring guardrails, tightening IAM policies, and documenting controls. When the audit report finally comes back clean, it feels like a definitive win.&lt;/p&gt;

&lt;p&gt;A successful audit proves your organization takes governance seriously. It builds customer trust, unblocks enterprise deals, and validates that your AWS workloads meet rigorous industry standards.&lt;/p&gt;

&lt;p&gt;But there is a dangerous assumption lurking behind that clean report: the belief that because an environment is compliant, it is automatically secure.&lt;/p&gt;

&lt;p&gt;In the cloud, compliance means you have implemented the required controls. Security, however, means those controls remain effective against real-world threats.&lt;/p&gt;

&lt;p&gt;AWS provides a powerful arsenal—IAM, CloudTrail, GuardDuty, and Security Hub—but tools are not a strategy. They must be continuously monitored and aligned with evolving threat models, not just a static checklist. The real work begins the moment the audit ends—when the focus shifts from "Are we compliant?" to "Are we resilient?"&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%2Fa7szcbg4hncnxwt8a8y5.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%2Fa7szcbg4hncnxwt8a8y5.png" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is exactly the point where many organizations stumble. Thinking of compliance as a "finish line" rather than a "baseline" creates a false sense of security that sophisticated attackers love to exploit.&lt;/p&gt;

&lt;p&gt;To bridge the gap between a clean audit and a truly hardened environment, you have to look at how these two worlds interact within the AWS ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Saying "Compliance = Security" is Wrong and Dangerous
&lt;/h2&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%2Fwisuzi4y3lvlgtn94z3a.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%2Fwisuzi4y3lvlgtn94z3a.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Compliance Looks Backward. Threats Come from the Future.
&lt;/h3&gt;

&lt;p&gt;Compliance rules are based on what we already know. They are written from past best practices, often in response to the last major attack. They are very good at solving yesterday's problems.&lt;/p&gt;

&lt;p&gt;But attackers live in the present and future. They are always inventing new methods, finding unknown vulnerabilities (zero-days), and creating clever tricks to fool people. These new threats won't be on any compliance checklist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Compliance asks:&lt;/strong&gt; "Do you have a rule for firewalls?" and "Do you force password changes every 90 days?"&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Security asks:&lt;/strong&gt; "Is our firewall set up to stop this new data theft method?" and "Are our people prepared for the latest phishing email that can get around multi-factor authentication (MFA)?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compliance checks the rearview mirror. Security has to watch the road ahead for dangers that are not on the map.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compliance is the Minimum, Not the Goal
&lt;/h3&gt;

&lt;p&gt;Compliance standards are made so that many different companies can meet them. They set a baseline, a starting point, and not the finish line. They are the lowest level of security needed to be in an industry.&lt;/p&gt;

&lt;p&gt;If you make this minimum your main goal, you are not aiming high enough. You are building a wall that is just high enough to pass inspection, while attackers are building taller ladders.&lt;/p&gt;

&lt;p&gt;Real security is a culture of always getting better. It means adding layers of defense, planning for a breach, actively looking for threats, and using advanced tools that compliance rules might not talk about, like Zero-Trust or Endpoint Detection and Response (EDR).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Checkbox Mindset vs. The Security Mindset
&lt;/h3&gt;

&lt;p&gt;This is the core of the problem. The process of passing an audit encourages a "checkbox mindset." The goal becomes to prove you have a control, not to make sure that control actually works well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Checkbox Mindset:&lt;/strong&gt; "Yes, we have a plan for what to do in a cyber attack." (The plan is a long document that no one has read or practiced).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Security Mindset:&lt;/strong&gt; "Let's practice our response to a ransomware attack in a drill. Let's see if our team knows what to do when under real pressure."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One is about having paperwork. The other is about being ready to act. You can check every box and still have a security program that fails completely during a real attack.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Your Audit Scope vs. Your Real Attack Surface
&lt;/h3&gt;

&lt;p&gt;A compliance audit has a defined "scope." This usually includes your main cloud servers and work laptops. It often &lt;em&gt;excludes&lt;/em&gt; things like test systems, third-party apps, unauthorized software, or employees' home networks.&lt;/p&gt;

&lt;p&gt;An attacker does not care about your audit scope. Their target is your entire &lt;strong&gt;attack surface&lt;/strong&gt;. They will happily attack a weak point in a marketing tool, find a mistake in a test environment, or trick an employee on their home computer. If you only protected what was in your audit scope, you have left many other doors unlocked.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Build a Truly Secure Program
&lt;/h3&gt;

&lt;p&gt;So, if compliance isn't security, what should you do? Should you stop doing audits? No. Compliance is still very important. You just need to use it the right way.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Compliance as a Foundation, Not the Finish Line.&lt;/strong&gt; Let standards like SOC 2 give your security program a basic structure. Think of the certificate as a ticket that lets you into the game, not the prize for winning it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Focus on Always Getting Better.&lt;/strong&gt; Change the question in your company from "Are we compliant?" to "Are we secure?" Test yourself against real-world attack scenarios, not just a list of controls. Invest in training, threat information, and proactively searching for hackers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Focus on Results, Not Rules.&lt;/strong&gt; Don't just set up a security control; test how well it works. Is our MFA actually blocking attacks? Can we actually restore our backups quickly after an attack? This shifts the goal from proving you &lt;em&gt;have&lt;/em&gt; a tool to proving it &lt;em&gt;works&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assume You Are Already Hacked.&lt;/strong&gt; This is the biggest change in thinking. Operate as if an attacker is already inside your network. This makes you invest in what matters most: finding threats quickly, responding effectively, and recovering fast. These skills are often overlooked in compliance rules but are essential for survival.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion: The Map and the Territory
&lt;/h3&gt;

&lt;p&gt;Compliance is the license to operate, but security is the will to survive. In AWS, your audit report proves you have the tools; your operational cadence proves you know how to use them when the sirens go off.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>management</category>
      <category>security</category>
    </item>
    <item>
      <title>Shifting Security Left: Why DevSecOps is Not Optional Anymore</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Fri, 19 Sep 2025 00:57:16 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/shifting-security-left-why-devsecops-is-not-optional-anymore-52fk</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/shifting-security-left-why-devsecops-is-not-optional-anymore-52fk</guid>
      <description>&lt;p&gt;For a long time, software development and security were separate. Development teams focused on building features quickly. Security teams focused on finding risks and vulnerabilities. They worked in silos. Developers would finish an application and then "throw it over the wall" to the security team for testing right before launch. This caused last-minute panic to fix issues, delayed releases, and frustrated everyone.&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%2Fmx4uvkbdojwsnfzzuph0.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%2Fmx4uvkbdojwsnfzzuph0.png" alt=" " width="512" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This old way of working is no longer just inefficient; it's unsafe. Today, cyberattacks are common, and one software weakness can lead to a major data breach. Security can't be an afterthought. It must be built into every step of the development process. This is the main idea behind &lt;strong&gt;DevSecOps&lt;/strong&gt;—and it is now essential for any company that creates software.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does "Shifting Left" Mean?
&lt;/h3&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%2Fuehiw7zeveyd8gvkyx4h.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%2Fuehiw7zeveyd8gvkyx4h.png" alt=" " width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Shifting left" means adding security checks early and throughout the entire software building process (the Software Development Lifecycle, or SDLC). Instead of one big security test at the end, security happens at every stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Code:&lt;/strong&gt; A developer writes code. Security starts here with tools in their coding software that scan for mistakes or exposed secrets (like passwords) before the code is even shared.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Build:&lt;/strong&gt; When code is saved to a shared repository, automated processes begin. Tools called &lt;strong&gt;SAST&lt;/strong&gt; scan the source code to find flaws like SQL injection.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Test:&lt;/strong&gt; In the testing phase, other tools run automatically:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;DAST&lt;/strong&gt; tools test the running application for vulnerabilities.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;SCA&lt;/strong&gt; tools scan all the open-source building blocks (libraries) the app uses for known security holes.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Deploy:&lt;/strong&gt; Before the app goes live, tools scan the infrastructure setup (like cloud server configurations) to ensure nothing is accidentally left open to the internet.&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Operate:&lt;/strong&gt; After launch, security continues with monitoring for suspicious activity.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why You Must Use DevSecOps Now: The Real Reasons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modern Development is Too Fast for Old Security&lt;/strong&gt;&lt;br&gt;
Teams now release software multiple times a day. A security review that takes two weeks cannot work in this model. Automated security tools that work inside the development pipeline can keep up without slowing things down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fixing Bugs Later Costs Much More&lt;/strong&gt;&lt;br&gt;
Fixing a vulnerability while writing code might take minutes. Fixing the same bug after the app is built might take an hour. If found after release, the cost includes downtime, breach cleanup, legal fines, and lost customer trust. Finding issues early is far cheaper.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Third-Party Code is a Major Risk&lt;/strong&gt;&lt;br&gt;
Attacks like the one on &lt;a href="https://www.security.com/threat-intelligence/log4j-vulnerabilities-attacks" rel="noopener noreferrer"&gt;Log4j&lt;/a&gt; showed us that applications are built using many open-source parts. You must know if these parts have known weaknesses. An &lt;strong&gt;SCA tool&lt;/strong&gt; that automatically checks for these vulnerabilities is now a basic requirement for safety.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Systems Create New Risks&lt;/strong&gt;&lt;br&gt;
Modern apps run in the cloud using containers and microservices. A single setting mistake can expose huge amounts of data. Because this infrastructure is controlled by code, we must scan that code for errors &lt;em&gt;before&lt;/em&gt; it ever gets deployed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It Empowers Developers&lt;/strong&gt;&lt;br&gt;
DevSecOps isn't about making developers security experts. It's about giving them automated tools to find problems themselves, early on. This helps developers build more secure software and creates a better partnership with the security team.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Start: A Practical Approach
&lt;/h3&gt;

&lt;p&gt;You don't have to do everything at once. Start small:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Automate One Thing:&lt;/strong&gt; Begin by adding one automated scanner (like an SCA or SAST tool) to your build process.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Focus on Important Issues:&lt;/strong&gt; Don't overwhelm teams with thousands of warnings. Configure the tools to highlight only the most critical problems first.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Track Your Progress:&lt;/strong&gt; Measure how long it takes to fix a vulnerability after it's found. This shows you if your process is improving.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Encourage Teamwork:&lt;/strong&gt; Have security experts and developers work together on solutions. This builds a shared culture of security.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion: The New Essential
&lt;/h3&gt;

&lt;p&gt;Security is not a separate phase anymore. It is a core part of building software, like performance or usability. DevSecOps is how you make that happen.&lt;/p&gt;

&lt;p&gt;The question is no longer &lt;em&gt;if&lt;/em&gt; you can afford to do DevSecOps, but if you can afford &lt;em&gt;not&lt;/em&gt; to. The risk of ignoring it is too high. Building security in from the start creates software that is faster, stronger, and secure—protecting your customers and your business.&lt;/p&gt;

&lt;p&gt;Follow Me for More Security Tips.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Building an Automated Event-Driven File Processing System in Azure (No Code Required)</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Thu, 11 Sep 2025 20:43:11 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/building-an-automated-event-driven-file-processing-system-in-azure-no-code-required-1k6p</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/building-an-automated-event-driven-file-processing-system-in-azure-no-code-required-1k6p</guid>
      <description>&lt;p&gt;Managing file uploads and post-processing workflows often requires custom scripts, manual oversight, and complex pipelines. But with Microsoft Azure, you can build a &lt;strong&gt;fully automated, event-driven file processing system&lt;/strong&gt;—all through the Azure Portal. No command-line tools, no coding beyond minimal setup.&lt;/p&gt;

&lt;p&gt;This guide walks you step by step through creating a seamless workflow where uploading a file automatically triggers processing, archiving, and cleanup actions.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What You’ll Build
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Workflow Overview:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;File Upload → Blob Storage → Event Grid → Logic App → App Service → Automation Account&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here’s how it works in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A user uploads a file to &lt;strong&gt;Azure Blob Storage&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Grid&lt;/strong&gt; detects the upload and fires an event.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logic App&lt;/strong&gt; orchestrates the workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Service&lt;/strong&gt; processes the file with your business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation Account&lt;/strong&gt; archives and cleans up processed files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture scales automatically, has built-in monitoring, and charges only for what you use.&lt;/p&gt;




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

&lt;p&gt;Before you start, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An active &lt;strong&gt;Azure subscription&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributor access&lt;/strong&gt; to create resources&lt;/li&gt;
&lt;li&gt;A modern browser (Edge, Chrome, or Firefox)&lt;/li&gt;
&lt;li&gt;A test file (any text, image, or document)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 1: Foundation Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Resource Group
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the Azure Portal, create a new &lt;strong&gt;Resource Group&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;rg-workflow-demo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Region: Your closest Azure region&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This keeps all components organized.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a Storage Account
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;storage account&lt;/strong&gt; stores uploaded files and emits events when new files arrive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;stworkflowdemo123456&lt;/code&gt; (use random numbers for uniqueness)&lt;/li&gt;
&lt;li&gt;Redundancy: &lt;strong&gt;LRS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Secure transfer: &lt;strong&gt;Enabled&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Public access: &lt;strong&gt;Private&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, create a container inside it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;input-files&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Public Access: &lt;strong&gt;Private&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 2: Build the Processing Engine
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. App Service Plan
&lt;/h3&gt;

&lt;p&gt;Create an &lt;strong&gt;App Service Plan&lt;/strong&gt; to host your file processing logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;asp-workflow-demo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;OS: Linux&lt;/li&gt;
&lt;li&gt;Pricing Tier: &lt;strong&gt;B1 Basic&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Web App
&lt;/h3&gt;

&lt;p&gt;Create a &lt;strong&gt;Web App&lt;/strong&gt; on that plan.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;app-workflow-processor-123456&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Runtime: &lt;strong&gt;Node.js 18 LTS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Deploy Processing Logic
&lt;/h3&gt;

&lt;p&gt;Through &lt;strong&gt;Kudu (Advanced Tools)&lt;/strong&gt; or App Service Editor, create two files:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"azure-file-processor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"app.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node app.js"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.18.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@azure/storage-blob"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^12.17.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;app.js&lt;/code&gt;&lt;/strong&gt; → contains your processing logic (e.g., reading blob metadata).&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;npm install&lt;/code&gt; in the console.&lt;/p&gt;

&lt;p&gt;Add an &lt;strong&gt;App Setting&lt;/strong&gt; for your storage connection string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key: &lt;code&gt;STORAGE_CONNECTION_STRING&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value: [Your storage connection string]&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 3: Orchestrate with Logic Apps
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Logic App&lt;/strong&gt; coordinates the workflow.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;strong&gt;Logic App (Consumption)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add a trigger: &lt;strong&gt;When an HTTP request is received&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Parse the &lt;strong&gt;Event Grid JSON payload&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Extract file details with a &lt;strong&gt;Compose&lt;/strong&gt; action.&lt;/li&gt;
&lt;li&gt;Call the App Service API using an &lt;strong&gt;HTTP action&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;Condition&lt;/strong&gt; to check if processing succeeded.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Part 4: Post-Processing Automation
&lt;/h2&gt;

&lt;p&gt;Create an &lt;strong&gt;Automation Account&lt;/strong&gt; for archiving and cleanup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Runbook: Archive Files
&lt;/h3&gt;

&lt;p&gt;Create a &lt;strong&gt;PowerShell Runbook&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connects via Managed Identity&lt;/li&gt;
&lt;li&gt;Creates an &lt;code&gt;processed-files&lt;/code&gt; container if missing&lt;/li&gt;
&lt;li&gt;Copies the file into it with a timestamped name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example archive file: &lt;code&gt;20250911_213000_myfile.txt&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 5: Security &amp;amp; Permissions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logic App → Storage Account&lt;/strong&gt;: Assign &lt;strong&gt;Storage Blob Data Reader&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation Account → Storage Account&lt;/strong&gt;: Assign &lt;strong&gt;Storage Blob Data Contributor&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logic App → Automation Account&lt;/strong&gt;: Assign &lt;strong&gt;Automation Contributor&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable &lt;strong&gt;System-assigned Managed Identity&lt;/strong&gt; on both Logic App and Automation Account.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 6: Event Grid Integration
&lt;/h2&gt;

&lt;p&gt;Finally, wire up the trigger:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Source: &lt;strong&gt;Blob Created&lt;/strong&gt; in &lt;code&gt;input-files&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Event Schema: Event Grid Schema&lt;/li&gt;
&lt;li&gt;Endpoint: Logic App &lt;strong&gt;HTTP POST URL&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 7: Test the Workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Upload a test file to &lt;code&gt;input-files&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Watch Event Grid trigger the Logic App.&lt;/li&gt;
&lt;li&gt;Check App Service &lt;strong&gt;Log Stream&lt;/strong&gt; for processing logs.&lt;/li&gt;
&lt;li&gt;Verify the Automation Runbook created an archived copy in &lt;code&gt;processed-files&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Expected Outcome:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File uploaded → automatically processed → archived with timestamp.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔎 Troubleshooting Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logic App not triggering?&lt;/strong&gt; Check event subscription status.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Service errors?&lt;/strong&gt; Review Log Stream and verify connection strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation failures?&lt;/strong&gt; Confirm role assignments &amp;amp; module imports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permission errors?&lt;/strong&gt; Wait 5–10 minutes after role assignment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Benefits of This Architecture
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Coding Required&lt;/strong&gt; → All via Azure Portal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fully Automated&lt;/strong&gt; → Zero manual intervention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt; → Handles single or bulk uploads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt; → Managed identities, no secrets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost-Effective&lt;/strong&gt; → Pay-per-use pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitored&lt;/strong&gt; → Full visibility in Azure Portal&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💰 Cost Considerations (100 files/month)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Logic Apps: ~\$5–15&lt;/li&gt;
&lt;li&gt;App Service B1: ~\$13&lt;/li&gt;
&lt;li&gt;Storage: ~\$2–10&lt;/li&gt;
&lt;li&gt;Automation: First 500 min free&lt;/li&gt;
&lt;li&gt;Event Grid: First 100K ops free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Use &lt;strong&gt;Free App Service tier&lt;/strong&gt; during development.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps: Go Beyond the Portal
&lt;/h2&gt;

&lt;p&gt;Once comfortable with the portal, explore &lt;strong&gt;Infrastructure as Code&lt;/strong&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure CLI&lt;/strong&gt; → Automate deployments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ARM/Bicep&lt;/strong&gt; → Template-driven provisioning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terraform&lt;/strong&gt; → Cloud-agnostic automation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipelines&lt;/strong&gt; → Continuous deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az storage blob upload &lt;span class="nt"&gt;--account-name&lt;/span&gt; stworkflowdemo123456 &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--container-name&lt;/span&gt; input-files &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--name&lt;/span&gt; test.txt &lt;span class="nt"&gt;--file&lt;/span&gt; ./test.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;With just the Azure Portal, you’ve built a &lt;strong&gt;production-ready, event-driven file processing pipeline&lt;/strong&gt;. From file upload to automated archiving, every step happens seamlessly without manual effort.&lt;/p&gt;

&lt;p&gt;This foundation is perfect for learning, prototyping, and scaling into enterprise-grade solutions with Infrastructure as Code.&lt;/p&gt;

&lt;p&gt;Your Azure workflow is now ready to handle real-world file processing scenarios—securely, efficiently, and automatically.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Build a Simple Node.js Server from Scratch — A Step-by-Step Guide</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 20 Jul 2025 14:23:46 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-build-a-simple-nodejs-server-from-scratch-a-step-by-step-guide-5e5h</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-build-a-simple-nodejs-server-from-scratch-a-step-by-step-guide-5e5h</guid>
      <description>&lt;p&gt;Are you ready to create your first backend project with &lt;strong&gt;Node.js&lt;/strong&gt;? In this post, you’ll learn &lt;strong&gt;how to build a basic Node.js HTTP server&lt;/strong&gt; that handles different routes and sends back responses — all using &lt;strong&gt;core Node modules&lt;/strong&gt; (no frameworks like Express yet!).&lt;/p&gt;

&lt;p&gt;Let’s break it down step by step and explain exactly what’s happening behind the scenes. 💡&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Step 1: Set Up Your Project
&lt;/h2&gt;

&lt;p&gt;Before writing any code, we need a place to put 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="nb"&gt;mkdir &lt;/span&gt;my-nodejs-server
&lt;span class="nb"&gt;cd &lt;/span&gt;my-nodejs-server
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new project folder and initializes it with a default &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&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%2Fsnx3ozwuh2rjmy8fccmw.png" alt=" " width="800" height="206"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ✨ Step 2: Create Your Server File
&lt;/h2&gt;

&lt;p&gt;Now let’s create the file that will run your server:&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="nb"&gt;touch &lt;/span&gt;server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;server.js&lt;/code&gt; in your code editor (VS Code, Vim, or anything else you like).&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Step 3: Write Your First HTTP Server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 1. Import the HTTP Module
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&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="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This brings in Node.js’s built-in &lt;code&gt;http&lt;/code&gt; module, which lets us create web servers. No need to install anything extra!&lt;/p&gt;




&lt;h3&gt;
  
  
  🔹 2. Create the Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Request handler logic goes here&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;req&lt;/code&gt;: The &lt;strong&gt;request&lt;/strong&gt; object (contains details about the request — like the URL and method).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;res&lt;/code&gt;: The &lt;strong&gt;response&lt;/strong&gt; object (we’ll use this to send data back to the browser).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔹 3. Handle Routes
&lt;/h3&gt;

&lt;p&gt;Now let’s respond based on the URL path requested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, World! 🌍&lt;/span&gt;&lt;span class="se"&gt;\n&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;About Us 📖&lt;/span&gt;&lt;span class="se"&gt;\n&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Page Not Found 🚨&lt;/span&gt;&lt;span class="se"&gt;\n&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What’s happening here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We inspect &lt;code&gt;req.url&lt;/code&gt; to determine which page was requested.&lt;/li&gt;
&lt;li&gt;We respond with appropriate text for &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/about&lt;/code&gt;, or anything else (which returns a 404).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔹 4. Start Listening for Requests
&lt;/h3&gt;

&lt;p&gt;Finally, let’s make our server start listening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&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;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running at http://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/ 🎉`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;code&gt;127.0.0.1&lt;/code&gt; is your localhost IP.&lt;br&gt;
✅ &lt;code&gt;3000&lt;/code&gt; is the port where the server will run.&lt;br&gt;
✅ The callback confirms when the server is up.&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%2Fmip1don4vjvquqyu1jr5.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%2Fmip1don4vjvquqyu1jr5.png" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  📜 Full Code: &lt;code&gt;server.js&lt;/code&gt;
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&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="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, World! 🌍&lt;/span&gt;&lt;span class="se"&gt;\n&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;About Us 📖&lt;/span&gt;&lt;span class="se"&gt;\n&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Page Not Found 🚨&lt;/span&gt;&lt;span class="se"&gt;\n&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="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&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;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running at http://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/ 🎉`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚡ Step 4: Run and Test Your Server
&lt;/h2&gt;

&lt;p&gt;Start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open your browser and visit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;a href="http://127.0.0.1:3000/" rel="noopener noreferrer"&gt;http://127.0.0.1:3000/&lt;/a&gt; → Should show &lt;code&gt;Hello, World! 🌍&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;a href="http://127.0.0.1:3000/about" rel="noopener noreferrer"&gt;http://127.0.0.1:3000/about&lt;/a&gt; → Should show &lt;code&gt;About Us 📖&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;❌ &lt;a href="http://127.0.0.1:3000/contact" rel="noopener noreferrer"&gt;http://127.0.0.1:3000/contact&lt;/a&gt; → Should show &lt;code&gt;Page Not Found 🚨&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To stop the server, hit &lt;code&gt;Ctrl + C&lt;/code&gt; in your terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 How It All Works Behind the Scenes
&lt;/h2&gt;

&lt;p&gt;Here’s a simplified flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser sends a &lt;strong&gt;GET request&lt;/strong&gt; to your server.&lt;/li&gt;
&lt;li&gt;Node’s &lt;code&gt;http&lt;/code&gt; module captures it.&lt;/li&gt;
&lt;li&gt;Your code checks the requested route (&lt;code&gt;req.url&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;A response is built and returned with &lt;code&gt;res.end()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The browser receives and displays it.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛤️ Key Takeaways
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;req.url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The path the client is requesting (&lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/about&lt;/code&gt;, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;res.statusCode&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets HTTP status like 200 (OK) or 404 (Not Found)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;res.setHeader()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells the browser what type of content it’s getting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;res.end()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ends the response and sends it to the client&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🎉 Final Words
&lt;/h2&gt;

&lt;p&gt;You just built a fully functioning Node.js HTTP server with &lt;strong&gt;zero dependencies&lt;/strong&gt;. 🎉&lt;/p&gt;

&lt;p&gt;It’s a simple project — but a foundational one. From here, you can build more complex backend systems and eventually integrate databases, authentication, REST APIs, and beyond.&lt;/p&gt;

&lt;p&gt;Happy coding! 💻✨&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building and Deploying a MEAN Stack Application on Azure</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 20 Jul 2025 13:46:07 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/building-and-deploying-a-mean-stack-application-on-azure-31c6</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/building-and-deploying-a-mean-stack-application-on-azure-31c6</guid>
      <description>&lt;p&gt;As full-stack development continues to evolve, the MEAN stack has emerged as one of the most popular choices for building modern, scalable web applications. This blog post will walk you through a hands-on guide—from understanding the MEAN stack to deploying it on cloud platforms like Azure Virtual Machines.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 What is the MEAN Stack?
&lt;/h2&gt;

&lt;p&gt;The MEAN stack is a powerful, JavaScript-based framework that allows developers to build end-to-end web applications using a single language across the entire stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB&lt;/strong&gt;: A NoSQL database for storing data in JSON-like documents. It’s perfect for handling unstructured or semi-structured data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Express.js&lt;/strong&gt;: A fast and minimalist backend framework that simplifies building RESTful APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt;: A frontend framework for building single-page applications (SPAs), providing dynamic and rich user interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt;: A runtime environment for executing JavaScript server-side, enabling non-blocking, event-driven development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Use MEAN?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript Everywhere&lt;/strong&gt;: One language across the frontend, backend, and database layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Source&lt;/strong&gt;: Strong community support with free-to-use tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt;: Suitable for both small projects and enterprise-scale applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Ready&lt;/strong&gt;: Great for chat apps, live feeds, and collaborative tools.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ☁️ Deploying MEAN Stack on Azure or AWS
&lt;/h2&gt;

&lt;p&gt;Let’s break down the deployment process into manageable steps.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠 Step 1: Provision a Virtual Machine
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔷 Azure
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Virtual Machines &amp;gt; Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Ubuntu 22.04 LTS&lt;/strong&gt; as the OS.&lt;/li&gt;
&lt;li&gt;Select a size like &lt;strong&gt;B1s&lt;/strong&gt; for testing.&lt;/li&gt;
&lt;li&gt;Allow inbound ports: &lt;strong&gt;SSH (22)&lt;/strong&gt;, &lt;strong&gt;HTTP (80)&lt;/strong&gt;, and &lt;strong&gt;HTTPS (443)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Connect via SSH:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh azureuser@&amp;lt;public-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8upf9jvnqawtzv18gfjl.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%2F8upf9jvnqawtzv18gfjl.png" alt=" " width="800" height="372"&gt;&lt;/a&gt;&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%2F5gfts79oc6mut6zh5c6x.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%2F5gfts79oc6mut6zh5c6x.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ Step 2: Install MEAN Stack Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ✅ Update System &amp;amp; Install Dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git curl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🍃 Install MongoDB
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-qO&lt;/span&gt; - https://www.mongodb.org/static/pgp/server-6.0.asc | &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-key add -
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/mongodb-org-6.0.list
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; mongodb-org
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start mongod
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;mongod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fba2l5f3jbd9ifknde361.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%2Fba2l5f3jbd9ifknde361.png" alt=" " width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  🟩 Install Node.js and npm
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://deb.nodesource.com/setup_20.x | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; bash -
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧱 Step 3: Set Up the Express Backend
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;mean-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;mean-app
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express mongoose cors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;server.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&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="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&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;mongoose&lt;/span&gt; &lt;span class="o"&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="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&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;cors&lt;/span&gt; &lt;span class="o"&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="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongodb://localhost:27017/mean-db&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connected to MongoDB&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="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MongoDB connection error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MEAN Stack Backend Running!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fkvu5fzu6qxje0bwgd0ul.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%2Fkvu5fzu6qxje0bwgd0ul.png" alt=" " width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run with PM2:&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="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pm2
pm2 start server.js
pm2 save
pm2 startup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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%2Fzp3y2fyxr6obajwaxbcj.png" alt=" " width="800" height="492"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🧑‍🎨 Step 4: Deploy Angular Frontend
&lt;/h3&gt;

&lt;p&gt;Install Angular CLI:&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="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create and build the Angular project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng new frontend &lt;span class="nt"&gt;--defaults&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
ng build &lt;span class="nt"&gt;--configuration&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move build output to backend public directory:&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="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; dist/frontend/&lt;span class="k"&gt;*&lt;/span&gt; ../mean-app/public/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update &lt;code&gt;server.js&lt;/code&gt; to serve static files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this assignment, I chose not to use Nginx since I didn't have an available domain name.&lt;/p&gt;

&lt;p&gt;View the website on your browser here&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http:&amp;lt;public_ip&amp;gt;:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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%2Fdpcb3ml0z6nii172y0vl.png" alt=" " width="800" height="227"&gt;
&lt;/h2&gt;

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

&lt;p&gt;The MEAN stack is a great choice for modern full-stack applications thanks to its unified JavaScript ecosystem, flexibility, and scalability. Deploying your MEAN stack app on a cloud VM (like Azure or AWS) gives you full control over your infrastructure and allows you to scale as needed.&lt;/p&gt;

&lt;p&gt;Whether you're building a personal project or launching a production-grade system, mastering this deployment workflow will give you the confidence and skills to deliver high-performing web apps.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Secure Azure Storage with Customer-Managed Keys and Managed Identities</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Thu, 03 Jul 2025 21:32:02 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-secure-azure-storage-with-customer-managed-keys-and-managed-identities-932</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-secure-azure-storage-with-customer-managed-keys-and-managed-identities-932</guid>
      <description>&lt;p&gt;When building cloud-native applications, securing your storage resources is a top priority. Azure provides powerful tools like &lt;strong&gt;Managed Identities&lt;/strong&gt;, &lt;strong&gt;Key Vault&lt;/strong&gt;, &lt;strong&gt;Customer-Managed Keys (CMKs)&lt;/strong&gt;, and &lt;strong&gt;Immutable Storage&lt;/strong&gt; to help you do just that.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll walk through how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a storage account with infrastructure encryption&lt;/li&gt;
&lt;li&gt;Set up a managed identity and assign access&lt;/li&gt;
&lt;li&gt;Create a Key Vault with customer-managed keys&lt;/li&gt;
&lt;li&gt;Configure your storage account to use those keys&lt;/li&gt;
&lt;li&gt;Set up immutable blob storage and encryption scopes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ Step 1: Create the Storage Account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the Azure Portal, search for &lt;strong&gt;Storage accounts&lt;/strong&gt; and click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;new Resource Group&lt;/strong&gt;, name it accordingly.&lt;/li&gt;
&lt;li&gt;Provide a &lt;strong&gt;unique name&lt;/strong&gt; for your storage account.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;Encryption tab&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enable the checkbox for &lt;strong&gt;Infrastructure encryption&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ This cannot be changed after creation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt; the storage account.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h2&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%2Fgbl228ftplbjpz1d6sf5.png" alt="Image description" width="800" height="395"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Step 2: Create a User-Assigned Managed Identity
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the Azure Portal, search for &lt;strong&gt;Managed identities&lt;/strong&gt; and click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose the same &lt;strong&gt;Resource Group&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name your managed identity (e.g., &lt;code&gt;ezekielmanagedidentity&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fi7dri6s8p15nhdlzwn3g.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%2Fi7dri6s8p15nhdlzwn3g.png" alt="Image description" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Step 3: Assign Storage Permissions to the Managed Identity
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to your &lt;strong&gt;Storage Account &amp;gt; Access Control (IAM)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Add role assignment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Storage Blob Data Reader&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the &lt;strong&gt;Members&lt;/strong&gt; tab:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;strong&gt;Managed identity&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;User-assigned managed identity&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Pick the identity you created earlier

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Review + assign&lt;/strong&gt; (twice to confirm).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&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%2Fpbjoikdvogxudt0m1doz.png" alt="Image description" width="800" height="398"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Step 4: Give Yourself Key Vault Administrator Access
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Resource Group &amp;gt; Access Control (IAM)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Add role assignment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;Key Vault Administrator&lt;/strong&gt; role.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;User, group, or service principal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Pick your &lt;strong&gt;user account&lt;/strong&gt; from the list.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + assign&lt;/strong&gt; (twice).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fmycoqhqlabrswjoy1ckv.png" alt="Image description" width="800" height="389"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Step 5: Create a Key Vault and a Key
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the Azure Portal, search for &lt;strong&gt;Key vaults&lt;/strong&gt; and click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use your existing &lt;strong&gt;Resource Group&lt;/strong&gt; and give the vault a &lt;strong&gt;unique name&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On the &lt;strong&gt;Access Configuration&lt;/strong&gt; tab, ensure &lt;strong&gt;Azure role-based access control (recommended)&lt;/strong&gt; is selected.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;After deployment, click &lt;strong&gt;Go to resource&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Confirm that &lt;strong&gt;Soft-delete&lt;/strong&gt; and &lt;strong&gt;Purge protection&lt;/strong&gt; are enabled.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Keys&lt;/strong&gt;, click &lt;strong&gt;+ Generate/Import&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Provide a name, leave other settings as default, and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fay09o1eka923i32ddbx4.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%2Fay09o1eka923i32ddbx4.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2Fsnu0j5qcc6g7gbs8q9cq.png" alt="Image description" width="800" height="342"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Step 6: Grant Encryption Role to the Managed Identity
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to your &lt;strong&gt;Resource Group &amp;gt; Access Control (IAM)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Add role assignment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Key Vault Crypto Service Encryption User&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Managed identity&lt;/strong&gt;, then select your &lt;strong&gt;user-assigned identity&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + assign&lt;/strong&gt; (twice).&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  ✅ Step 7: Configure Customer-Managed Key on the Storage Account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go back to your &lt;strong&gt;Storage Account &amp;gt; Encryption&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Switch to &lt;strong&gt;Customer-managed keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select your &lt;strong&gt;Key Vault&lt;/strong&gt; and the &lt;strong&gt;key&lt;/strong&gt; you created earlier.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Identity type&lt;/strong&gt; to &lt;strong&gt;User-assigned&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select your &lt;strong&gt;managed identity&lt;/strong&gt; and click &lt;strong&gt;Add&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;🔁 If you get an error, wait a few minutes to let permissions propagate, then retry.&lt;/p&gt;
&lt;/blockquote&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%2Fdntp4sdc1glpfjqqyhxl.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%2Fdntp4sdc1glpfjqqyhxl.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Step 8: Configure Immutable Blob Storage
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your &lt;strong&gt;Storage Account &amp;gt; Containers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Container&lt;/strong&gt;, name it &lt;code&gt;hold&lt;/code&gt;, and create it with default settings.&lt;/li&gt;
&lt;li&gt;Upload a test file to the container.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; Access policy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Immutable blob storage&lt;/strong&gt;, click &lt;strong&gt;+ Add policy&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy type&lt;/strong&gt;: Time-based retention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retention period&lt;/strong&gt;: 5 days

&lt;ol&gt;
&lt;li&gt;Save the changes.&lt;/li&gt;
&lt;/ol&gt;
&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%2Fa1t4cibt7z4e9qs6u72r.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%2Fa1t4cibt7z4e9qs6u72r.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&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%2Fhlj3sf33hatj683fz7cn.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%2Fhlj3sf33hatj683fz7cn.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧪 Try deleting the file. You should get a &lt;strong&gt;deletion failed&lt;/strong&gt; error due to the policy.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  ✅ Step 9: Create an Encryption Scope with Infrastructure Encryption
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go back to your &lt;strong&gt;Storage Account &amp;gt; Encryption &amp;gt; Encryption scopes tab&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Add&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name your scope (e.g., &lt;code&gt;myezekielwncryptionscope&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Encryption type&lt;/strong&gt;: Microsoft-managed keys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure encryption&lt;/strong&gt;: Enabled

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&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%2Fh85z18020d2f3990pdxm.png" alt="Image description" width="800" height="399"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Step 10: Use the Encryption Scope in a New Container
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Return to your &lt;strong&gt;Storage Account &amp;gt; Containers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Container&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Provide a &lt;strong&gt;Name&lt;/strong&gt; and set &lt;strong&gt;Public access level&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Advanced&lt;/strong&gt;, choose the &lt;strong&gt;Encryption scope&lt;/strong&gt; you created.&lt;/li&gt;
&lt;li&gt;Create the container.&lt;/li&gt;
&lt;/ol&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%2Fq6b1hdaxdzqdxt8hbyy2.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%2Fq6b1hdaxdzqdxt8hbyy2.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Setting Up Azure File Share with Snapshots and Secure Access</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Thu, 03 Jul 2025 07:52:07 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/setting-up-azure-file-share-with-snapshots-and-secure-access-4mfa</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/setting-up-azure-file-share-with-snapshots-and-secure-access-4mfa</guid>
      <description>&lt;p&gt;Azure Files is a great solution when you need shared file storage in the cloud — just like a network file share, but hosted and managed by Azure. In this guide, I’ll walk you through how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;strong&gt;Premium Storage Account&lt;/strong&gt; for Azure Files&lt;/li&gt;
&lt;li&gt;Set up a &lt;strong&gt;File Share&lt;/strong&gt; with directories and uploaded files&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Snapshots&lt;/strong&gt; for recovery&lt;/li&gt;
&lt;li&gt;Restrict access using &lt;strong&gt;Virtual Networks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a perfect setup for teams like &lt;strong&gt;Finance&lt;/strong&gt;, who need secure, high-performance, and recoverable shared storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Step 1: Create the Azure Storage Account
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;Azure Portal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Search for and select &lt;strong&gt;Storage accounts&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;new resource group&lt;/strong&gt; (e.g., &lt;code&gt;storage-rg&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Enter a &lt;strong&gt;unique name&lt;/strong&gt; for the storage account (e.g., &lt;code&gt;ezekielstorageaccount&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Premium&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Premium account type&lt;/strong&gt;: File shares&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redundancy&lt;/strong&gt;: Zone-redundant storage (ZRS)

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;After deployment, click &lt;strong&gt;Go to resource&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ &lt;em&gt;Why Premium?&lt;/em&gt; Premium storage gives low-latency and high-throughput — perfect for file sharing.&lt;/p&gt;
&lt;/blockquote&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%2Frz5kw8ugzdl2ga9dkewt.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%2Frz5kw8ugzdl2ga9dkewt.png" alt="Image description" width="800" height="395"&gt;&lt;/a&gt;&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%2Ffz0bm6mf0lfn0u1akhpn.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%2Ffz0bm6mf0lfn0u1akhpn.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📁 Step 2: Create a File Share and Add Directory
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In your storage account, go to &lt;strong&gt;File shares&lt;/strong&gt; under &lt;strong&gt;Data storage&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ File share&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter a name like &lt;code&gt;ezekiel-file-share&lt;/code&gt; and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Once created, click the file share, then &lt;strong&gt;+ Add directory&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name the directory &lt;code&gt;finance&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 You can organize your file shares using folders, just like on a traditional file server.&lt;/p&gt;
&lt;/blockquote&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%2Fntpcfs14jnboigpclbxw.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%2Fntpcfs14jnboigpclbxw.png" alt="Image description" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2Fdey7hfplssawcfz616mo.png" alt="Image description" width="800" height="372"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  ⬆️ Step 3: Upload a File
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;code&gt;finance&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Upload&lt;/strong&gt; and choose any test file (e.g., a .txt or .pdf).&lt;/li&gt;
&lt;li&gt;Upload the file.&lt;/li&gt;
&lt;/ol&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%2Fur19aqfxyg1v3ja3bd90.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%2Fur19aqfxyg1v3ja3bd90.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, your file share has a folder and a test file — ready to be backed up and secured.&lt;/p&gt;




&lt;h2&gt;
  
  
  🕒 Step 4: Enable and Test Snapshots
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Snapshots&lt;/strong&gt; in Azure Files help you restore previous versions of files or recover deleted files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the file share → select the &lt;strong&gt;Snapshots&lt;/strong&gt; tab under &lt;strong&gt;Operations&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Add snapshot&lt;/strong&gt; → click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select the snapshot and ensure your &lt;code&gt;finance&lt;/code&gt; folder and file are included.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2F0fd070s4qekypzfeg8e8.png" alt="Image description" width="800" height="368"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🧪 Test Restoring a File from Snapshot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go back to your file share → open the &lt;code&gt;finance&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Delete the uploaded file (click the file → &lt;strong&gt;Delete&lt;/strong&gt; → &lt;strong&gt;Yes&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Return to the &lt;strong&gt;Snapshots&lt;/strong&gt; tab → open the snapshot.&lt;/li&gt;
&lt;li&gt;Navigate to the deleted file → click &lt;strong&gt;Restore&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Give it a &lt;strong&gt;new name&lt;/strong&gt; (e.g., &lt;code&gt;my-upload&lt;/code&gt;) and restore.&lt;/li&gt;
&lt;li&gt;Go back to your file share and confirm the restored file is there.&lt;/li&gt;
&lt;/ol&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%2Fz2plo59mpc1f4z2bx1sh.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%2Fz2plo59mpc1f4z2bx1sh.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&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%2Fl7jh2pwfjvdhb4m9h0rk.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%2Fl7jh2pwfjvdhb4m9h0rk.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📌 &lt;em&gt;Snapshots are point-in-time copies — great for protecting against accidental deletion.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔐 Step 5: Restrict Access Using Virtual Network
&lt;/h2&gt;

&lt;p&gt;Let’s now &lt;strong&gt;restrict access&lt;/strong&gt; so that only users within a specific &lt;strong&gt;virtual network (VNet)&lt;/strong&gt; can connect to this storage account.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌐 Create a Virtual Network
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the portal, search for &lt;strong&gt;Virtual networks&lt;/strong&gt; → click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use your storage account’s resource group.&lt;/li&gt;
&lt;li&gt;Name it something like &lt;code&gt;storage-vnet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fd0kozsfxunkxqfayirnq.png" alt="Image description" width="800" height="370"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔁 Add a Service Endpoint
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;After deployment, go to your &lt;strong&gt;VNet&lt;/strong&gt; → &lt;strong&gt;Subnets&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on the &lt;code&gt;default&lt;/code&gt; subnet.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Service endpoints&lt;/strong&gt;, select &lt;strong&gt;Microsoft.Storage&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This allows the VNet to securely connect to Azure Storage.&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%2Fwtobjs4xdcvo0qydjyaz.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%2Fwtobjs4xdcvo0qydjyaz.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🔒 Limit Access in the Storage Account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go back to your storage account → go to &lt;strong&gt;Networking&lt;/strong&gt; under &lt;strong&gt;Security + networking&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Public network access&lt;/strong&gt; to:
➤ &lt;em&gt;Enabled from selected virtual networks and IP addresses&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Virtual networks&lt;/strong&gt; section, click &lt;strong&gt;Add existing virtual network&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;storage-vnet&lt;/code&gt; and its default subnet → click &lt;strong&gt;Add&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Save your changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fjbhe5xjpo7jdvmc5jx75.png" alt="Image description" width="800" height="348"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🔍 Step 6: Test the Security
&lt;/h2&gt;

&lt;p&gt;Try accessing the file share from the &lt;strong&gt;Storage browser&lt;/strong&gt; in the portal. You should see an error like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ “Not authorized to perform this operation.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This confirms your restriction is working — access is allowed only from inside your VNet.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Here’s what we achieved:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storage Type&lt;/td&gt;
&lt;td&gt;Premium, ZRS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Share&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;corporate-share&lt;/code&gt; with &lt;code&gt;finance&lt;/code&gt; folder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upload File&lt;/td&gt;
&lt;td&gt;Test file uploaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshots&lt;/td&gt;
&lt;td&gt;Enabled and tested file recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VNet Restriction&lt;/td&gt;
&lt;td&gt;Access allowed only from &lt;code&gt;finance-vnet&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Recovery&lt;/td&gt;
&lt;td&gt;Manual restore from snapshot tested&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Azure Files is powerful when you want &lt;strong&gt;cloud-based shared folders&lt;/strong&gt; with &lt;strong&gt;backup&lt;/strong&gt;, &lt;strong&gt;access control&lt;/strong&gt;, and &lt;strong&gt;high availability&lt;/strong&gt; — all without managing servers. This setup is a great starting point for securely storing and managing corporate documents.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Set Up Azure Virtual Machines in Multiple Availability Zones (Manual Failover Scenario)</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Mon, 30 Jun 2025 12:19:03 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-set-up-azure-virtual-machines-in-multiple-availability-zones-manual-failover-scenario-374k</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-set-up-azure-virtual-machines-in-multiple-availability-zones-manual-failover-scenario-374k</guid>
      <description>&lt;p&gt;When running critical applications in the cloud, &lt;strong&gt;availability matters&lt;/strong&gt;. Azure provides &lt;strong&gt;Availability Zones (AZs)&lt;/strong&gt; to help protect your apps from data center failures. In this guide, I’ll walk you through setting up &lt;strong&gt;Virtual Machines (VMs)&lt;/strong&gt; in different zones — allowing for &lt;strong&gt;manual failover&lt;/strong&gt; if one zone goes down.&lt;/p&gt;

&lt;p&gt;This setup is great for learning how &lt;strong&gt;high availability&lt;/strong&gt; and &lt;strong&gt;disaster recovery&lt;/strong&gt; work at the infrastructure level.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌍 What Are Availability Zones?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Availability Zones&lt;/strong&gt; are physically separate locations within an Azure region. Each zone has its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Power&lt;/li&gt;
&lt;li&gt;Cooling&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deploying VMs across zones ensures that even if one zone goes down, your app can recover from another — though in &lt;strong&gt;manual failover&lt;/strong&gt;, you must redirect traffic or services yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧰 What You'll Do in This Guide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploy &lt;strong&gt;2 Virtual Machines&lt;/strong&gt; across different AZs using VMSS&lt;/li&gt;
&lt;li&gt;Test the setup&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🖥 Step 1: Create Virtual Machines in Different AZs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  VM 1 (Primary)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Virtual Machines&lt;/strong&gt; → &lt;strong&gt;+ Create&lt;/strong&gt; → &lt;strong&gt;Virtual Machine Scale Set&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;win11vm-1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Region: Same as your VNet&lt;/li&gt;
&lt;li&gt;Availability Zone: &lt;strong&gt;Zone 1&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose image (e.g., Win11)&lt;/li&gt;
&lt;li&gt;Size: Standard B2s (for demo purposes)&lt;/li&gt;
&lt;li&gt;Add to the &lt;code&gt;failover-vnet&lt;/code&gt; network&lt;/li&gt;
&lt;li&gt;Allow RDP/SSH depending on OS&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This Virtual Machine Scale Set gives you one VM in Zone 1 and another in Zone 2.&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%2Fxm1u21aio3y3vvp9ze9p.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%2Fxm1u21aio3y3vvp9ze9p.png" alt="Image description" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Step 3: Test Both VMs
&lt;/h2&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%2F7lxmoqf61gl2dw74a90e.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%2F7lxmoqf61gl2dw74a90e.png" alt="Image description" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Machine 1
&lt;/h2&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%2Fc1oe6yffohyh9irjjqzn.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%2Fc1oe6yffohyh9irjjqzn.png" alt="Image description" width="800" height="375"&gt;&lt;/a&gt;&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%2Fiuz1t1wekaticagpm6vr.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%2Fiuz1t1wekaticagpm6vr.png" alt="Image description" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Machine 2
&lt;/h2&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%2F8j1n4zhl5a1f2xfgliub.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%2F8j1n4zhl5a1f2xfgliub.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&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%2Fe2tc2w63gkjw109zjmcx.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%2Fe2tc2w63gkjw109zjmcx.png" alt="Image description" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;East US (or any region with AZs)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual Failover&lt;/td&gt;
&lt;td&gt;No Load Balancer present&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📝 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Using Azure Availability Zones gives your infrastructure &lt;strong&gt;resilience&lt;/strong&gt; against unexpected failures. In this lab-style setup, we used &lt;strong&gt;manual failover&lt;/strong&gt; — a realistic way to understand what happens when one part of your system becomes unavailable.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Store Private Files in Azure Blob Storage</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 29 Jun 2025 23:25:45 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-store-public-and-private-files-in-azure-blob-storage-1m9d</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-store-public-and-private-files-in-azure-blob-storage-1m9d</guid>
      <description>&lt;p&gt;How to Store Private Files in Azure Blob Storage&lt;/p&gt;

&lt;p&gt;Azure Blob Storage is a great way to host both public website content and private company files. In this post, I’ll guide you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding safety features like &lt;strong&gt;soft delete&lt;/strong&gt; and &lt;strong&gt;versioning&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Creating a &lt;strong&gt;private storage account&lt;/strong&gt; for sensitive documents&lt;/li&gt;
&lt;li&gt;Giving &lt;strong&gt;temporary access&lt;/strong&gt; using SAS (Shared Access Signatures)&lt;/li&gt;
&lt;li&gt;Using &lt;strong&gt;lifecycle rules&lt;/strong&gt; to manage storage costs&lt;/li&gt;
&lt;li&gt;Setting up &lt;strong&gt;replication&lt;/strong&gt; to back up files from one storage account to another&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;




&lt;h2&gt;
  
  
  ☁️ Part 1: Set Up a Public Storage Account
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔧 Step 1: Create the Storage Account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the &lt;strong&gt;&lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Search for &lt;strong&gt;"Storage accounts"&lt;/strong&gt; and click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;new resource group&lt;/strong&gt; (e.g., &lt;code&gt;storage-rg&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Name your account something like &lt;code&gt;privatewebsitemyezekiel&lt;/code&gt; (the name must be globally unique).&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🔐 Part 2: Store Internal Documents in a Private Container
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔧 Step 1: Create the Private Storage Account
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create another storage account (e.g., &lt;code&gt;privatewebsitemyezekiel&lt;/code&gt;) in the same resource group.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fhcrqi4fwo1h1mrs456oe.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%2Fhcrqi4fwo1h1mrs456oe.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🌐 Step 2: Enable Geo-Redundant Storage (GRS Only)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the storage account, go to &lt;strong&gt;Redundancy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Geo-redundant storage (GRS)&lt;/strong&gt; — no read access needed.&lt;/li&gt;
&lt;li&gt;Save the setting.&lt;/li&gt;
&lt;/ol&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%2F62o66mqjunkg7skrz23k.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%2F62o66mqjunkg7skrz23k.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  📁 Step 3: Create a Private Container
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Containers&lt;/strong&gt; → click &lt;strong&gt;+ Container&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;private&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Public access level&lt;/strong&gt; to &lt;strong&gt;Private (no anonymous access)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2F7c5kusajogeyp76elx6x.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%2F7c5kusajogeyp76elx6x.png" alt="Image description" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🚫 Step 4: Test That the File Is Not Public
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Upload a small file.&lt;/li&gt;
&lt;li&gt;Copy the Blob URL and try to open it in a browser — it should not open.&lt;/li&gt;
&lt;/ol&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%2F0m0if63a6qog3wdkc7ql.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%2F0m0if63a6qog3wdkc7ql.png" alt="Image description" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🔐 Step 5: Grant Temporary Access with SAS
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click on the uploaded file → go to the &lt;strong&gt;Generate SAS&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Grant &lt;strong&gt;Read&lt;/strong&gt; permission.&lt;/li&gt;
&lt;li&gt;Set an &lt;strong&gt;expiry&lt;/strong&gt; of 24 hours.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Generate SAS token and URL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open the URL in a browser to test.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ The file should now load only with this link.&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%2Farg4avx90tv1638hm89z.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%2Farg4avx90tv1638hm89z.png" alt="Image description" width="800" height="368"&gt;&lt;/a&gt;&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%2Fegaciknb8xnpekfa81py.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%2Fegaciknb8xnpekfa81py.png" alt="Image description" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧊 Step 6: Use Lifecycle Rules to Save Costs
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Lifecycle management&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add rule&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;movetocool&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Apply to all blobs → set rule to &lt;strong&gt;"Last modified more than 30 days"&lt;/strong&gt; → &lt;strong&gt;Move to cool tier&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Save the rule.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&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%2Fk2btnxpyceswnuixe4nc.png" alt="Image description" width="800" height="370"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔁 Step 7: Backup Public Files with Replication
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;strong&gt;private&lt;/strong&gt; storage account, create a new container named &lt;code&gt;backup&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;public&lt;/strong&gt; storage account → &lt;strong&gt;Object replication&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Create a replication rule:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Destination account&lt;/strong&gt;: private storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source container&lt;/strong&gt;: &lt;code&gt;public&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination container&lt;/strong&gt;: &lt;code&gt;backup&lt;/code&gt;

&lt;ol&gt;
&lt;li&gt;Upload a file to &lt;code&gt;public&lt;/code&gt;, and it will appear in &lt;code&gt;backup&lt;/code&gt; after a few minutes.&lt;/li&gt;
&lt;/ol&gt;
&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%2Fxf84h696dlib4bp542t5.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%2Fxf84h696dlib4bp542t5.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&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%2Fwqijqx53cupr4mhqryx8.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%2Fwqijqx53cupr4mhqryx8.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&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%2Fq362smi0a4pdqr86sn3m.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%2Fq362smi0a4pdqr86sn3m.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&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%2Ftji6g2q8cf7hsbp5uxj9.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%2Ftji6g2q8cf7hsbp5uxj9.png" alt="Image description" width="800" height="376"&gt;&lt;/a&gt;&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%2F24x9ra3ffvcj1uagtraz.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%2F24x9ra3ffvcj1uagtraz.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;Here’s what we’ve accomplished:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Public Account&lt;/th&gt;
&lt;th&gt;Private Account&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;High Availability&lt;/td&gt;
&lt;td&gt;RA-GRS&lt;/td&gt;
&lt;td&gt;GRS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anonymous Access&lt;/td&gt;
&lt;td&gt;Enabled&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Soft Delete&lt;/td&gt;
&lt;td&gt;Enabled (21 days)&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blob Versioning&lt;/td&gt;
&lt;td&gt;Enabled&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SAS Access&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;td&gt;Used for secure sharing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifecycle Management&lt;/td&gt;
&lt;td&gt;Move to cool after 30 days&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replication&lt;/td&gt;
&lt;td&gt;From public to backup&lt;/td&gt;
&lt;td&gt;As destination only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This setup ensures that &lt;strong&gt;public content is easily accessible&lt;/strong&gt; and &lt;strong&gt;private files are secure&lt;/strong&gt;, while still keeping your storage &lt;strong&gt;cost-effective&lt;/strong&gt; and &lt;strong&gt;recoverable&lt;/strong&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Set Up a High-Availability Azure Storage Account for a Public Website</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 29 Jun 2025 21:11:59 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-set-up-a-high-availability-azure-storage-account-for-a-public-website-4kkj</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-to-set-up-a-high-availability-azure-storage-account-for-a-public-website-4kkj</guid>
      <description>&lt;p&gt;If you’re hosting static content like images, website files, or documents, Azure Storage is a reliable, cost-effective solution. In this guide, I’ll show you how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;strong&gt;high-availability Azure storage account&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;public blob access&lt;/strong&gt; for website users&lt;/li&gt;
&lt;li&gt;Configure &lt;strong&gt;soft delete&lt;/strong&gt; and &lt;strong&gt;versioning&lt;/strong&gt; to protect your files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s get started.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Step 1: Create the Storage Account
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open the &lt;strong&gt;&lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the search bar, type and select &lt;strong&gt;“Storage accounts”&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;Resource group&lt;/strong&gt;, click &lt;strong&gt;Create new&lt;/strong&gt;, enter a name like &lt;code&gt;storage-rg&lt;/code&gt;, and click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name the storage account &lt;code&gt;publicwebsitemyezekiel&lt;/code&gt; (add random characters to make it globally unique).&lt;/li&gt;
&lt;li&gt;Keep other settings as default.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fahtvb06x05odkgxyx73a.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%2Fahtvb06x05odkgxyx73a.png" alt="Image description" width="800" height="374"&gt;&lt;/a&gt;&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%2Fr7hypbl097rys8ar3qha.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%2Fr7hypbl097rys8ar3qha.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 Step 2: Enable Read-Access Geo-Redundant Storage (RA-GRS)
&lt;/h2&gt;

&lt;p&gt;After deployment, go to the newly created storage account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;strong&gt;Data management&lt;/strong&gt; section, click &lt;strong&gt;Redundancy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Read-access geo-redundant storage (RA-GRS)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Review the &lt;strong&gt;Primary&lt;/strong&gt; and &lt;strong&gt;Secondary region&lt;/strong&gt; info.&lt;/li&gt;
&lt;/ol&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%2F1iqw6eiwtz6xpfe3nac9.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%2F1iqw6eiwtz6xpfe3nac9.png" alt="Image description" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🔓 Step 3: Allow Anonymous Access
&lt;/h2&gt;

&lt;p&gt;To make your content accessible to everyone:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;strong&gt;Settings&lt;/strong&gt; section, select &lt;strong&gt;Configuration&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Allow blob anonymous access&lt;/strong&gt; to &lt;strong&gt;Enabled&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Frw69h0hkxhbyx9zgv12f.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%2Frw69h0hkxhbyx9zgv12f.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📁 Step 4: Create a Container for Website Files
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Containers&lt;/strong&gt; under &lt;strong&gt;Data storage&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;+ Container&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;public&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select the new &lt;code&gt;public&lt;/code&gt; container.&lt;/li&gt;
&lt;li&gt;On the &lt;strong&gt;Overview&lt;/strong&gt; tab, click &lt;strong&gt;Change access level&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Set it to &lt;strong&gt;Blob (anonymous read access for blobs only)&lt;/strong&gt;, then &lt;strong&gt;OK&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fegaf9wyri22dkf8kxzg4.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%2Fegaf9wyri22dkf8kxzg4.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⬆️ Step 5: Upload and Test a File
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Inside the &lt;code&gt;public&lt;/code&gt; container, click &lt;strong&gt;Upload&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select any small file (like an image or text file) from your computer.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Upload&lt;/strong&gt;, then &lt;strong&gt;Refresh&lt;/strong&gt; to see your file.&lt;/li&gt;
&lt;li&gt;Click on the file → &lt;strong&gt;Overview tab&lt;/strong&gt; → copy the &lt;strong&gt;URL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Paste the URL in a browser tab.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Image files will display; others (e.g. &lt;code&gt;.txt&lt;/code&gt;, &lt;code&gt;.pdf&lt;/code&gt;) will download.&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%2F0lgq3jx3d3y4v3333dqp.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%2F0lgq3jx3d3y4v3333dqp.png" alt="Image description" width="800" height="365"&gt;&lt;/a&gt;&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%2Fxi1viyc45myc5m1egc82.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%2Fxi1viyc45myc5m1egc82.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&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%2Fbeemb1hvfnxjvpw5hpcf.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%2Fbeemb1hvfnxjvpw5hpcf.png" alt="Image description" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ♻️ Step 6: Enable Soft Delete (21 Days)
&lt;/h2&gt;

&lt;p&gt;This helps recover deleted files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the storage account’s &lt;strong&gt;Overview&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Blob service&lt;/strong&gt;, click &lt;strong&gt;Soft delete&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enable the setting.&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Keep deleted blobs for&lt;/strong&gt; to &lt;strong&gt;21 days&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2Fg47xvdlnlnt4o2ayug93.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%2Fg47xvdlnlnt4o2ayug93.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Step 7: Test Soft Delete and Restore
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Return to your container, select the file, and click &lt;strong&gt;Delete&lt;/strong&gt; → Confirm.&lt;/li&gt;
&lt;li&gt;On the container page, toggle &lt;strong&gt;Show deleted blobs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Find your deleted file → Click &lt;strong&gt;...&lt;/strong&gt; → &lt;strong&gt;Undelete&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Refresh the page to confirm it's restored.&lt;/li&gt;
&lt;/ol&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%2F3lwgr2hhpc3nr6fiwfnf.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%2F3lwgr2hhpc3nr6fiwfnf.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&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%2Fwbn9sgmbxy55ohtyjwre.png" alt="Image description" width="800" height="367"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🔄 Step 8: Enable Blob Versioning
&lt;/h2&gt;

&lt;p&gt;To keep a history of changes to files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go back to the storage account &lt;strong&gt;Overview&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Blob service&lt;/strong&gt;, click &lt;strong&gt;Versioning&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Versioning for blobs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&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%2F2c7lptn8eie32kvqor02.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%2F2c7lptn8eie32kvqor02.png" alt="Image description" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⏪ Step 9: Test Blob Versioning
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Upload a new version of the same file (same name) to overwrite it.&lt;/li&gt;
&lt;li&gt;Toggle &lt;strong&gt;Show deleted blobs&lt;/strong&gt; — you’ll see the previous version listed.&lt;/li&gt;
&lt;/ol&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%2Fuge29ir8swnvap9u4h50.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%2Fuge29ir8swnvap9u4h50.png" alt="Image description" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;By following this guide, you’ve successfully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up a &lt;strong&gt;highly available storage account&lt;/strong&gt; with RA-GRS&lt;/li&gt;
&lt;li&gt;Enabled &lt;strong&gt;anonymous blob access&lt;/strong&gt; for public use&lt;/li&gt;
&lt;li&gt;Configured &lt;strong&gt;soft delete&lt;/strong&gt; to prevent data loss&lt;/li&gt;
&lt;li&gt;Turned on &lt;strong&gt;versioning&lt;/strong&gt; to track file history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup is perfect for hosting static website content, images, downloads, and more — with built-in protection and global availability.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How I Created a Linux VM on Azure and Installed NGINX</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 29 Jun 2025 13:23:35 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-i-created-a-linux-vm-on-azure-and-installed-nginx-40no</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-i-created-a-linux-vm-on-azure-and-installed-nginx-40no</guid>
      <description>&lt;p&gt;As part of my ongoing cloud computing training, I was tasked with deploying a Linux virtual machine (VM) on Microsoft Azure and installing NGINX web server on it. Below is a breakdown of the entire process — from creating the VM to accessing the NGINX welcome page.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Log into the Azure Portal
&lt;/h3&gt;

&lt;p&gt;I started by logging into &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;https://portal.azure.com&lt;/a&gt; using my Microsoft account.&lt;/p&gt;

&lt;blockquote&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%2Fwjiuyjsov0sp0t796pqq.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%2Fwjiuyjsov0sp0t796pqq.png" alt="Image description" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 2: Search for “Virtual Machines”
&lt;/h3&gt;

&lt;p&gt;In the Azure Portal, I used the &lt;strong&gt;search bar&lt;/strong&gt; at the top to search for &lt;strong&gt;“Virtual Machines”&lt;/strong&gt; and selected it from the dropdown menu.&lt;/p&gt;

&lt;h2&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%2F2vawxtux4mo3zuer3ui1.png" alt="Image description" width="800" height="399"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 3: Create a Linux VM
&lt;/h3&gt;

&lt;p&gt;I clicked the &lt;strong&gt;“+ Create”&lt;/strong&gt; button and selected &lt;strong&gt;“Azure virtual machine.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Basics tab&lt;/strong&gt;, I entered the following configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subscription&lt;/strong&gt;: My current Azure subscription&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Group&lt;/strong&gt;: Selected an existing one or created a new one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Machine Name&lt;/strong&gt;: &lt;code&gt;linux-nginx-vm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region&lt;/strong&gt;: Chose the closest Azure region&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: Selected &lt;strong&gt;Ubuntu 22.04 LTS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: Chose a lightweight option like &lt;code&gt;Standard_B1s&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication type&lt;/strong&gt;: Selected &lt;strong&gt;Password&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username&lt;/strong&gt; and &lt;strong&gt;Password&lt;/strong&gt;: Set my SSH login credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Make sure to &lt;strong&gt;allow port 22 (SSH)&lt;/strong&gt; under the &lt;strong&gt;Inbound port rules&lt;/strong&gt; so you can connect to the VM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 4: Review + Create
&lt;/h3&gt;

&lt;p&gt;After confirming the settings, I clicked &lt;strong&gt;“Review + Create”&lt;/strong&gt;, waited for validation to complete, and then clicked &lt;strong&gt;“Create.”&lt;/strong&gt; Azure started provisioning the VM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Connect to the Linux VM via SSH
&lt;/h3&gt;

&lt;p&gt;Once the VM was deployed, I connected using SSH.&lt;/p&gt;

&lt;p&gt;I copied the &lt;strong&gt;public IP address&lt;/strong&gt; from the VM overview and ran the following command from my terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &amp;lt;username&amp;gt;@&amp;lt;public-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It prompted for my password, and then I was successfully logged into the Linux VM.&lt;/p&gt;

&lt;blockquote&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%2F888gjjzbcal9alxb3x7e.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%2F888gjjzbcal9alxb3x7e.png" alt="Image description" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 6: Install NGINX on the Linux VM
&lt;/h3&gt;

&lt;p&gt;After logging in, I ran the following commands to install NGINX:&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="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once installed, I confirmed the status of NGINX:&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="nb"&gt;sudo &lt;/span&gt;systemctl status nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output showed that NGINX was &lt;strong&gt;active (running)&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&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%2F79yaqr6q3c9wa7jvec95.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%2F79yaqr6q3c9wa7jvec95.png" alt="Image description" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 7: View the NGINX Welcome Page
&lt;/h3&gt;

&lt;p&gt;To access the default NGINX web page, I opened a browser and visited:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;public-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The NGINX welcome page appeared, which means the installation was successful.&lt;/p&gt;

&lt;blockquote&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%2Ft66jgzkijtomv5gdl8o9.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%2Ft66jgzkijtomv5gdl8o9.png" alt="Image description" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Logged into Azure Portal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Created a new Ubuntu VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Connected via SSH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Installed NGINX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Verified using the public IP in a browser&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Lessons Learned
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How to provision a Linux VM in Azure&lt;/li&gt;
&lt;li&gt;How to connect to a Linux VM using SSH&lt;/li&gt;
&lt;li&gt;How to install and start NGINX using basic terminal commands&lt;/li&gt;
&lt;li&gt;The role of &lt;strong&gt;inbound port rules&lt;/strong&gt; in exposing services like NGINX&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>How I Deployed a Windows 11 Virtual Machine on Azure</title>
      <dc:creator>Ezekiel Umesi</dc:creator>
      <pubDate>Sun, 29 Jun 2025 12:51:24 +0000</pubDate>
      <link>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-i-deployed-a-windows-11-virtual-machine-on-azure-1ehn</link>
      <guid>https://dev.to/ezekiel_umesi_5bd2fa6069c/how-i-deployed-a-windows-11-virtual-machine-on-azure-1ehn</guid>
      <description>&lt;p&gt;As part of my cloud computing class, we were tasked with creating and deploying a Windows 11 virtual machine (VM) using the Azure portal. This guide walks you through the steps I followed to get it done — no coding involved, just pure cloud interface configuration!&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Login to Azure Portal
&lt;/h3&gt;

&lt;p&gt;I started by visiting the Azure Portal at &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;https://portal.azure.com&lt;/a&gt; and logging in with my Microsoft account. This is where all Azure resources are created and managed.&lt;/p&gt;

&lt;blockquote&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%2Fyea6jywolmeizzwb3byz.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%2Fyea6jywolmeizzwb3byz.png" alt="Image description" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 2: Search for “Virtual Machines”
&lt;/h3&gt;

&lt;p&gt;On the Azure dashboard, I used the &lt;strong&gt;search bar&lt;/strong&gt; at the top and typed &lt;strong&gt;“Virtual Machines.”&lt;/strong&gt; I clicked on the &lt;strong&gt;Virtual Machines&lt;/strong&gt; option that appeared in the search results.&lt;/p&gt;

&lt;blockquote&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%2F3o7k2sj91dwtc7f2dbkj.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%2F3o7k2sj91dwtc7f2dbkj.png" alt="Image description" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 3: Create a New VM
&lt;/h3&gt;

&lt;p&gt;I clicked the &lt;strong&gt;“+ Create”&lt;/strong&gt; button and selected &lt;strong&gt;“Azure virtual machine”&lt;/strong&gt;. This opened a setup wizard to configure the virtual machine.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📸 &lt;em&gt;[Insert screenshot of the Create VM form]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 4: Configure the Basic Settings
&lt;/h3&gt;

&lt;p&gt;Here's what I entered in the &lt;strong&gt;Basics&lt;/strong&gt; tab:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subscription&lt;/strong&gt;: "Subscription 1"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Group&lt;/strong&gt;: "cloud101-rg"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Machine Name&lt;/strong&gt;: I used &lt;code&gt;win11-vm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region&lt;/strong&gt;: I picked a region closest to me, like &lt;code&gt;East US&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: I selected &lt;strong&gt;Windows 11 Pro, version 22H2 - Gen2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: I went with a VM size that meets the minimum requirements for Windows 11 (e.g., &lt;code&gt;Standard_D2s_v3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Administrator Account&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: A name I could remember&lt;/li&gt;
&lt;li&gt;Password: A strong, secure password&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;em&gt;Note: Windows 11 requires TPM and Secure Boot — that’s why only Gen2 VM images are supported.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 5: Configure Networking
&lt;/h3&gt;

&lt;p&gt;I left most settings on default, but made sure that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public IP&lt;/strong&gt; was enabled so I could RDP into the machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port 3389&lt;/strong&gt; (for Remote Desktop) was open&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 6: Review + Create
&lt;/h3&gt;

&lt;p&gt;After going through all the required tabs (leaving the rest at default values), I clicked on &lt;strong&gt;“Review + Create”&lt;/strong&gt;. Once Azure validated my settings, I clicked &lt;strong&gt;“Create.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure began provisioning the VM. After a few minutes, the Windows 11 VM was ready to use.&lt;/p&gt;

&lt;h2&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%2Fkwu73uqy0f9pkqr1o8ot.png" alt="Image description" width="800" height="397"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 7: Connect to the Windows 11 VM
&lt;/h3&gt;

&lt;p&gt;Once the deployment was complete, I:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigated to the VM page&lt;/li&gt;
&lt;li&gt;Clicked on &lt;strong&gt;Connect &amp;gt; RDP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Downloaded the RDP file&lt;/li&gt;
&lt;li&gt;Opened the file and logged in using the username and password I created earlier&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&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%2Fbj8l9x201iqfzxzixp84.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%2Fbj8l9x201iqfzxzixp84.png" alt="Image description" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&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%2Fg478rhk442w646gvmwg3.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%2Fg478rhk442w646gvmwg3.png" alt="Image description" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;How to select and configure a Windows 11 image in Azure&lt;/li&gt;
&lt;li&gt;The importance of Gen2 VM requirements (TPM, Secure Boot)&lt;/li&gt;
&lt;li&gt;How to expose the correct ports to connect to a VM securely&lt;/li&gt;
&lt;li&gt;How Azure handles provisioning, networking, and remote access&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Summary of Key Steps
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Logged into Azure Portal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Searched for Virtual Machines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Clicked Create and chose Windows 11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Configured basic settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Enabled networking with RDP access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Reviewed and created the VM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Connected using Remote Desktop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
    </item>
  </channel>
</rss>
