<?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>Forem: Brian Meinert</title>
    <description>The latest articles on Forem by Brian Meinert (@bmeinert8).</description>
    <link>https://forem.com/bmeinert8</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%2F1150303%2Fc5c9b7e1-5177-4bf3-840c-a50e25914f63.jpg</url>
      <title>Forem: Brian Meinert</title>
      <link>https://forem.com/bmeinert8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bmeinert8"/>
    <language>en</language>
    <item>
      <title>From LocalStorage to Zero-Trust: Architecting a Serverless Secret Management Platform</title>
      <dc:creator>Brian Meinert</dc:creator>
      <pubDate>Mon, 09 Feb 2026 18:51:31 +0000</pubDate>
      <link>https://forem.com/bmeinert8/from-localstorage-to-zero-trust-architecting-a-serverless-secret-management-platform-2am4</link>
      <guid>https://forem.com/bmeinert8/from-localstorage-to-zero-trust-architecting-a-serverless-secret-management-platform-2am4</guid>
      <description>&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt; JavaScript, Node.js, Azure Functions, Azure Key Vault, Table Storage, Bicep&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%2F0356c7ro57khcu93rw1o.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%2F0356c7ro57khcu93rw1o.png" alt="Hero Image: Screenshot of the main Password Generator UI with a high-strength password generated and all UI elements visible" width="800" height="885"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Genesis: Breaking Out of the Browser
&lt;/h2&gt;

&lt;p&gt;This project started the way many portfolio projects do for me: a Frontend Mentor challenge. The prompt was simple, build a password generator using vanilla JavaScript.&lt;/p&gt;

&lt;p&gt;I built the core logic quickly: a sliding scale for length, character set toggles (uppercase, symbols, etc.), and a strength meter for user feedback on strength of password. But as I tested it, I hit a wall. I wanted to save the passwords I generated.&lt;/p&gt;

&lt;p&gt;I implemented &lt;code&gt;localStorage&lt;/code&gt;, which worked fine until I cleared my cache, or opened the site elsewhere. The data was trapped in the browser. I realized that if I wanted this to be a real application, I needed to break out of the browser, giving me the perfect opportunity to scale to the cloud.&lt;/p&gt;

&lt;p&gt;This is the story of how a static website evolved into a fully architected, "Zero-Trust" serverless application on Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: Designing the "Zero-Trust" Architecture
&lt;/h2&gt;

&lt;p&gt;My goal wasn't just to "add a backend." I wanted to simulate a high-security environment. If I’m storing passwords and other secrets, I need to treat the application like a digital vault.&lt;/p&gt;

&lt;p&gt;I established three core constraints for the architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Serverless First:&lt;/strong&gt; I didn't want to manage VMs or OS updates. I chose &lt;strong&gt;Azure Functions&lt;/strong&gt; (Node.js 18) for the API and &lt;strong&gt;Azure Static Web Apps&lt;/strong&gt; for global hosting.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hardware-Backed Security:&lt;/strong&gt; Storing a "Master PIN" in code is a vulnerability. I needed &lt;strong&gt;Azure Key Vault&lt;/strong&gt; to hold the sensitive hash.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Identity-Based Access:&lt;/strong&gt; The application should authenticate against cloud resources using Managed Identities, not hardcoded connection strings.&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%2Fl92ylmcw9epms8lwql44.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%2Fl92ylmcw9epms8lwql44.png" alt="Image: Screenshot of your Azure Resource Group in the Portal, showing the Key Vault, Function App, and Storage Account listed together" width="800" height="526"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Cloud Infrastructure: A fully serverless topology.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: The Identity Challenge
&lt;/h2&gt;

&lt;p&gt;The first major hurdle appeared when I tried to connect my API to the Key Vault.&lt;/p&gt;

