<?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: John Friesen</title>
    <description>The latest articles on DEV Community by John Friesen (@superjohn140).</description>
    <link>https://dev.to/superjohn140</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%2F150106%2F09e726e0-9ac9-4517-bc79-b35fcf92abed.jpg</url>
      <title>DEV Community: John Friesen</title>
      <link>https://dev.to/superjohn140</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/superjohn140"/>
    <language>en</language>
    <item>
      <title>2 Local machines 1 Dev VM</title>
      <dc:creator>John Friesen</dc:creator>
      <pubDate>Sat, 16 Jan 2021 19:53:36 +0000</pubDate>
      <link>https://dev.to/superjohn140/2-local-machines-1-dev-vm-ib3</link>
      <guid>https://dev.to/superjohn140/2-local-machines-1-dev-vm-ib3</guid>
      <description>&lt;p&gt;I recently wanted to connect a new laptop to one of the Azure virtual machines that I use for remote development. I realized this isn't something easy to do within the azure portal and I have limited knowledge in Linux (ubuntu) and SSL. So after I accomplished this I decided to share what I learned. &lt;/p&gt;

&lt;p&gt;This blog post isn't just to learn how to connect a local machine to a VM. It will also give you a basic understanding of how to set up an SSH connection &lt;/p&gt;

&lt;h2&gt;
  
  
  Content:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What i am using&lt;/li&gt;
&lt;li&gt;1. Create new VM (Optional)&lt;/li&gt;
&lt;li&gt;
2. Create new ssh keys on new local machine 

&lt;ul&gt;
&lt;li&gt;NOTE: SSH understanding&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
3. Add your public key to your Azure VM

&lt;ul&gt;
&lt;li&gt;Integrity check!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;4. Get ready for SSH connection&lt;/li&gt;
&lt;li&gt;5. Actually do the SSH connection&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I am using
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Azure VM (Ubuntu Release 18.XX / bionic) &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/cli/azure/"&gt;Azure cli&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;VS code &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack"&gt;Remote Development&lt;/a&gt; extention pack&lt;/li&gt;
&lt;li&gt;Windows 10 local machine&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Create a new VM (Optional)
&lt;/h2&gt;

&lt;p&gt;If you already have a VM you wish to do this on then you can skip this step.&lt;br&gt;
Create a Linux VM in azure. Choose whichever size you need and in this article, I used Ubuntu Release 18.&lt;/p&gt;

&lt;p&gt;// TODO az create VM code with ssh keys. what user does it create?&lt;br&gt;
set a user varable to make it easier later &lt;code&gt;$user = "%myuser%"&lt;/code&gt;&lt;br&gt;
// TODO remember the user you created for this VM&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create new ssh keys on the new local machine
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;On windows I used this command &lt;code&gt;ssh-keygen -t rsa&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I add the path where to store the keys. i used &lt;code&gt;C:\Users\UserName\.ssh\my-vs-code-vm&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I then add in my passphrase (this is optional but adds security. If you choose to use it REMEMBER THE PASSPHRASE)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5wmHli5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kgzou5f9phxkifqitgc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5wmHli5Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kgzou5f9phxkifqitgc1.png" alt="ssh keygen command execution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great now we have our keys.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  NOTE: SSH understanding
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;my-vs-code-vm&lt;/code&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your new private key &lt;/li&gt;
&lt;li&gt;This stays on your machine and you need to keep it safe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;my-vs-code-vm.pub&lt;/code&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your new public key &lt;/li&gt;
&lt;li&gt;This is going onto your VM so your private key has something to unlock... like the ssh connection we want to establish&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Add your public key to your Azure VM
&lt;/h2&gt;

&lt;p&gt;Here we will be using the &lt;a href="https://docs.microsoft.com/en-us/cli/azure/"&gt;azure cli&lt;/a&gt; to add our new public key remotely execute commands remotely on our virtual machine.&lt;/p&gt;

&lt;p&gt;Specifically, we will be using the &lt;a href="https://docs.microsoft.com/en-us/cli/azure/vm/run-command?view=azure-cli-latest"&gt;az vm run-command&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you logged in &lt;code&gt;az login&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Make sure you have the right Subscription active. &lt;code&gt;az account show&lt;/code&gt; change with &lt;code&gt;az account set -s //*correct subscription guid*//&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Get our public key and put it into a variable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;$publickey = cat ~/.ssh/my-vs-code-vm.pub&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrity check!
&lt;/h3&gt;

