<?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: manny300</title>
    <description>The latest articles on DEV Community by manny300 (@manny300).</description>
    <link>https://dev.to/manny300</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%2F787659%2F6c3da68e-1c2c-42f3-a42b-885328ad64d9.jpg</url>
      <title>DEV Community: manny300</title>
      <link>https://dev.to/manny300</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manny300"/>
    <language>en</language>
    <item>
      <title>How to Automate Azure Resource Group Creation with a Bash Script</title>
      <dc:creator>manny300</dc:creator>
      <pubDate>Mon, 08 Jun 2026 18:17:27 +0000</pubDate>
      <link>https://dev.to/manny300/how-to-automate-azure-resource-group-creation-with-a-bash-script-8jk</link>
      <guid>https://dev.to/manny300/how-to-automate-azure-resource-group-creation-with-a-bash-script-8jk</guid>
      <description>&lt;p&gt;If you are just getting started with Azure CLI and Bash scripting, this post is for you. I will walk you through how I automated the creation of Azure resource groups for multiple environments using a single Bash script — something that was taking a cloud admin several manual steps every week.&lt;/p&gt;

&lt;p&gt;This is Project 2 in my TechRush Cloud Engineering bootcamp series. If you want to see where this journey started, you can read my previous post where I tackled &lt;a href="https://dev.to/manny300/from-zero-to-multi-region-my-experience-deploying-on-azure-for-the-first-time-cj3"&gt;deploying a web app across two Azure regions for the first time&lt;/a&gt;. That project involved real blockers — quota limits, CLI version mismatches, and a deep dive into Azure Resource Providers. This one went smoother, and I think that is because the previous project was the hard school.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Imagine a cloud administrator who has to create five resource groups every single week, one for each active project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project-A-RG
Project-B-RG
Project-C-RG
Project-D-RG
Project-E-RG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every week. By hand. Management's response was simple: automate it.&lt;/p&gt;

&lt;p&gt;But here is where the task gets more interesting. Instead of creating one flat resource group per project, the better approach is to create &lt;strong&gt;four resource groups per project&lt;/strong&gt; — one for each environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dev&lt;/li&gt;
&lt;li&gt;Test&lt;/li&gt;
&lt;li&gt;UAT&lt;/li&gt;
&lt;li&gt;Production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because each environment needs its own access controls, cost tracking, and lifecycle rules. You do not want your Development environment sharing a resource group with Production. Keeping them separate is a real-world cloud best practice, not just a bootcamp exercise.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Will Need
&lt;/h2&gt;

&lt;p&gt;Before running this script, make sure you have the following set up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure CLI installed&lt;/strong&gt; on your local machine. You can follow the &lt;a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" rel="noopener noreferrer"&gt;official installation guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An active Azure account&lt;/strong&gt;. A free account works fine for this.&lt;/li&gt;
&lt;li&gt;A terminal that runs Bash — Linux, macOS, or WSL on Windows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Understanding the Design
&lt;/h2&gt;

&lt;p&gt;The core idea behind this script is &lt;strong&gt;parameterization&lt;/strong&gt;. Instead of hardcoding project names, the script accepts a project name as input and uses it as a prefix for every resource group it creates.&lt;/p&gt;

&lt;p&gt;So if you enter &lt;code&gt;Project-A&lt;/code&gt;, you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project-A-RG-Dev
Project-A-RG-Test
Project-A-RG-UAT
Project-A-RG-Production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next week, you run the same script, enter &lt;code&gt;Project-B&lt;/code&gt;, and get the same structure with a different prefix. The script never changes. Only the input does.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;RG&lt;/code&gt; in the middle is there to make the resource type clear at a glance. When you are looking at a list of twenty Azure resources, names that include what the resource is save you a lot of time.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;deploy.sh&lt;/code&gt; and paste the following:&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="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# Check if the user is logged into Azure&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; az account show &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Not logged in. Run 'az login' first."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Prompt the user for a project name&lt;/span&gt;
&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Enter Project Name: "&lt;/span&gt; ProjectName