&lt;p&gt;I initially attempted to use the &lt;code&gt;@azure/identity&lt;/code&gt; library to authenticate my function app against the vault. Locally, this worked seamlessly using my developer credentials. However, the moment I deployed to production, the backend crashed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Diagnosis:&lt;/strong&gt;&lt;br&gt;
It was a classic "It works on my machine" environment mismatch. The Node.js runtime environment within Azure Static Web Apps handles identity tokens differently than a standard App Service. The library was failing to retrieve a valid token, causing the handshake to fail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: Key Vault References&lt;/strong&gt;&lt;br&gt;
Instead of fighting the library, I pivoted to a platform-native feature: &lt;strong&gt;Key Vault References&lt;/strong&gt;. By configuring the Application Settings in Azure to point directly to the Vault URI (e.g., &lt;code&gt;@Microsoft.KeyVault(...)&lt;/code&gt;), Azure handles the authentication at the platform level. It fetches the secret and injects it into the environment variable before my code even runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 3: Persistence &amp;amp; The Build Pipeline Trap
&lt;/h2&gt;

&lt;p&gt;With security solved, I needed a database. A full SQL server felt like overkill for simple key-value pairs, so I chose &lt;strong&gt;Azure Table Storage&lt;/strong&gt;. It is fast, NoSQL, and incredibly cheap for this use case.&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%2Fohqzxeagohh5zqi42bb5.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%2Fohqzxeagohh5zqi42bb5.png" alt="Image: Screenshot of the " width="800" height="737"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Result: Secure, cloud-persisted storage replacing the temporary localStorage.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I built the CRUD endpoints locally, but when I pushed to GitHub, the build failed silently. The Azure build server was looking at my &lt;code&gt;package-lock.json&lt;/code&gt; file to decide what to install. I had installed the database SDK manually, but the lock file hadn't updated correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Lesson:&lt;/strong&gt;&lt;br&gt;
I performed a "clean install" locally deleting &lt;code&gt;node_modules&lt;/code&gt; and the lock file—generating a fresh, accurate dependency tree. This reinforced a valuable lesson: &lt;strong&gt;The build pipeline is the ultimate source of truth, not your local machine.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 4: UX Polish &amp;amp; The Full CRUD Lifecycle
&lt;/h2&gt;

&lt;p&gt;A backend is useless if the user experience feels clunky. I spent the next phase refining the frontend to match the robustness of the backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid Input System:&lt;/strong&gt;&lt;br&gt;
Originally, the app only generated random passwords. I realized users often want to manage their own passwords. I refactored the display component into a hybrid input/display field, adding real-time strength detection to the strength meter as the user types.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Edit" Workflow:&lt;/strong&gt;&lt;br&gt;
I implemented an "Edit Mode" where clicking a pencil icon loads a saved password back into the generator context. When the user saves changes, the backend uses an update and insert, or upsert, strategy, seamlessly overwriting the old entry.&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%2Fwsplmax1vrqeoi9vz35e.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%2Fwsplmax1vrqeoi9vz35e.png" alt="Image: Screenshot of the app in " width="800" height="766"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;State Management: Loading existing data back into the generator context.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native-Feel Modals:&lt;/strong&gt;&lt;br&gt;
For deletions, I avoided the standard browser &lt;code&gt;alert()&lt;/code&gt;. I built a custom modal with a "Don't show this again" preference that persists in the browser via localStorage, giving the app a polished, native feel.&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%2F3dv2y0t8y1j9w3f0iuav.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%2F3dv2y0t8y1j9w3f0iuav.png" alt="Image: Screenshot of your custom " width="800" height="762"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 5: From "Pets" to "Cattle" (Infrastructure as Code)
&lt;/h2&gt;

&lt;p&gt;At this point, I had a fully functional app. But I had built it by clicking around in the Azure Portal. If I accidentally deleted the Resource Group, I would have to remember every setting to rebuild it.&lt;/p&gt;