&lt;p&gt;make sure your &lt;code&gt;$publickey&lt;/code&gt; value looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ePjGGORi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3mjd409w0q8a4euuwt9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ePjGGORi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3mjd409w0q8a4euuwt9u.png" alt="Publickey Integrity Check"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;now that we have our public key ready let's send it off to our VM.
We need to store our public key in the &lt;code&gt;authorized_keys&lt;/code&gt; file for the user we will connect to.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;az vm run-command invoke --name my-vs-code-vm --resource-group my-dev-vm-rg --command-id RunShellScript --scripts "echo '$publickey' &amp;gt;&amp;gt; /home/$user/.ssh/authorized_keys"&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Get ready for SSH connection
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;We will need the &lt;code&gt;ssh&lt;/code&gt; command to make the connection to the VM. The easiest way I generate it is from the Azure portal. all you need to do is add you &lt;strong&gt;Private Key&lt;/strong&gt; Path in the Azure UI:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X0-kNZBN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uuy01ad1oqwgxya1seej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X0-kNZBN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uuy01ad1oqwgxya1seej.png" alt="Get remote connect for add new remote ssh"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Copy the command from &lt;strong&gt;4. Run the example command below to connect to your VM.&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NOTE: 
you have what you need to just ssh with your local terminal right now but let's keep going. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now in VS Code open the Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;code&gt;Remote-SSH: Add New SSH Host...&lt;/code&gt; and paste the &lt;code&gt;ssh&lt;/code&gt; command we got from azure (if you don't see it you need to make sure you have the extension installed/enabled) // TODO make sure the remote extension is linked &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next you will be prompted to `Select SSH configuration file to update'. I use the first option that will store it under my local user&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PvgG3RH5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kjn7j5jy3r0jsnk0cg0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PvgG3RH5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kjn7j5jy3r0jsnk0cg0e.png" alt="Select SSH configuration file to update"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You will see this pop-up. Select &lt;code&gt;Open Config&lt;/code&gt; and change the &lt;code&gt;Host&lt;/code&gt; from the ip address to a friendly name like &lt;code&gt;my-vs-code-vm&lt;/code&gt;. I highly recommend doing this!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BCh8smhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yawbfy1k1z21pojh0o1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BCh8smhC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yawbfy1k1z21pojh0o1e.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Config file before:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ebBti4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dkr655s1vo3j9b559kof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ebBti4M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dkr655s1vo3j9b559kof.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Config file after:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uB4Jytbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/axkwfidfo2c02di5fi48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uB4Jytbs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/axkwfidfo2c02di5fi48.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Actually do the SSH connection
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the VS Code Command Palette again (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;code&gt;Remote-SSH: Connect to Host...&lt;/code&gt; this time and select our config &lt;code&gt;my-vs-code-vm&lt;/code&gt; and the rest should be straight forward.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>azure</category>
      <category>ssh</category>
      <category>azurevm</category>
    </item>
    <item>
      <title>Azure Alerts -&gt; Secure Webhook -&gt; Azure Functions with Authentication</title>
      <dc:creator>John Friesen</dc:creator>
      <pubDate>Sat, 14 Nov 2020 19:26:21 +0000</pubDate>
      <link>https://dev.to/superjohn140/azure-alerts-secure-webhook-azure-functions-with-authentication-364</link>
      <guid>https://dev.to/superjohn140/azure-alerts-secure-webhook-azure-functions-with-authentication-364</guid>
      <description>&lt;h1&gt;
  
  
  Azure Alerts -&amp;gt; Secure Webhook -&amp;gt; Az Functions with Auth
&lt;/h1&gt;

&lt;p&gt;I have been trying to implement Security in Azure Functions a lot recently and in the past but unfortunately, I can never accomplish it based on Microsoft documentation alone.&lt;/p&gt;

&lt;p&gt;So, I am creating this article to help anyone trying to do the same with a nice rundown of how to set up a secure webhook between Azure Monitoring Alerts and an Azure Function HTTP endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Create an Azure function in your Subscription. I am calling my functions &lt;strong&gt;Alert-Action-Function&lt;/strong&gt;. Any plan should work to accomplish this as we will only be creating 1 HTTP trigger function and enabling Authentication/Authorization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Run time .NET Core 3.1&lt;/li&gt;
&lt;li&gt;Consumptions plan&lt;/li&gt;
&lt;li&gt;Windows OS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Enable&lt;/strong&gt; function &lt;strong&gt;Authentication/Authorization&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open your function resource and go to the section Settings and open Authentication/Authorization. Than turn &lt;strong&gt;App Service Authentication to On&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpcb35nf11rhgsn62mxvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpcb35nf11rhgsn62mxvz.png" title="Enable function Authentication/Authorization" alt="Enable function Authentication/Authorization"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set &lt;strong&gt;Action to take when the request is not authenticated&lt;/strong&gt; to &lt;strong&gt;Log in with Azure Active Directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxr7by81ahw1a1kcdb3di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxr7by81ahw1a1kcdb3di.png" title="App Service Athentication config Part 1" alt="App Service Athentication config Part 1"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under  Authentication Providers click the &lt;strong&gt;Azure Active Directory Not Configured&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23thxzzqbnqup6fkwy1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F23thxzzqbnqup6fkwy1i.png" title="App Service Athentication config Part 2" alt="App Service Athentication config Part 2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under &lt;strong&gt;Management Mode&lt;/strong&gt; select &lt;strong&gt;Express.&lt;/strong&gt; Notice the &lt;strong&gt;Create App&lt;/strong&gt; field, this will provide you with an auto-generated App Registry name (I will be adding “AD-App” on the end to make it more clear).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftioc1whueqvmw2jwrzmk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftioc1whueqvmw2jwrzmk.png" title="Active Directory App Authentication config" alt="Active Directory App Authentication config"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now click ok and save. Now we have enabled the Authentication part of our function&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3. Add a HTTP Trigger function
&lt;/h2&gt;

&lt;p&gt;... to do tests on your setup. I like to write to blob storage so I can view the request body if needed, also b/c you can use this to see if the request is finished in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I do this:&lt;/strong&gt; Azure Monitoring with Application Insights and diagnostic settings setup properly will take around 5 mins to let you see logs and around 2 mins for metrics...  and that is on a good day for Azure.&lt;/p&gt;

&lt;p&gt;GitHub repo page for this code &lt;a href="https://github.com/Mexicoder/AzureFunctionRequestToBlob" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    using System;
    using System.IO;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.Azure.WebJobs.Extensions.Storage;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Logging;
    using Microsoft.Azure.Storage.Blob;
    /*
    ************************************************
    NOTE:
        make sure you have your AzureWebJobsStorage Environmental Variable is set when trying to run
        AND
        make sure you add this package

        dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage

    ************************************************
    */

    namespace Company.Function
    {
        public static class HttpTrigger_test_blob_store
        {
            [FunctionName("HttpTrigger_test_blob_store")]
            public static async Task&amp;lt;IActionResult&amp;gt; Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                [Blob("blobverifycontainer")] CloudBlobContainer outputContainer,
                ILogger log)
            {
                log.LogInformation("C# HTTP trigger function processed a request.");

                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

                /// write to the blob storage
                await outputContainer.CreateIfNotExistsAsync();
                var blobName = Guid.NewGuid().ToString();
                var cloudBlockBlob = outputContainer.GetBlockBlobReference(blobName);
                await cloudBlockBlob.UploadTextAsync(requestBody);

                // return blob name for easy lookup
                return new OkObjectResult(blobName);
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Configure your AD App registration.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In &lt;strong&gt;Azure Active Directory -&amp;gt; App registrations&lt;/strong&gt; find and open the name from step 2.4 (the express auto-generated name if you didn’t change it) &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fropykumtprch9208gbkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fropykumtprch9208gbkr.png" title="Azure AD App Registration" alt="Azure AD App Registration"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maker sure to add yourself as the Owner&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiuep5mrqhavzlx3iki71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fiuep5mrqhavzlx3iki71.png" title="Ensure Azure AD Service principle Ownership" alt="Ensure Azure AD Service principle Ownership"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now go to &lt;strong&gt;Manifest&lt;/strong&gt; and you will be adding to the App Roles array in the JSON editor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftzxg6bvasguajqhqst41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftzxg6bvasguajqhqst41.png" title="Azure Sercive Principle Manifest Edit" alt="Azure Sercive Principle Manifest Edit"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace with provided JSON.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"appRoles": [
    {
        "allowedMemberTypes": [
            "Application"
        ],
        "description": "This is a role for Action Groups to join",
        "displayName": "ActionGroupsSecureWebhook",
        "id": "e14442ab-8bd5-47be-90af-695c413d9761 REPLACE WITH NEW GUID",
        "isEnabled": true,
        "lang": null,
        "origin": "Application",
        "value": "ServiceClient"
    }
],
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;BUT make sure to replace the id with a new GUID. If you don’t you will get this error!&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Febqgmo23yqj4rb9n65y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Febqgmo23yqj4rb9n65y8.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Things to Note!!!&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;don’t worry about the tab formatting, after save and you come back it will be done for you. Just make sure your JSON is valid)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;IMPORTANT: if you mess up the **appRoles&lt;/strong&gt; and try to edit it later you may need to first set IsEnabled to “false”, save and then make your changes. This is something I found out the hard way.**&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. ALSO, ensure this (Integrity Check)
&lt;/h2&gt;

&lt;p&gt;Make sure that the &lt;strong&gt;Application ID URL&lt;/strong&gt; has been assigned to the base URL of your Azure Function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If it has not&lt;/strong&gt; this will an error when linking this AD App Registration to the Secure Webhook (you will get an azure notification that doesn’t give you a useful message and just says &lt;code&gt;“undefined” error&lt;/code&gt;. (I was only able to see the real error was when I when into chrome devtools to investigate the corresponding Network call.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhznyaliizx8tvdb31u7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhznyaliizx8tvdb31u7.png" title="Azure App Service Integrity Check" alt="Azure App Service Integrity Check"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Create Azure Function to Alert on
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I created a little NoiseMaker project to be an easy way to test Azure Monitor Alerts in general. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link this to Application Insights&lt;/strong&gt;. I named mine NoiseMaker as well.&lt;/li&gt;
&lt;li&gt;If nothing is passed to the query string it will return a 418 (“I’m a teapot”. Look it up, it’s real)&lt;/li&gt;
&lt;li&gt;Github code is &lt;a href="https://github.com/Mexicoder/AzureFunctionNoiseMaker" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace Company.Function
{
    public static class HTTP_Noise_Maker
    {
        [FunctionName("HTTP_Noise_Maker")]
        public static async Task&amp;lt;IActionResult&amp;gt; Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function *NoiseMaker* processed a request.");

            string pass = req.Query["pass"];
            string notfound = req.Query["notfound"];

            if (pass == "true")
            {
                var result = new ObjectResult("I'M OK 😁");
                result.StatusCode = StatusCodes.Status200OK;
                return result;
            }
            else if (notfound == "true")
            {
                var result = new ObjectResult("I'M NOT FOUND 😲");
                result.StatusCode = StatusCodes.Status404NotFound;
                return result;
            }
            else
            {
                var result = new ObjectResult("I'M A TEA POT 🍵");
                result.StatusCode = StatusCodes.Status418ImATeapot;
                return result;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Create your alert
&lt;/h2&gt;

&lt;p&gt;Go to Azure Monitor&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftufp5uuapujtr5k4z4vk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftufp5uuapujtr5k4z4vk.png" title="Create new Alert Rule" alt="Create new Alert Rule"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select Resource. I am using the NoiseMaker&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvt8mfq5tx6g9s235cpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvt8mfq5tx6g9s235cpl.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the Condition. Server Requests are what we want to catch when a 418 happens. (You can do the same for other HTTP response codes as well)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvblf2tp6b08g221o6gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdvblf2tp6b08g221o6gf.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuvz5zfwklkhh0wrdefv2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuvz5zfwklkhh0wrdefv2.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now Create the Action Group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvr2v7gzs5mzwq5be96kd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvr2v7gzs5mzwq5be96kd.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give it a name and add the Secure Webhook Action and Create&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmwgsetsq5lw9hkwohkuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmwgsetsq5lw9hkwohkuw.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now just finish the Alert Creation form with a Name, Description, Severity and make sure Enabled is checked. Should look like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv0cqn1s8k20bjt0t6vy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv0cqn1s8k20bjt0t6vy4.png" title="image_tooltip" alt="alt_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Finally, test it
&lt;/h2&gt;

&lt;p&gt;Trigger the NoiseMaker API endpoint a couple of times (either with a browser or Postman), wait a couple of minutes for the alert to show up on the Monitoring Alert page. Then go to the Storage Account linked to your “Alert-Action-Function” you created before and you should see a new blob in “blobverifycontainer” Container.&lt;/p&gt;

&lt;p&gt;Let me know this tutorial worked out for you in the comments below. This is my first Dev.to article and I hope it helps but If improvements need to be made (or I just used too many pictures haha) let me know.&lt;/p&gt;

&lt;p&gt;Happy Monitoring &lt;/p&gt;

</description>
      <category>azure</category>
      <category>azuread</category>
      <category>azurealerts</category>
      <category>azuremonitor</category>
    </item>
  </channel>
</rss>