&lt;span class="c"&gt;# Validate that the input is not empty&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Project Name cannot be empty."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Inform the user that resource group creation is starting&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Creating resource groups for &lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;

&lt;span class="c"&gt;# Create one resource group per environment&lt;/span&gt;
az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-Dev"&lt;/span&gt;        &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;
az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-Test"&lt;/span&gt;       &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;
az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-UAT"&lt;/span&gt;        &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;
az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-Production"&lt;/span&gt; &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Resource groups created successfully."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now make the script executable:&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;chmod&lt;/span&gt; +x deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run it:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Walking Through the Script
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Login check&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; az account show &amp;amp;&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The very first thing the script does is check whether you are already logged into Azure. If you are not, it stops immediately and tells you exactly what to do. This is called a &lt;strong&gt;guard clause&lt;/strong&gt; — you check your preconditions before doing any real work. It prevents confusing errors further down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input prompt&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Enter Project Name: "&lt;/span&gt; ProjectName
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;read&lt;/code&gt; command pauses the script and waits for you to type something. Whatever you type gets stored in the variable &lt;code&gt;ProjectName&lt;/code&gt;. The &lt;code&gt;-p&lt;/code&gt; flag lets you show a prompt message at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Empty input validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user just presses Enter without typing anything, &lt;code&gt;ProjectName&lt;/code&gt; will be empty. Without this check, the script would go ahead and try to create resource groups with names like &lt;code&gt;-RG-Dev&lt;/code&gt;, which is not useful to anyone. This check catches that and exits cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource group creation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-Dev"&lt;/span&gt; &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the Azure CLI command that does the actual work. The &lt;code&gt;--name&lt;/code&gt; flag uses string interpolation to combine the variable with the environment suffix. The &lt;code&gt;--location&lt;/code&gt; flag tells Azure which region to deploy to. You can change &lt;code&gt;eastus&lt;/code&gt; to any region that is available on your subscription.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Result Looks Like
&lt;/h2&gt;

&lt;p&gt;After running the script with &lt;code&gt;FI_deparment&lt;/code&gt; as the project name (from the actual assignment run), the Azure portal showed the following resource groups created successfully:&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%2Fecfecnj26gboi2ie60nk.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%2Fecfecnj26gboi2ie60nk.png" alt="Azure portal showing four resource groups: FI_deparment-RG-Dev, FI_deparment-RG-Test, FI_deparment-RG-UAT, FI_deparment-RG-Production"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Would Improve in a v2
&lt;/h2&gt;

&lt;p&gt;Shipping something that works is step one. Thinking about what comes next is what separates a script you wrote once from a script a team can actually use.&lt;/p&gt;

&lt;p&gt;Two things I would change:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Add a location prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right now the region is hardcoded to &lt;code&gt;eastus&lt;/code&gt;. A slightly better script would also ask the user for their preferred region. Different teams or clients might need resources in different geographies, and hardcoding a region removes that flexibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Replace the four &lt;code&gt;az group create&lt;/code&gt; lines with a loop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The current script has four nearly identical lines. If the environments ever changed — say, you needed to add a &lt;code&gt;Staging&lt;/code&gt; environment — you would have to manually add another line. A loop over an array is cleaner and easier to extend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;environments&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"Dev"&lt;/span&gt; &lt;span class="s2"&gt;"Test"&lt;/span&gt; &lt;span class="s2"&gt;"UAT"&lt;/span&gt; &lt;span class="s2"&gt;"Production"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;env &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;environments&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ProjectName&lt;/span&gt;&lt;span class="s2"&gt;-RG-&lt;/span&gt;&lt;span class="nv"&gt;$env&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s2"&gt;"eastus"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same result, but now adding a new environment is a one-word change.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parameterize, do not hardcode.&lt;/strong&gt; A script that accepts input is reusable. A script with hardcoded values is a one-time tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate your inputs early.&lt;/strong&gt; Check that required values exist before doing any real work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Name things clearly.&lt;/strong&gt; &lt;code&gt;ProjectName-RG-Dev&lt;/code&gt; tells you the project, the resource type, and the environment at a glance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate environments into separate resource groups.&lt;/strong&gt; Dev and Production should never share a resource group in a real setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write a destroy script alongside every deploy script.&lt;/strong&gt; I did not need it here, but the habit of writing a teardown script is what keeps your Azure bill from surprising you.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Is Next
&lt;/h2&gt;