&lt;p&gt;I decided to migrate to &lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt; using &lt;strong&gt;Azure Bicep&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Goal:&lt;/strong&gt; Define the entire environment, Storage, Vault, Web App, and Permissions, in a single file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Challenge: RBAC Orchestration&lt;/strong&gt;&lt;br&gt;
Being brand new to IaC, there were many challenges that came with this phase, however, the hardest part of automation was permissions. My Static Web App needed permission to read the Key Vault. In code, this requires orchestrating a sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Create the Static Web App (to generate a Managed Identity).&lt;/li&gt;
&lt;li&gt; Dynamically retrieve that Identity's Principal ID.&lt;/li&gt;
&lt;li&gt; Inject that ID into a &lt;code&gt;roleAssignment&lt;/code&gt; resource targeted at the Key Vault.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Result:&lt;/strong&gt;&lt;br&gt;
I wrote a &lt;code&gt;main.bicep&lt;/code&gt; file that defined the entire stack. I successfully deployed a "Test Environment" parallel to my live app, verified it worked, and then destroyed it with a single CLI command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: What I Learned
&lt;/h2&gt;

&lt;p&gt;This project started as a JavaScript exercise, but it became a much needed crash course in Cloud Engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security is an Architecture:&lt;/strong&gt; Storing secrets requires thinking about Identity, not just hashing passwords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Cloud is Asynchronous:&lt;/strong&gt; You have to wait for resources to exist before you can grant permissions to them—Bicep handles this dependency graph beautifully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless is powerful:&lt;/strong&gt; I built a scalable, global, secure application for pennies a month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I now have a &lt;strong&gt;Serverless Secret Management Platform&lt;/strong&gt; that is secure, scalable, and fully reproducible to show off in my portfolio, and for my own personal use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bmeinert8/serverless-password-app" rel="noopener noreferrer"&gt;Link to GitHub Repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>cloud</category>
      <category>azure</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Solving the "MFA Wall" and Other Roadblocks: Setting Up a Cloud-Ready Linux Environment</title>
      <dc:creator>Brian Meinert</dc:creator>
      <pubDate>Fri, 19 Dec 2025 15:18:35 +0000</pubDate>
      <link>https://forem.com/bmeinert8/solving-the-mfa-wall-and-other-roadblocks-setting-up-a-cloud-ready-linux-environment-3o66</link>
      <guid>https://forem.com/bmeinert8/solving-the-mfa-wall-and-other-roadblocks-setting-up-a-cloud-ready-linux-environment-3o66</guid>
      <description>&lt;p&gt;Spending the last few years diving into the multifaceted world of IT, from physical hardware and networking to frontend development and Infrastructure as Code (IaC), I realized they all share a common heartbeat. As someone striving to become a world-class Solutions and Security Architect in the future, I knew it was crucial to become proficient in the engine that powers the modern cloud: Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provisioning the Environment: Why WSL2?
&lt;/h2&gt;

&lt;p&gt;For a lifelong Windows user (with a little Apple ecosystem sprinkled in), the first hurdle was deciding how to run my Linux distribution. I weighed the options of dual-booting, dedicated Virtual Machines, and the Windows Subsystem for Linux (WSL2).&lt;/p&gt;

&lt;p&gt;I ultimately chose WSL2. It offers a seamless bridge, allowing me to run a high-performance Linux environment directly alongside my Windows productivity applications without the overhead of a full VM or the hassle's of rebooting for a dual-boot setup.&lt;/p&gt;

&lt;p&gt;However, the installation presented a firmware-level roadblock. My initial attempts to install WSL were blocked because virtualization was disabled in the system firmware. This required a quick trip into the UEFI/BIOS to enable Intel Virtualization Technology (VT-x).&lt;/p&gt;

&lt;h2&gt;
  
  
  Mastering Navigation and Shell Customization
&lt;/h2&gt;

&lt;p&gt;Once I had my Ubuntu environment live, I spent time leveling up my command-line proficiency. I used the &lt;a href="https://www.boot.dev/courses/learn-linux" rel="noopener noreferrer"&gt;Boot.Dev Linux course&lt;/a&gt; to accelerate my learning, which I highly recommend for anyone looking to move past the basics of Bash quickly.&lt;/p&gt;

&lt;p&gt;After gaining confidence in navigation, I wanted to customize my environment for better workflow persistence and a touch of personality. I modified my &lt;code&gt;.bashrc&lt;/code&gt; file using the &lt;code&gt;nano&lt;/code&gt; text editor to achieve two things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated Directory Mapping:&lt;/strong&gt; I added an auto-CD command so my terminal launches directly into my active project folder on the Windows filesystem (/mnt/c/).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Scripting:&lt;/strong&gt; I wrote a custom Bash script using conditional logic (if/elif). Now, every time I open the terminal, it executes a check against the system date and greets me with a personalized message or a holiday-specific greeting (Christmas, New Year’s, etc.) based on the date command output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ==========================================================
# Holiday Greeting Variables
# Format MM-DD for fixed-date holidays
DATE_MONTH=$(date +"%m-%d")

# Calculates the Nth Day of the Week holidays
# Thanksgiving: 4th Thursday in November
THANKSGIVING_DATE=$(date -d "$(date +%Y)-11-01 +3 weeks Thursday" +%m-%d)
# Labor Day: 1st Monday in September
LABOR_DAY_DATE=$(date -d "$(date +%Y)-09-01 +$(($(date -d "$(date +%Y)-09-01" +%w) != 1 ? 8-$(date -d "$(date +%Y)-09-01" +%w) : 0)) days" +%m-%d)

# ==========================================================

# 1. New Year's Day
if [ "$DATE_MONTH" == "01-01" ]; then
    echo "🎉 Happy New Year, Brian!"

# 2. Birthday
elif [ "$DATE_MONTH" == "02-21" ]; then
    echo "🎂 Happy Birthday, Brian!"

# 3. Halloween
elif [ "$DATE_MONTH" == "10-31" ]; then
    echo "🎃 Happy Halloween!"

# 4. Christmas
elif [ "$DATE_MONTH" == "12-25" ]; then
    echo "🎄 Merry Christmas, Brian!"

# 5. 4th of July
elif [ "$DATE_MONTH" == "07-04" ]; then
    echo "🎆 Happy Independence Day, Brian!"

# 6. Thanksgiving
elif [ "$DATE_MONTH" == "$THANKSGIVING_DATE" ]; then
    echo "🦃 Happy Thanksgiving, Brian!"

# 7. Labor Day
elif [ "$DATE_MONTH" == "$LABOR_DAY_DATE" ]; then
    echo "🛠️ Happy Labor Day, Brian!"

# 8. Default Welcome Message
else
    echo "Welcome back, Brian! Ready to build something great."
fi

# Display the Date/Time
echo "Current Time: $(date)"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Azure Integration &amp;amp; The MFA Challenge
&lt;/h2&gt;

&lt;p&gt;With the environment stabilized, it was time to connect to the cloud. I installed the Azure Command Line Interface, but immediately hit a common security roadblock: Error AADSTS50076.&lt;/p&gt;

&lt;p&gt;Because my Azure tenant is secured with Conditional Access Policies, my login was blocked due to a missing Multi-Factor Authentication claim. To resolve this, I performed an &lt;code&gt;az logout&lt;/code&gt; and cleared the local profile cache (&lt;code&gt;rm -rf ~/.azure&lt;/code&gt;) to ensure no stale tokens were causing a conflict.&lt;/p&gt;

&lt;p&gt;I then re-authenticated using the &lt;code&gt;--use-device-code&lt;/code&gt; flag combined with my specific Tenant ID. By using an isolated browser session for the device code flow, I successfully triggered the MFA, satisfying the Microsoft Entra ID security requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Road Ahead
&lt;/h2&gt;

&lt;p&gt;My environment is now "Cloud Ready." My next milestone is architecting a Serverless Password Vault, a cloud-native application leveraging Azure Functions, Cosmos DB, and Azure Static Web Apps, while recycling a password generator and storage vault frontend I had built previously for a frontend mentor challenge.&lt;/p&gt;