&lt;p&gt;Assignment 3 is more complex. It covers two scenarios: a one-click deploy script that provisions a full environment stack for non-technical staff, and a university migration to Azure where each department gets its own set of resources — with a requirement to support 20 more departments the following year. That last part is a design thinking challenge, not just a scripting challenge.&lt;/p&gt;

&lt;p&gt;I will write about that one too. Follow along on &lt;a href="https://dev.to/manny300"&gt;my Dev.to profile&lt;/a&gt; if you want to see how it goes.&lt;/p&gt;




&lt;p&gt;You can find the full script and repo here: &lt;a href="https://github.com/EmmanuelAjibokun/Techcrush-Ass-2" rel="noopener noreferrer"&gt;github.com/EmmanuelAjibokun/Techcrush-Ass-2&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloudcomputing</category>
      <category>azure</category>
      <category>devops</category>
      <category>bash</category>
    </item>
    <item>
      <title>From Zero to Multi-Region: My experience deploying on Azure for the First Time</title>
      <dc:creator>manny300</dc:creator>
      <pubDate>Sat, 30 May 2026 17:27:37 +0000</pubDate>
      <link>https://dev.to/manny300/from-zero-to-multi-region-my-experience-deploying-on-azure-for-the-first-time-cj3</link>
      <guid>https://dev.to/manny300/from-zero-to-multi-region-my-experience-deploying-on-azure-for-the-first-time-cj3</guid>
      <description>&lt;p&gt;Starting this project, I was not as lost as I was with the first one.&lt;br&gt;
If you haven't seen the first one, here it is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8" class="crayons-story__hidden-navigation-link"&gt;A cloud service model decision framework comparing IaaS / PaaS / SaaS trade-offs for three production workloads&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/manny300" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F787659%2F6c3da68e-1c2c-42f3-a42b-885328ad64d9.jpg" alt="manny300 profile" class="crayons-avatar__image" width="800" height="739"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/manny300" class="crayons-story__secondary fw-medium m:hidden"&gt;
              manny300
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                manny300
                
              
              &lt;div id="story-author-preview-content-3668993" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/manny300" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F787659%2F6c3da68e-1c2c-42f3-a42b-885328ad64d9.jpg" class="crayons-avatar__image" alt="" width="800" height="739"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;manny300&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 14&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8" id="article-link-3668993"&gt;
          A cloud service model decision framework comparing IaaS / PaaS / SaaS trade-offs for three production workloads
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloudcomputing"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloudcomputing&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/solutionarchitect"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;solutionarchitect&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloudsolution"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloudsolution&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;This time I had some familiarity coming in. The first thing I did was explore the Azure portal, clicked around, created a Resource Group, setup an App Service, and it worked.&lt;/p&gt;

&lt;p&gt;Then I moved on to the CLI, which is where things started to feel funny.&lt;/p&gt;




&lt;h2&gt;
  
  
  First Attempt: Azure Cloud Shell
&lt;/h2&gt;

&lt;p&gt;My first attempt was with Azure Cloud Shell. It did not feel natural to me. My main confusion was around shell scripts. I was not sure if I could write and run a deploy script from inside Cloud Shell.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In hindsight, the answer is yes. You can use a text editor like Vim/Emacs right inside Cloud Shell and execute your script from there. But I did not think of that at the time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I moved on to installing the Azure CLI locally on my machine.&lt;/p&gt;

&lt;p&gt;That took a couple of days on its own, but working on my local machine felt more natural. The first installation method I tried did not work. I eventually got it working, moved into VS Code, and started writing my deploy script properly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;Take the same static website I built for Project 1 and deploy it to Azure using the Web App Service, across two different regions.&lt;/p&gt;