&lt;p&gt;I’ve always welcomed problems during a build. Whether it’s a login failure or a script not producing the desired output, I see these roadblocks as opportunities to sharpen my troubleshooting skills. In a field that evolves as rapidly as the IT ecosystem, a "not-so-simple" fix is just another notch in the belt of an IT professional.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloudcomputing</category>
      <category>linux</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Updates to the Azure Onboarding App</title>
      <dc:creator>Brian Meinert</dc:creator>
      <pubDate>Fri, 22 Dec 2023 15:06:40 +0000</pubDate>
      <link>https://forem.com/bmeinert8/updates-to-the-azure-onboarding-app-kj6</link>
      <guid>https://forem.com/bmeinert8/updates-to-the-azure-onboarding-app-kj6</guid>
      <description>&lt;p&gt;Previously, in my &lt;a href="https://dev.to/bmeinert8/azure-automated-onboarding-project-2jj4"&gt;last post&lt;/a&gt;, I went about creating an automated onboarding app in Azure using the Logic Apps resource. Looking back at the app, I wanted to figure out how to make it more secure, outside of just having an administrator enable the user, so I turned to key vault.&lt;/p&gt;

&lt;p&gt;In my first build, the password was hard coded into the application, which as we all know, is a huge security risk and bad practice in the industry. Enter &lt;a href="https://learn.microsoft.com/en-us/azure/key-vault/general/basic-concepts" rel="noopener noreferrer"&gt;Azure Key Vault&lt;/a&gt;, a cloud service that is used to securely store and access secrets, such as our new user password. Once the key vault is created and our password securely stored, I granted permissions to the logic app to access and use the stored secret, which I will be taking you through the steps to integrate key vault into your own logic apps.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Create key vault.&lt;/li&gt;
&lt;li&gt;Create a secret in the key vault.&lt;/li&gt;
&lt;li&gt;Activate the system assigned identity of the logic app.&lt;/li&gt;
&lt;li&gt;Grant permissions to the logic app.&lt;/li&gt;
&lt;li&gt;Add the key vault api connection.&lt;/li&gt;
&lt;li&gt;Integrate the secret into the user creation.&lt;/li&gt;
&lt;li&gt;Test the new app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first thing that needs to be done in this process is to add our key vault resource. There are a few different ways that this can be done, either in the portal, by using the Azure CLI, Azure PowerShell, or by deploying through IaC such as bicep, ARM template, or Terraform. For this step, I created the key vault through PowerShell by running, &lt;/p&gt;

&lt;p&gt;&lt;code&gt;New-AzKeyVault -VaultName 'KeyVaultName' -ResourceGroupName 'ResourceGroupName' -Location 'Location' -EnabledForDeployment&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once that key vault was created, the next step is to add the secret to the key vault, which is our password, that will be used for our new users. To create the secret, this can also be done in the portal, or over the Azure CLI, or Azure PowerShell. To accomplish this task, I once again used PowerShell by running the command to create a new key vault secret.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$Secret = ConvertTo-SecureString -String 'Password' -AsPlainText -Force&lt;br&gt;
Set-AzKeyVaultSecret -VaultName 'KeyVaultName' -Name 'SecretName' -SecretValue $Secret&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With the key vault created and secret added to the vault, we now need to grant permissions to the app to use our secret using least privilege access. The first step in doing this was to enable the system managed identity of the logic app. To do this step I hopped into the portal and went into the logic app. Once inside of the logic app, on the left hand side under the settings menu, open the identity option, and change the status from off to on.&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%2Ffwq0u980lmpsjbqjzxle.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffwq0u980lmpsjbqjzxle.jpg" alt="logic app identity" width="800" height="910"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the logic app has an identity, we can grant it access to the key vault using RBAC with least privileges. To use least privilege, we need to first understand what we need the logic app to do, which in our case, is to be able to read secrets in the key vault and use the secrets. With that noted, I went ahead and assigned the key vault secrets user role to the onboarding app. &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%2Fzn5f28hhjspunjqqh2lo.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%2Fzn5f28hhjspunjqqh2lo.png" alt="logic app role assignment" width="800" height="152"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the key vault set up and permissions to the logic app granted, the next step is to connect the key vault api connection to the logic app workflow. Since we need the password secret from the key vault before we create the user, we'll insert the get secret connection between the HTTP request trigger and create user connection. With that in place, we'll go ahead and select our secret that we created for the new user password.&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%2Fg6lwargahkx8zpq2u0aa.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%2Fg6lwargahkx8zpq2u0aa.png" alt="get secret connection added" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since our logic app has now grabbed the secret in the previous step, in the create user connection, password creation, we can input the value from the secret without exposing or hard coding our password.&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%2F77hcyi5m0d161bgxi6xu.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%2F77hcyi5m0d161bgxi6xu.png" alt="secret value added to user creation" width="800" height="1065"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step with our new logic app integration is to test. Again, I used thunder client in VSCode to send the HTTP request to the app, making 2 different accounts and signing in with those accounts to make the password was the one stored in the secrets. With 2 successful runs, the Key vault integration was working as planned. &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%2Fkmyxeh26m49neswsxj3w.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%2Fkmyxeh26m49neswsxj3w.png" alt="succesful runs" width="800" height="51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key vault should always be your go to for storing your secrets passwords, certificates and any other sensitive information that you may need to use. Azure makes integration of key vault very easy through RBAC with either user accounts or managed identities. It's a great practice to help secure your sensitive data from falling into the wrong hands, that should always be integrated when possible. &lt;/p&gt;

</description>
      <category>azure</category>
      <category>logicapps</category>
      <category>tutorial</category>
      <category>azurekeyvault</category>
    </item>
    <item>
      <title>Azure Automated Onboarding Project</title>
      <dc:creator>Brian Meinert</dc:creator>
      <pubDate>Tue, 31 Oct 2023 22:36:01 +0000</pubDate>
      <link>https://forem.com/bmeinert8/azure-automated-onboarding-project-2jj4</link>
      <guid>https://forem.com/bmeinert8/azure-automated-onboarding-project-2jj4</guid>
      <description>&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;Another week, another Azure project in the books for my portfolio and cloud engineering journey. I'd first like to start by giving a ton of credit to &lt;a href="https://www.linkedin.com/in/madebygps/" rel="noopener noreferrer"&gt;Gwyneth Peña-Siguenza&lt;/a&gt; for all of her incredible videos, project ideas, and educational content she puts out. She has been a ton of help to me on my journey through all of this content, and I recommend anyone who's looking to either get into cloud or advance their cloud careers to check out her &lt;a href="https://www.youtube.com/@MadeByGPS/videos" rel="noopener noreferrer"&gt;channel&lt;/a&gt;. Now let's get into this project!&lt;/p&gt;

&lt;p&gt;The idea of this project is to create an onboarding process for a new member, from an email that is received, or information comes in from a Microsoft list. That info is then taken in by an Azure logic app, creates a new user account in Entra ID, adds them to the proper group with proper permissions and roles, and finally sending an email to the user administrator to review the account and permissions before enabling the account. I did this project a little differently than it was suggested, as I don't have a work or school account, I did not have the proper permissions to trigger the logic app off an email or Microsoft list. Instead, I used an HTTP request that I generated to the app using the VSCode Thunder Client extension.  &lt;/p&gt;

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

&lt;p&gt;To get started with this project, the resources you'll need are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Azure Account (you can get one for &lt;a&gt;free&lt;/a&gt; if you don't have one.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure Tennant&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSCode or any other code editor to write some JSON&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;VSCode Thunder Client&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Entra ID Group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Azure Logic App&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first step of this project, once you have an Azure account and tenant said up, is to go in and create a group in your Microsoft Entra ID. For this project, I just created a basic group to add a new user to. If you have an AD p2 license, you can create a &lt;a href="https://learn.microsoft.com/en-us/entra/identity/users/groups-dynamic-membershiprl" rel="noopener noreferrer"&gt;dynamic group&lt;/a&gt; where you can have people dynamically added based on something like a job role and have a set of specific roles assigned to that group. &lt;/p&gt;