&lt;p&gt;I wrote a &lt;code&gt;deploy.sh&lt;/code&gt; script and a &lt;code&gt;destroy.sh&lt;/code&gt; script. The destroy script is the habit that saves you from racking up charges on resources you forgot about.&lt;/p&gt;

&lt;p&gt;The script flow followed Azure's hierarchy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;strong&gt;Resource Group&lt;/strong&gt;, every resource on Azure must belong to one&lt;/li&gt;
&lt;li&gt;Create an &lt;strong&gt;App Service Plan&lt;/strong&gt;, this is where you choose the OS for your web app&lt;/li&gt;
&lt;li&gt;Create the &lt;strong&gt;Web App&lt;/strong&gt; on top of that plan&lt;/li&gt;
&lt;li&gt;Deploy your files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The App Service Plan is worth understanding properly. It is not just a billing tier. Even though we are working with Platform as a Service, meaning we are not managing the underlying infrastructure ourselves, we still choose the operating system. Azure handles everything below that.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting West Europe Working
&lt;/h2&gt;

&lt;p&gt;Getting the West Europe deployment working took some back and forth with the commands. Some flags I used were not recognized by my version of the CLI, and some runtime options that older documentation referenced no&lt;br&gt;
longer exist.&lt;br&gt;
&lt;em&gt;Static site hosting on a Web App Service Plan with a Linux OS, for example, is not supported. The Web App Service Plan works with Windows OS for deploying static sites.&lt;/em&gt; Each of these were small walls that required reading error messages carefully, researching, and adjusting.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Wall: East US Quota Limits
&lt;/h2&gt;

&lt;p&gt;The second half of the challenge was deploying to a second region, East US.&lt;br&gt;
I expected it to work the same way West Europe did. It did not.&lt;br&gt;
The error I kept hitting was about quota. Specifically, the &lt;strong&gt;Total VMs limit for East US was set to zero&lt;/strong&gt; on my subscription. No VMs available meant no App Service Plan could be created, which meant no deployment.&lt;/p&gt;

&lt;p&gt;My first instinct was that maybe the SKU was the problem. I was using &lt;code&gt;F1&lt;/code&gt;, which is the free tier. I went into the Azure portal and looked through the quota section under the Web App provider. I could see that certain SKUs like &lt;code&gt;P1V4&lt;/code&gt; had limits of 10 or 30 in that region, while &lt;code&gt;F1&lt;/code&gt; was sitting at zero.&lt;/p&gt;

&lt;p&gt;I changed the SKU in my script to one of those available tiers, ran the script again, and hit the same wall. &lt;em&gt;The error was not about the SKU specifically. It was about the Total VM quota for the region, and that articular quota had no option to adjust the limit from the portal.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Rabbit Hole: Resource Providers
&lt;/h2&gt;

&lt;p&gt;Around this time I started paying closer attention to how Azure&lt;br&gt;
organizes its services. I came across &lt;strong&gt;Resource Providers&lt;/strong&gt;, which I had not really thought about before.&lt;/p&gt;

&lt;p&gt;Every Azure service belongs to a provider namespace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Microsoft.Web&lt;/code&gt; for App Services&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Microsoft.Compute&lt;/code&gt; for Virtual Machines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before you can use any service, the corresponding provider needs to be registered on your subscription. On a free account, some providers are not registered by default, and quotas are locked.&lt;/p&gt;

&lt;p&gt;I went down the rabbit hole of manually registering the Compute&lt;br&gt;
provider, only to discover that the Web provider I actually needed had already been registered automatically.&lt;br&gt;
&lt;em&gt;It was a detour, but it was a useful one.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Upgrading to Pay As You Go
&lt;/h2&gt;

&lt;p&gt;I upgraded from the free tier to Pay As You Go. I still have my $200 free credit for the first 30 days, so the cost risk was manageable.&lt;br&gt;
After upgrading, the provider situation improved and quotas became adjustable.&lt;br&gt;
But the East US Total VM limit was still at zero and still had no adjustment option in the portal. I reached out to Microsoft engineering support and submitted a formal quota increase request for two instances.&lt;br&gt;
&lt;em&gt;That request is still being processed.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Finding a Different Path
&lt;/h2&gt;

&lt;p&gt;While that was still on, I found a different path.&lt;br&gt;
Since what I am deploying is a static website, Azure has a dedicated &lt;strong&gt;Static Web Apps&lt;/strong&gt; service that sits outside the App Service quota system entirely. I deployed to it and it worked without hitting any quota restrictions at all. I was able to deploy to two different regions successfully using that service.&lt;/p&gt;

&lt;p&gt;I also went back and tested West Europe with the original Web App Service approach, and it worked there as well. So I now have deployments running across multiple regions through two different methods.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Unanswered Question
&lt;/h2&gt;

&lt;p&gt;As a Pay As You Go subscriber, I would expect to be able to deploy to any region Azure offers. But right now I am restricted to one region for Web App Service deployments while the quota request gets processed.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If anyone has run into this and know the reason for this, I would genuinely like to know. It is the kind of thing that would matter on a real project with a deadline.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Read the Full Project&lt;/p&gt;

&lt;p&gt;You can have a look at the project by clicking the link below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/EmmanuelAjibokun" rel="noopener noreferrer"&gt;
        EmmanuelAjibokun
      &lt;/a&gt; / &lt;a href="https://github.com/EmmanuelAjibokun/Azure-Web-App" rel="noopener noreferrer"&gt;
        Azure-Web-App
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A small web application (a static site is fine; even better, a "Hello, [your name]" Flask app) deployed into Azure App Service in two regions, behind a Resource Group you provisioned entirely from the Azure CLI — no portal clicks for the deployment itself.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Azure Web App&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Deploy a Node.js app to Azure using the Azure CLI. This repo contains two deployment scripts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/EmmanuelAjibokun/Azure-Web-App/deploy-app.sh" rel="noopener noreferrer"&gt;deploy-app.sh&lt;/a&gt; — deploys the local Node.js app from the &lt;code&gt;app/&lt;/code&gt; folder using &lt;code&gt;az webapp up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/EmmanuelAjibokun/Azure-Web-App/deploy-static.sh" rel="noopener noreferrer"&gt;deploy-static.sh&lt;/a&gt; — provisions a Static Web App (East US 2) and a Web App from GitHub (West Europe)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" rel="nofollow noopener noreferrer"&gt;Azure CLI&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;An active Azure subscription&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://git-scm.com/" rel="nofollow noopener noreferrer"&gt;Git&lt;/a&gt; installed&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quickstart&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Clone the repo&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/EmmanuelAjibokun/cloud-eng.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; azure-web-app&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Log in to Azure&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;az login&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. (Optional) Set your active subscription&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;az account list --output table
az account &lt;span class="pl-c1"&gt;set&lt;/span&gt; --subscription &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;&amp;lt;your-subscription-id&amp;gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Option A — Deploy the local Node.js app&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;This deploys the &lt;code&gt;app/&lt;/code&gt; folder directly to an Azure Web App using &lt;code&gt;az webapp up&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;chmod +x deploy-app.sh
./deploy-app.sh&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;What it does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checks that you are logged in to the Azure CLI — exits with an error if not&lt;/li&gt;
&lt;li&gt;Checks if &lt;code&gt;cloud-decision-east&lt;/code&gt; is already…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/EmmanuelAjibokun/Azure-Web-App" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you would like to follow along on the learn-by-doing journey,&lt;br&gt;
comment "github" and I will send you the project guide link. Kindly star the project and follow me on GitHub.&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://github.com/EmmanuelAjibokun" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars.githubusercontent.com%2Fu%2F96999656%3Fv%3D4%3Fs%3D400" height="460" class="m-0" width="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://github.com/EmmanuelAjibokun" rel="noopener noreferrer" class="c-link"&gt;
            EmmanuelAjibokun (Emmanuel Ajibokun ) · GitHub
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            A computer programming enthusiast, Geologist by field of study and a fast learner - EmmanuelAjibokun
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Ffavicons%2Ffavicon.svg" width="32" height="32"&gt;
          github.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>cloudcomputing</category>
      <category>azure</category>
      <category>cloudsolution</category>
      <category>staticwebapps</category>
    </item>
    <item>
      <title>A cloud service model decision framework comparing IaaS / PaaS / SaaS trade-offs for three production workloads</title>
      <dc:creator>manny300</dc:creator>
      <pubDate>Thu, 14 May 2026 10:27:54 +0000</pubDate>
      <link>https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8</link>
      <guid>https://dev.to/manny300/a-cloud-service-model-decision-framework-comparing-iaas-paas-saas-trade-offs-for-three-4jd8</guid>
      <description>&lt;h2&gt;
  
  
  From Geology to Cloud Computing: My First Project 🌍