&lt;p&gt;Once we have that group created, its time to get into building the logic app.&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%2F2u5pc7dzrfkcb976mc98.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%2F2u5pc7dzrfkcb976mc98.png" alt="Logic app creation window" width="800" height="1173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the creation, since this isn't going to be a live running app I selected the consumption-based plan instead so I'm only paying for whenever the workflow runs. As soon as the logic app is created, our next step is to hop into the logic designer pane and begin creating our app.&lt;/p&gt;

&lt;p&gt;To kick off the app I selected the "When a HTTP request is recieved" trigger. insdie the trigger, it'll ask for a Request Body JSON Schema.&lt;br&gt;
*Note that when you create the trigger your HTTP POST URL will be blank. Do not worry it'll generate the URL when you save the app.&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%2Fqkiq1xg4maonti02jadx.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%2Fqkiq1xg4maonti02jadx.png" alt="HTTP Request Trigger" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create the JSON Schema, there are a couple different ways to go about this task. If you know how to write JSON, you can create the file in VSCode or whatever text editor you use. If not, you can use a site such as &lt;a href="https://www.liquid-technologies.com/online-json-to-schema-converter" rel="noopener noreferrer"&gt;this free JSON to JSON Schema Converter&lt;/a&gt;. You could also just write it out in the body itself. Since I was creating a repository for this project in GitHub to display, I created my JSON Schema in VScode. Once you have your JSON schema written go ahead and add it to the trigger.&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%2Fzdn54u5mmc2cinxpmvau.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%2Fzdn54u5mmc2cinxpmvau.png" alt="JSON Schema" width="702" height="810"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our trigger completed, the next step I took was to create the actions. for this logic app, I had three actions that were to take place. The first action was to create a user in our Microsoft Entra ID tenant. To fill in the boxes of the create user action, I used dynamic content and concat functions to pull data from the JSON in the HTTP request. Also, for security purposes, I did not enable the newly created account, in case of a chance of a malicious user. The account must first be approved and then enabled by the admin.&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%2Fjxiv7myomhk721m78i42.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%2Fjxiv7myomhk721m78i42.png" alt="Logic app with create user step added" width="800" height="1074"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now with the new user created it, I set up another action to add user to a group which I created in my Micorosft Entra ID earlier. Now remember if you have a P2 liscence and dynamic groups, you may not need to do this step based on what the conditions are for your dynamic group (ex. add everyone with Job title containing network administrator) and you have that condition declared and met in the creation of the user. To add the user to the group, there are 2 things you need, the first is the Group ID which you can grab from your Microsoft Entra ID tenant, and the User Id. The User Id, like previously in the Create User, can be dynamically grabbed from the create user action.&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%2F8hklh5e4k0bhc8mdswlo.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%2F8hklh5e4k0bhc8mdswlo.png" alt="Logic app with add user to group added" width="726" height="1191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the new user created and added to our specified group, the final step in building the logic app was to add the final action of sending an email to the admin to review and activate the account.&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%2Fyhnl2pvik09544mnv41n.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%2Fyhnl2pvik09544mnv41n.png" alt="Fully created Logic app" width="722" height="1623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the logic app completed and saved, it was time to head over to VSCode, open up the thunder client and see everything go into action. with the Post URL copied from the logic app and placed in the thunder client, I then added the JSON body of the required parameters that the app requested, and sent the request.&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%2Fmbtmn0wa3bimt9edxn3v.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%2Fmbtmn0wa3bimt9edxn3v.png" alt="Thunder Client Request" width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;with the request sent, in the overview section of the logic app, I verified that the run was successful, checked the Entra ID for the new user and also made sure the user was in the group, followed by checking my email to make sure that I got the email to verify and activate the account.&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%2Fiuxhr9vdajbzbai5zjc7.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%2Fiuxhr9vdajbzbai5zjc7.png" alt="Succesful runs" width="800" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Statements
&lt;/h2&gt;

&lt;p&gt;This was a great mini project to build, and I had a ton of fun creating and learning about logic apps as well. If you are looking for something fun to create and add to your portfolio I highly recommend giving this one a shot! Best of luck on your journey and creations, and as always, thank you for taking the time to give this a read!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>logicapps</category>
      <category>azuread</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