&lt;/h2&gt;

&lt;p&gt;Diving into the world of cloud computing as an applied geology graduate, &lt;br&gt;
having moved from frontend development with React and Next.js to backend &lt;br&gt;
development with Node.js.&lt;/p&gt;

&lt;p&gt;This is not just another tech skill to learn. This season could be the &lt;br&gt;
beginning of a career transition for me. Because of that, I paid a &lt;br&gt;
subsidised price to join the TechCrush bootcamp. But I know that is not &lt;br&gt;
enough. If I want to finish with the outcome I desire, I must put in &lt;br&gt;
extra work.&lt;/p&gt;


&lt;h2&gt;
  
  
  How I Planned the Work
&lt;/h2&gt;

&lt;p&gt;The first thing I did was prompt Claude with some considerations that &lt;br&gt;
included 10 job posting requirements in cloud computing and DevOps, the &lt;br&gt;
course modules that would be covered during the bootcamp, and a sample &lt;br&gt;
task by Forrest Brazeal called the #CloudResumeChallenge. Here is the &lt;br&gt;
prompt I used:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I'm transitioning my career into cloud engineering, and I feel the &lt;br&gt;
3-month training covers the majority of these opportunities. I want to &lt;br&gt;
have projects for each milestone, in the same order that I would be &lt;br&gt;
doing them in the training. Create a similar guide to the one by &lt;br&gt;
Forrest Brazeal's #CloudResumeChallenge. Juxtapose my learning and job &lt;br&gt;
requirements to map out the projects."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This mapped out &lt;strong&gt;9 projects&lt;/strong&gt; to work on by the end of my bootcamp.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first project is what this post is about.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  The Humbling Part
&lt;/h2&gt;

&lt;p&gt;I had one introductory class and one main class with my tutor. I &lt;br&gt;
actually started working on the first project before my classes began. &lt;br&gt;
I had studied on my own, watched about 6 YouTube videos, and was &lt;br&gt;
feeling pretty confident.&lt;/p&gt;

&lt;p&gt;Then, to my great amusement, I did not seem to understand the task at &lt;br&gt;
all, let alone know where to get started. It was one of the strangest &lt;br&gt;
feelings, and I remember thinking to myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I don't understand what is expected of me."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I gave AI this prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"I'm just starting out in this career, I don't want the answer &lt;br&gt;
handed out to me, but I need resources that can help me better &lt;br&gt;
understand the question, and information on what to learn in order to &lt;br&gt;
complete the task."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With some targeted reading and research, I was able to complete the &lt;br&gt;
project. 🎉&lt;/p&gt;


&lt;h2&gt;
  
  
  Read the Full Project
&lt;/h2&gt;

&lt;p&gt;You can read about my findings by clicking the link below:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://emmanuelajibokun.github.io/cloud-decision-document/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;emmanuelajibokun.github.io&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;&lt;em&gt;If you would like to follow along on the learn-by-doing journey, &lt;br&gt;
comment "github" and I will send you the project guide link. Kindly &lt;br&gt;
star the project and follow me on GitHub.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cloudcomputing</category>
      <category>devops</category>
      <category>solutionarchitect</category>
      <category>cloudsolution</category>
    </item>
  </channel>
</rss>
