<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>DevOps on Azure Readiness starts here...</title>
        <link>http://localhost:1313/tags/devops/</link>
        <description>Recent content in DevOps on Azure Readiness starts here...</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <lastBuildDate>Sat, 29 Nov 2025 00:00:00 +0000</lastBuildDate><atom:link href="http://localhost:1313/tags/devops/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Using GitHub Copilot Agent Mode to vibe code a Python shooting game</title>
            <link>http://localhost:1313/post/using-github-copilot-agent-mode-to-vibe-code-a-python-shooting-game/</link>
            <pubDate>Fri, 28 Nov 2025 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/using-github-copilot-agent-mode-to-vibe-code-a-python-shooting-game/</guid>
            <description>&lt;p&gt;For about a year now, I&amp;rsquo;ve been teaching a lot on &lt;a class=&#34;link&#34; href=&#34;https://github.com/copilot&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;GitHub Copilot&lt;/a&gt; as part of my Microsoft role. Our program offers 2 different learning paths, one created by the Microsoft Content developers, &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/training/paths/accelerate-app-development-using-github-copilot/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;AZ-2007&lt;/a&gt;, and the other one is managed by GitHub Content team, known as &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/training/paths/copilot/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;GH-300&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;If you know my approach to teaching tech a bit, which a learner in my class lately called &lt;strong&gt;inspiring through technology&lt;/strong&gt;, it means I&amp;rsquo;m trying to explain as much as possible through compelling, live demos. After walking learners through different GitHub Copilot features such as documenting/explaining code, generate application code (on different development frameworks), but also Azure CLI, CI/CD pipeline, Dockerfile, YAML, JSON and alike, I usually close with &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Agent Mode&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Having showed the first time in April when GitHub Copilot was still in preview, I usually show a demo where the Agent Mode builds me an ASP.NET webapp, modifies the Welcome home page, creates some sample employee data in a json-file, which then gets displayed in a table view in the webapp. If time allows, I also ask to then migrate everything into a SQLite setup, which brings in more complexity such as Entity Framework, SQL data migration steps and interaction with Azure KeyVault, since I specify I want to run this in Azure SQL, but not allowing connection strings in my appsettings.json.&lt;/p&gt;&#xA;&lt;p&gt;(Now that I think about it, it might be another great blog post to write on in the near future&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;Earlier this week however, I came up with a new scenario, asking Agent Mode to develop a &lt;em&gt;shooter game&lt;/em&gt; using Python code, bringing me back to my youth in the mid-80&amp;rsquo;s when I was playing such games on my first 486-PC.&lt;/p&gt;&#xA;&lt;h2 id=&#34;agent-mode-prompt&#34;&gt;Agent Mode Prompt&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;The prompt I used was this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;*&lt;span class=&#34;s2&#34;&gt;&amp;#34;as a kid, I played arcade games a lot. I want to build a Python app, which tests me on my shooting reflexes. Help me developing a game which does the following:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;1. aks for player name input&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;2. bottom middle of the game screen shows a shooter &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;3. anywhere random on screen appears a target&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;4. player uses the space bar to simulate a shoot&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;5. calculate the time between the target appearing and player pressing the space bar to shoot&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;6. if that time is less than 0.3 sec, player wins, otherwise computer wins&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;7. show a &amp;#34;&lt;/span&gt;YOU WIN&lt;span class=&#34;s2&#34;&gt;&amp;#34; or &amp;#34;&lt;/span&gt;YOU ARE TOO SLOW&lt;span class=&#34;s2&#34;&gt;&amp;#34; dpeending on the outcome&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104211.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode Prompt Used&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;agent-mode-processing&#34;&gt;Agent Mode Processing&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;From here, the &lt;strong&gt;Agent started rolling&amp;hellip;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Confirming with some sort of understanding what I asked for, followed by  &lt;em&gt;creating 3 todos&lt;/em&gt;:&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Set Up Python Environment&lt;/li&gt;&#xA;&lt;li&gt;Creating the Reflex Shooting Game&lt;/li&gt;&#xA;&lt;li&gt;Testing the Game&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104237.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode Starting&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;This process took less than &lt;strong&gt;1 minute&lt;/strong&gt;, can you imagine? From there, it continued with providing detailed instructions on how to the game works.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104336.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Game Playing Instructions&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Next, it also had a list of features included:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104353.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Game Features Included&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Time to start the game!!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104413.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Start Game&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Which allowed me to play exactly as I asked for. When I was too slow, it would tell me&amp;hellip;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104424.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Too Slow&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;And several attempts later, I finally managed to win a game!!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/Screenshot2025-11-29-104503.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;You Win&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;I thought after using GitHub Copilot for training our customers and showing capabilities using live demos for about 5 hours per class, as well as using it for a lot of &amp;ldquo;coding&amp;rdquo; tasks as part of my role as trainer, mainly creating more demo scenarios (see &lt;a class=&#34;link&#34; href=&#34;https://aka.ms/trainer-demo-deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Trainer-Demo-Deploy&lt;/a&gt; to get an idea what that means&amp;hellip;), I thought I&amp;rsquo;d seen it all.&lt;/p&gt;&#xA;&lt;p&gt;Yet, &lt;strong&gt;it keeps suprising me every single day when I try something new.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;If I had access to this technology in the mid 80&amp;rsquo;s, I guess I would have spent more time learning about coding than playing games&amp;hellip; although this game is actually pretty addicting already. Time to wrap up this post and go play a bit more! And feel 12 years old again.&lt;/p&gt;&#xA;&lt;p&gt;If you want to see some similar version of this templategame in action, head over to &lt;a class=&#34;link&#34; href=&#34;https://github.com/petender/vibeshooter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;my github repo&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using GitHub Copilot Agent Mode to transform ARM templates to BICEP</title>
            <link>http://localhost:1313/post/using-github-copilot-agent-mode-to-transform-arm-templates-to-bicep/</link>
            <pubDate>Sat, 12 Jul 2025 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/using-github-copilot-agent-mode-to-transform-arm-templates-to-bicep/</guid>
            <description>&lt;p&gt;Over the last few months, I&amp;rsquo;ve been working on an exciting project for our Microsoft Technical Trainer team, known as &lt;a class=&#34;link&#34; href=&#34;https://aka.ms/trainer-demo-deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&amp;ldquo;Trainer-Demo-Deploy&amp;rdquo;&lt;/a&gt;, a catalog of Azure end-to-end demo scenarios, available as an Open-Source project.&lt;/p&gt;&#xA;&lt;p&gt;While we managed to get about 50 templates live, there can never be enough scenarios to integrate into your Azure classes or POC activities if you ask me. One of the challenging tasks in the project is not only coming up with demo ideas, but also creating the actual artifacts, such as Azure templates with Bicep, sample apps and sample data.&lt;/p&gt;&#xA;&lt;p&gt;I had an &lt;a class=&#34;link&#34; href=&#34;https://azure.microsoft.com/en-us/products/site-recovery/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Site Recovery Services&lt;/a&gt; scenario from a few years ago, written in modular ARM templates. With Bicep providing a great way to &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/decompile?tabs=azure-cli&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;transform your ARM to Bicep&lt;/a&gt;, I could have gone through each template file and convert them. Have done several of those over the last few months.&lt;/p&gt;&#xA;&lt;p&gt;But out of teaching &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/training/paths/accelerate-app-development-using-github-copilot/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;AZ-2007 Accelerate app development by using GitHub Copilot&lt;/a&gt;, where I integrate a - what I think amazing demo on how to use Agent mode to deploy a sample web app - I started thinking about testing if &lt;strong&gt;Agent Mode&lt;/strong&gt; could help me with this transformation project.&lt;/p&gt;&#xA;&lt;p&gt;Fact I&amp;rsquo;m dedicating a blog post to it, is mainly to confirm it worked amazingly well, as well as sharing my excitement and some steps of what the process looked like. Hopefully this post inspires you to start embracing &lt;a class=&#34;link&#34; href=&#34;https://github.blog/ai-and-ml/github-copilot/agent-mode-101-all-about-github-copilots-powerful-mode/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;strong&gt;GitHub Copilot Agent Mode&lt;/strong&gt;&lt;/a&gt; into your own tasks.&lt;/p&gt;&#xA;&lt;h2 id=&#34;my-starting-templates&#34;&gt;My starting templates&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;My original setup was pretty straightforward, having a folder &amp;ldquo;templates&amp;rdquo;, in which I have modular templates for each part of my Azure Site Recovery Vault deployment.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Each templates hold a snippet of ARM / JSON structured code to deploy one or more Azure Resources.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-templates.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Current ARM Templates&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;I opened up the folder structure in my Visual Studio Code, and opened GitHub Copilot, selecting &lt;strong&gt;Agent Mode&lt;/strong&gt;. I &lt;em&gt;clearly described in a prompt&lt;/em&gt;, what I wanted the Agent to perform as tasks. I didn&amp;rsquo;t provide much detail to be honest, as initially, I was merily experimenting to try and find out if Agent could actually help with this, or how far it would go in the process.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;agent-mode-prompt&#34;&gt;Agent Mode Prompt&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;The prompt I used was this:&#xA;&lt;em&gt;for each file in the templates folder, convert to azure bicep. create a new bicep file for each, keeping the same name as the original json file. the azuredeploy should be transformed to main.bicep. validate all pointers to all new bicep files to be correct&amp;quot;&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-prompt.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode Prompt Used&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;From here, the &lt;strong&gt;Agent started rolling&amp;hellip;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Informing me about the different steps it would take to handle this task, starting with &lt;em&gt;exploring the templates folder to see all the files that need to be converted&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-start.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode Starting&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;5&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Followed by going more in-depth into each and every template JSON file&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Followed by &lt;em&gt;starting the conversion process to Bicep files&lt;/em&gt;. Before doing that, it also highlighted it would check the Azure deployment best practices (although I didn&amp;rsquo;t explicitly asked to do that, nice one! )&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-start-filecheck.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode inspecting files&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;7&#34;&gt;&#xA;&lt;li&gt;It felt like it &lt;em&gt;learned&lt;/em&gt; from the best practices, by starting with the azuredeploy.json conversion to main.bicep first. It could also be that it started with this, because I mentioned this in the prompt itself.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode creating main.bicep&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;8&#34;&gt;&#xA;&lt;li&gt;As the main.bicep conversion took a bit longer than normal - although it was only running over it for about a minute, it &lt;em&gt;prompted&lt;/em&gt;, asking if it was ok to continue. Obviously, I confirmed to &lt;strong&gt;continue&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-continue.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode pending task&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;9&#34;&gt;&#xA;&lt;li&gt;From here, it nicely continued looping through all smaller json-files, and transforming them into corresponding bicep-files. Since each file typically had only 1 or 2 resource references, the conversion went really smooth.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-templates-list.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode conversion&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;10&#34;&gt;&#xA;&lt;li&gt;After a bit, it had finished the transformation of each ARM to Bicep, and &lt;em&gt;started on updating the template links&lt;/em&gt;, as I asked for in my prompt, to also validate the references to all the deployment files.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep-templatelinks.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode updating file links&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;11&#34;&gt;&#xA;&lt;li&gt;With all references updated, it continued with its own &lt;em&gt;error checking&lt;/em&gt;, and validating the different templates for any possible errors. Even more interesting, &lt;strong&gt;without me specifying&lt;/strong&gt;, it detected an error in the &lt;strong&gt;azure.yaml&lt;/strong&gt;, which I had in my project folder, from a baseline started AZD-template we use to create all our Trainer-Demo-Deploy scenarios.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep-azure-yaml.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode create azure.yaml&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;12&#34;&gt;&#xA;&lt;li&gt;Last, it also created a &lt;em&gt;main.parameters.json&lt;/em&gt;, to capture any specific Parameters for the deployment.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep-main.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode create main.parameters.json&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;13&#34;&gt;&#xA;&lt;li&gt;From here, it went back to &lt;em&gt;validating&lt;/em&gt; the Bicep templates again, where it detected a few different issues. (I didn&amp;rsquo;t check in detail what got identified as issue, as it didn&amp;rsquo;t prompt me to validate anything on my end&amp;hellip;); based on the &lt;em&gt;next informational message&lt;/em&gt;, it struggled with missing an output for &lt;strong&gt;myWorkspaceKey&lt;/strong&gt;, in the deploy-infra.bicep file.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images2025-07-04-bicep-error.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode validating infra&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;14&#34;&gt;&#xA;&lt;li&gt;&lt;em&gt;Chewing&lt;/em&gt; a bit on the myWorkspaceKey problem, it managed to find its own work-around to solve the problem. It even provided a clear explaining on why, identifying the dependency on the parent template.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep-error.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode detecting an issue&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;15&#34;&gt;&#xA;&lt;li&gt;Feeling we were close to the end of the process, it &lt;strong&gt;continued amazing&lt;/strong&gt; me, as it now also created its &lt;strong&gt;own documentation&lt;/strong&gt; in a BICEP_CONVERSION_SUMMARY.md Markdown file, in which it listed up what conversations it did.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-bicep-conversion.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode creating conversion documentation&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;16&#34;&gt;&#xA;&lt;li&gt;With all that out of the way, it ran another &lt;strong&gt;final validation&lt;/strong&gt; to conclude there were no more issues, closing the task with creating another README-BICEP.md file, describing how to run the actual deployment, using AZD.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-readme.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode creating readme&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;17&#34;&gt;&#xA;&lt;li&gt;Finally, the Agent &lt;strong&gt;provided a description within the Chat Agent window&lt;/strong&gt;, clearly describing all the tasks accomplished with the necessary file references included:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-taskvalidation1.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode Chat description&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;18&#34;&gt;&#xA;&lt;li&gt;As well as adding additional details on the &lt;strong&gt;task validation&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-taskvalidation.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode creating task validation&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;19&#34;&gt;&#xA;&lt;li&gt;Finishing with describing different ways on how to run the actual deployment, using &lt;strong&gt;azd&lt;/strong&gt;, &lt;strong&gt;Azure CLI&lt;/strong&gt; and &lt;strong&gt;Azure PowerShell&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-ready.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Agent Mode explaining how to run the deployment&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;20&#34;&gt;&#xA;&lt;li&gt;Last step was running the deployment, and this worked without any hiccups!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2025-07-04-works.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Deployment completed&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;As mentioned earlier, I didn&amp;rsquo;t intend to go through this process as part of writing a blog post. Yet, the fact that the &lt;strong&gt;GitHub Copilot Agent Mode&lt;/strong&gt; happily suprised me once more, I wanted to share my joy and excitement about this.&lt;/p&gt;&#xA;&lt;p&gt;Starting from a &lt;em&gt;somewhat complex&lt;/em&gt; JSON ARM template folder with about 10 modular arm-json files, it managed to nicely convert all of them into the new Bicep template language, with only a few minor issues throughout the process. Without asking assistance or halting the process, it ran its own troubleshooting and issue resolution, resulting in a 100% successful transformation.&lt;/p&gt;&#xA;&lt;p&gt;Apart from the technical success of the task, what surprised me even more, is &lt;strong&gt;it only took the agent barely 5 minutes&lt;/strong&gt; and only had to &lt;strong&gt;prompt me twice&lt;/strong&gt; during the whole process!!&lt;/p&gt;&#xA;&lt;p&gt;If you want to see this template in action, head over to &lt;a class=&#34;link&#34; href=&#34;https://github.com/petender/azd-asrdemo&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;my github repo&lt;/a&gt; and continue your Azure learning journey with more demo scenarios at &lt;a class=&#34;link&#34; href=&#34;https://aka.ms/trainer-demo-deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Trainer-Demo-Deploy&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Azure Spring Clean - Application Insights - Inside Out</title>
            <link>http://localhost:1313/post/azure-spring-clean---application-insights---inside-out/</link>
            <pubDate>Thu, 06 Mar 2025 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/azure-spring-clean---application-insights---inside-out/</guid>
            <description>&lt;p&gt;&lt;img src=&#34;../images/AzureSpringClean2025-logo.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Azure Spring Clean&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Hey folks,&lt;/p&gt;&#xA;&lt;p&gt;Welcome to #AzureSpringClean, an initiative from &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/wedoazure&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Joe Carlyle&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/tamstar1234&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Thomas Thornton&lt;/a&gt;&lt;/strong&gt; which celebrates its 4th edition this year. I&amp;rsquo;m thrilled to be part of this again for the 3nd time this year. My &lt;a class=&#34;link&#34; href=&#34;https://www.007ffflearning.com/post/azure-spring-clean-demystifying-service-principal-and-managed-identities/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;first article&lt;/a&gt; had &lt;strong&gt;security in mind, explaining the difference between Azure Service Principals and Managed Identity&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;My 2nd article focused on &lt;strong&gt;understand DevSecOps, and how you can optimize security in your application deployment lifecycle, by &amp;ldquo;shifting left&amp;rdquo;&lt;/strong&gt;.&#xA;(&lt;a class=&#34;link&#34; href=&#34;https://www.007ffflearning.com/post/azure-spring-clean---devsecops-and-shifting-left-to-publish-secure-software/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://www.007ffflearning.com/post/azure-spring-clean---devsecops-and-shifting-left-to-publish-secure-software/&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;p&gt;Where now for this 3rd article, where moving more towards the &amp;rsquo;end&amp;rsquo; of the traditional DevOps cycle, discussing &lt;strong&gt;Operations and Monitoring, by using Azure Application Insights&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In today&amp;rsquo;s digital age, monitoring and maintaining the health of applications is crucial for ensuring optimal performance and user satisfaction. &lt;strong&gt;Azure Monitor&lt;/strong&gt;, a comprehensive monitoring solution from Microsoft, offers a suite of tools to help developers and IT professionals keep their applications running smoothly. One of the key components of Azure Monitor is Application Insights, which provides deep insights into application performance and user behavior. In this article, we&amp;rsquo;ll explore &lt;strong&gt;Application Insights&lt;/strong&gt;, its features, and how it integrates with Azure Monitor to deliver a robust monitoring solution.&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview-of-azure-monitor&#34;&gt;Overview of Azure Monitor&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Azure Monitor is a powerful platform that provides end-to-end monitoring for your applications and infrastructure. It collects and analyzes telemetry data from various sources, including Azure resources, applications, and on-premises environments. Azure Monitor helps you understand how your applications are performing and proactively identifies issues affecting them. It encompasses several services, including Log Analytics, Application Insights, and Azure Monitor for VMs, among others.&lt;/p&gt;&#xA;&lt;h2 id=&#34;application-insights-overview&#34;&gt;Application Insights Overview&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Application Insights is an application performance management (APM) service within Azure Monitor. It is designed to monitor live applications, providing real-time insights into their performance and usage. By integrating with OpenTelemetry, Application Insights offers a vendor-neutral approach to collecting and analyzing telemetry data, enabling comprehensive observability of your applications. It supports various programming languages and frameworks, including .NET, Java, Node.js, and client-side JavaScript.&lt;/p&gt;&#xA;&lt;h2 id=&#34;key-features-of-application-insights&#34;&gt;Key Features of Application Insights&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;End-to-End Transactions&lt;/strong&gt;: Application Insights provides a detailed view of end-to-end transactions, allowing you to trace and diagnose issues across different components of your application4. This feature supports time scrubbing, enabling you to filter and analyze specific time periods in more detail.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Performance and Failures&lt;/strong&gt;: The service offers tools to monitor performance and identify failures. It includes features like the Roles tab, which preserves role selection while navigating from the application map, and the availability tool, which helps you monitor the availability and responsiveness of your application endpoints.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Application Map&lt;/strong&gt;: The application map provides a visual overview of your application&amp;rsquo;s architecture and the interactions between its components. It includes features like &amp;ldquo;Zoom to fit&amp;rdquo; and grouped nodes to make the map easier to read and navigate4.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Live Metrics&lt;/strong&gt;: With Live Metrics Stream, you can monitor your application&amp;rsquo;s health metrics in real-time, even while deploying changes. This feature helps you quickly identify and address issues as they arise.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Smart Detection&lt;/strong&gt;: Application Insights uses machine learning to detect anomalies in your application&amp;rsquo;s performance and sends alerts with embedded diagnostics. This proactive approach helps you address potential issues before they impact users.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Integration with Azure Services&lt;/strong&gt;: Application Insights integrates seamlessly with other Azure services, such as Azure DevOps, Azure Kubernetes Service (AKS), and Azure Functions. This integration allows you to monitor and manage your applications using a unified platform.&lt;/p&gt;&#xA;&lt;h2 id=&#34;integration-with-azure-monitor&#34;&gt;Integration with Azure Monitor&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Application Insights is a core component of Azure Monitor, and its integration with other Azure Monitor services enhances its capabilities. For example, you can use Log Analytics to query and analyze telemetry data collected by Application Insights. This integration provides a comprehensive view of your application&amp;rsquo;s performance and helps you identify trends and patterns.&lt;/p&gt;&#xA;&lt;p&gt;Azure Monitor also offers out-of-the-box insights for various Azure resources, such as virtual machines, containers, and storage accounts. These insights are built on workbooks, which are interactive reports that you can customize to meet your specific needs. By leveraging these insights, you can gain a deeper understanding of your application&amp;rsquo;s performance and make data-driven decisions to optimize it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-cases-and-benefits&#34;&gt;Use Cases and Benefits&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Proactive Monitoring&lt;/strong&gt;: Application Insights enables proactive monitoring of your applications, helping you identify and address issues before they impact users. This proactive approach improves the overall user experience and reduces downtime.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Performance Optimization&lt;/strong&gt;: By providing detailed insights into your application&amp;rsquo;s performance, Application Insights helps you identify bottlenecks and optimize your code. This optimization leads to faster and more efficient applications.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;User Behavior Analysis&lt;/strong&gt;: Application Insights offers tools to analyze user behavior, such as usage patterns, session durations, and user flows. This analysis helps you understand how users interact with your application and identify areas for improvement.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Cost Management&lt;/strong&gt;: By monitoring resource usage and performance, Application Insights helps you manage costs more effectively. You can identify underutilized resources and optimize their usage to reduce costs.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Application Insights provides insights into potential security issues, such as failed login attempts and suspicious activities. By monitoring these activities, you can enhance the security of your applications and protect sensitive data.&lt;/p&gt;&#xA;&lt;h2 id=&#34;seeing-it-in-action&#34;&gt;Seeing it in action&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Now that we covered the theoretical part, let&amp;rsquo;s have a look at what all this looks like from a sample application workload perspective.&lt;/p&gt;&#xA;&lt;p&gt;I am using a sample app which I have been using in all my Azure Architecture (AZ-305) and Developing Azure Solutions (AZ-204) classes over the years, when talking about Application Insights. It recently got moved to a new &amp;rsquo;trainer&amp;rsquo; platform out of a project I&amp;rsquo;m leading within Microsoft, based on Azure Developer CLI deployments for trainer demo scenarios. (If you&amp;rsquo;re new to AZD, you should definitely check it out!)&lt;/p&gt;&#xA;&lt;p&gt;Head over to &lt;a class=&#34;link&#34; href=&#34;https://aka.ms/trainer-demo-deploy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Trainer-Demo-Deploy&lt;/a&gt; and search for &lt;strong&gt;tollbooth&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;![Trainer Demo Deploy - Tollbooth](../images/Screenshot 2025-03-07 060247.png)&lt;/p&gt;&#xA;&lt;p&gt;Select the Tollbooth Serverless Architecture with Azure Functions card, and follow the &lt;strong&gt;Template Details&lt;/strong&gt; instructions to get it deployed. Most important is having the Scenario-specific prereqs running on your local machine, as well as having Azure Developer CLI as well.&lt;/p&gt;&#xA;&lt;p&gt;from &lt;strong&gt;azd up&lt;/strong&gt;, it will ask you for your Azure subscription and the region where you want to deploy the scenario. Give it about 12-15min, and the fun can start&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/tollbooth.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Tollbooth Architecture&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;As you can see from the architecture, it is using several different services in Azure, to replicate a Tollbooth / Automated Parking Lot management application. This will generate &amp;rsquo;traffic&amp;rsquo; to be monitored through Application Insights.&lt;/p&gt;&#xA;&lt;p&gt;Using this demo scenario, you showcase a solution for processing vehicle photos as they are uploaded to a storage account, using serverless technologies on Azure. The license plate data gets extracted using Azure Cognitive Service, and stored in a highly available NoSQL data store on Azure CosmosDB for exporting. The data export process will be orchestrated by a serverless Azure Functions and EventGrid-based component architecture, that coordinates exporting new license plate data to file storage using the Blob Trigger Function. Each aspect of the architecture provides live dashboard views, and more detailed information can be viewed real-time from Azure Application Insights.&lt;/p&gt;&#xA;&lt;h4 id=&#34;azure-app-service---upload-images&#34;&gt;Azure App Service - Upload Images&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The &lt;strong&gt;starting point&lt;/strong&gt; of the demo scenario, is the &lt;strong&gt;imageupload&lt;/strong&gt; web application. This simulates car traffic for 500 vehicles, which should be enough to see live data dashboard views across all architecture components. Now there is a 1-2 minute delay before the metrics actually show up in the dashboards.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Navigate to the imageupload website URL (&lt;a class=&#34;link&#34; href=&#34;https://%25youralias%25tbimageuploadapp.azurewebsites.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://%youralias%tbimageuploadapp.azurewebsites.net/&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/generate_traffic.png&#34; alt=&#34;Generate Car Traffic WebApp&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Click the &lt;strong&gt;Upload Images&lt;/strong&gt; button - this loops to 500&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4 id=&#34;azure-storage-account&#34;&gt;Azure Storage Account&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Once the upload process is complete, navigate to the &lt;strong&gt;%youralias%datalake&lt;/strong&gt; Azure Storage Account.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Navigate to the &lt;strong&gt;Images&lt;/strong&gt; Container; notice the different image files, generated from the web application. Feel free to select a file and download it, to show it contains a car image with a license plate. You might open different images, to showcase there are different cars (Note: in reality, we used 10 different images, looping 50 times, to generate 500 images in total)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/datalake-images.png&#34; alt=&#34;Storage Account Container with car images&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;h4 id=&#34;azure-functions&#34;&gt;Azure Functions&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;Once the images are available in Azure Storage Account, an Azure Function &lt;strong&gt;ProcessImage&lt;/strong&gt;, which sends image files to &lt;strong&gt;Azure Cognitive Service&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/processimage.png&#34; alt=&#34;Azure Function with Blob Trigger&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Use this Azure Function to explain the concept of triggers (HTTP, Blob Trigger,&amp;hellip;) and how the starting point is &amp;lsquo;something happens in Blob&amp;rsquo;, which kicks off the Function.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Once the data comes back from &lt;strong&gt;Cognitive Service&lt;/strong&gt;, it triggers the next Azure Function &lt;strong&gt;SavePlateData&lt;/strong&gt;, which stores text values in Azure CosmosDB.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/saveplatedata.png&#34; alt=&#34;SavePlateData Function&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;h4 id=&#34;event-grid--topics--subscriptions&#34;&gt;Event Grid / Topics &amp;amp; Subscriptions&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;Notice that this Function is based on an Event Trigger, coming from Event Grid (%youralias%eventgridtopic). From the Azure Portal, navigate to &lt;strong&gt;Event Grid&lt;/strong&gt;, and select &lt;strong&gt;Topics&lt;/strong&gt;. Open the EventGridTopic resource**.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/eventgridtopic.png&#34; alt=&#34;Event Grid Topic with data&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Highlight the Event Grid Topic is related to the &lt;strong&gt;Event Grid Subscription&lt;/strong&gt; called &lt;strong&gt;SavePlate&lt;/strong&gt;, which triggers the actual Azure Function &lt;strong&gt;SavePlateData&lt;/strong&gt;. This also clarifies the use case, where Event Grid acts as the orchestrator, watching over certain events to occur, and based on the settings of the subscription, it triggers an Azure Function process.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/eventgridtopic.png&#34; alt=&#34;Event Grid Subscription&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Select the &lt;strong&gt;SavePlate&lt;/strong&gt; Event Grid Subscription from the dashboard view. This opens a new dashboard, showing the hierarchy of the event:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Event Grid Topic : %youralias%eventgridtopic&lt;/li&gt;&#xA;&lt;li&gt;Metrics - showing the 500 events&lt;/li&gt;&#xA;&lt;li&gt;Azure Function - SavePlateData&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/eventsubscription_hierarchy.png&#34; alt=&#34;Event Grid Subscription&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;While talking about Event Grid Subscriptions, there is actually a 2nd subscription in place, which watches over the Azure Blob Storage events. Navigate back to the Azure Storage Account &lt;strong&gt;%youralias%tbdatalake&lt;/strong&gt;, and navigate to &lt;strong&gt;Events&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/datalake-events.png&#34; alt=&#34;Datalake Events&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Notice the Event Grid Subscription &lt;strong&gt;blobtopicsubscription&lt;/strong&gt;, which is a &lt;strong&gt;Web Hook&lt;/strong&gt;, meaning, it gets triggered based on HTTP requests.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;From within the Event Subscription detailed dashboard, showing &lt;strong&gt;Metrics&lt;/strong&gt; initially, navigate to &lt;strong&gt;Filters&lt;/strong&gt;. Highlight the subscription is based on filter &lt;strong&gt;Create Blob&lt;/strong&gt;. This is what triggers the Azure Function, based on &amp;ldquo;a new blob is getting created&amp;rdquo;. All other events in the Storage Account are getting bypassed/neglected.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/eventsubscription_blobcreated.png&#34; alt=&#34;Blob Created Event Subscription Filter&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;h4 id=&#34;cosmos-db&#34;&gt;Cosmos DB&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;Open the %youralias%cosmosdb. Navigate to &lt;strong&gt;Data Explorer&lt;/strong&gt;. Show the LicensePlates Database, which has 2 different Containers &lt;strong&gt;NeedsManualReview&lt;/strong&gt; (not used in this demo scenario), and &lt;strong&gt;Processed&lt;/strong&gt;. The Processed Container is where the actual text information returned from Azure Cognitive Service is getting stored.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/cosmosdb_licenseplates.png&#34; alt=&#34;CosmosDB database&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Under Processed, open the &lt;strong&gt;Items&lt;/strong&gt; view. This shows the different document items in the container, each document having the license plate, image file name and timestamp in a JSON document format.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/cosmosdb_items.png&#34; alt=&#34;CosmosDB database&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;h4 id=&#34;application-insights&#34;&gt;Application Insights&#xD;&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;Navigate to Application Insights, opening the &lt;strong&gt;%youralias%tbappinsights&lt;/strong&gt; resource. Go to &lt;strong&gt;Live Metrics&lt;/strong&gt;. This will show a lot of different views about the ongoing processing of Functions, Events, Storage activity and more.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_livemetrics.png&#34; alt=&#34;App Insights - Live Metrics&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;p&gt;Note: If you see the &amp;ldquo;Demo&amp;rdquo; page, it means you don&amp;rsquo;t have live metrics (anymore), and the processing of the car images is completed already. To generate (new) live data, go back to the imageupload web app, and generate new images by pressing the &amp;ldquo;Upload images&amp;rdquo; button.&lt;/p&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_livemetrics_notavailable.png&#34; alt=&#34;App Insights - No Live Metrics Data&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;From within the base charts, scroll down to &lt;strong&gt;Servers&lt;/strong&gt; section. There should be anywhere between 2-10 visible. Explain that these &amp;ldquo;servers&amp;rdquo; reflect the different Azure Functions instances getting triggered, and handling the image processing from blob to CosmosDB.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_servers.png&#34; alt=&#34;App Insights - Servers&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Zoom in on the &lt;strong&gt;sample telemetry&lt;/strong&gt; to the right hand side. Explain how the different API-streams of the application topology are visible here. Notice how it shows the Azure Function call &amp;ldquo;SavePlateData&amp;rdquo;, as well as interaction with &amp;ldquo;Azure Computer Vision&amp;rdquo;, etc&amp;hellip;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_sampletelemetry.png&#34; alt=&#34;App Insights - Sample Telemetry&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Depending when you opened the Live Metrics view, the sample telemetry should have a &lt;strong&gt;red&lt;/strong&gt; item &lt;strong&gt;Dependency&lt;/strong&gt;, which simulates an issue from the Azure Function to Cognitive Service, showing you the details of the &lt;strong&gt;API POST Action call&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_dependency_error.png&#34; alt=&#34;App Insights - Dependency Error&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Next, select &lt;strong&gt;Application Map&lt;/strong&gt; within Application Insights.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_application_map.png&#34; alt=&#34;App Insights - Application Map&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Explain the usage of Application Map, describing the 2 different views here. The first view &lt;strong&gt;%youralias%events&lt;/strong&gt;, shows the number of running (Azure Functions) instances, with different metrics (performance details). The Events are representing communication with Azure CosmosDB. It shows the &lt;strong&gt;number of database calls&lt;/strong&gt;, as well as the &lt;strong&gt;average performance&lt;/strong&gt; between the Event Functions and CosmosDB.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_application_map_events.png&#34; alt=&#34;App Insights - Events&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Select the &lt;strong&gt;value&lt;/strong&gt; metric in the middle between Events and CosmosDB, to open the more detailed view. This opens a blade to the right-hand side of the Azure Portal, exposing many more details about the processing of events. It shows details about the CosmosDB instance, as well as performance details of each CosmosDB action (GET, Create Document, Get Collection, etc&amp;hellip;)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Click on &lt;strong&gt;Investigate Performance&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.comrob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_performance.png&#34; alt=&#34;App Insights - Performance Details&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Use this detailed dashboard to explain the different sections, reflecting chart representations of actual &lt;strong&gt;Log Analytics Queries&lt;/strong&gt;. This can be demoed by selecting &lt;strong&gt;View Logs&lt;/strong&gt; from the top menu, selecting a section, and opening it in Log Analytics.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;https://raw.githubusercontent.com/rob-foulkrod/TollBooth/main/Demoguide/TOLLBOOTH/appinsights_performance_loganalytics.png&#34; alt=&#34;App Insights - Log Analytics KQL&#34; style=&#34;width:70%;&#34;&gt;&#xD;&#xA;&lt;br&gt;&lt;/br&gt;&#xD;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Application Insights, as part of Azure Monitor, is a powerful tool for monitoring and optimizing the performance of your applications. Its comprehensive features, seamless integration with other Azure services, and real-time insights make it an essential component of any modern monitoring strategy. By leveraging Application Insights, you can ensure that your applications run smoothly, deliver a great user experience, and achieve your business goals.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Sending Emails from Azure DevOps using PowerShell and Azure LogicApps</title>
            <link>http://localhost:1313/post/sending-emails-from-ado-pipelines-using-powershell/</link>
            <pubDate>Sun, 03 Mar 2024 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/sending-emails-from-ado-pipelines-using-powershell/</guid>
            <description>&lt;p&gt;Hi Readers,&lt;/p&gt;&#xA;&lt;p&gt;This post is merely for myself, documenting all the steps I needed to go through to be able to send emails from a PowerShell script, as part of an Azure DevOps YAML pipeline flow. And since I was documenting it for our internal application, I thought it would hopefully help someone out there looking for a similar solution.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-not-using-the-built-in-email-notification-system&#34;&gt;Why not using the built-in Email Notification system&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Azure DevOps provides &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/azure/devops/organizations/notifications/about-notifications?view=azure-devops&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;email notification features&lt;/a&gt;, but this comes with a few assumptions. The biggest one being the receiver(s) should be Project Members. Which was not the case in my scenario, since I want to send out deployment status emails, at the start of a pipeline and when completed successfully, to external recipients.&lt;/p&gt;&#xA;&lt;h2 id=&#34;whats-wrong-with-marketplace-extensions&#34;&gt;What&amp;rsquo;s wrong with Marketplace Extensions?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In my Classic Release Pipelines, I relied on &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://marketplace.visualstudio.com/items?itemName=kasunkodagoda.sendgrid-email&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Sendgrid&lt;/a&gt;&lt;/strong&gt;, and it actually worked OK, and with the limited amount of emails (up to 100/daily), it was a free service on top.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2024-03-03_11-24-15.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;SendGrid Classic Settings&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Since I was migrating the full project away from Classic Release Pipelines to YAML, and wanted to customize the email flow a bit more, I started looking into other options. Keeping all functionality within my Azure subscription, was also a benefit.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-new-setup-architecture&#34;&gt;The new setup architecture&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In short, the new setup architecture is based on the following:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Azure LogicApp with HTTP Trigger, sending an Outlook 365 email based on parameters to an external recipient&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;ADO Release Pipeline using YAML tasks&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;One of the tasks is using Azure Powershell, to compose and send the email&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s detail each step a bit more.&lt;/p&gt;&#xA;&lt;h3 id=&#34;deploying-and-composing-the-azure-logic-app&#34;&gt;Deploying and composing the Azure Logic App&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;The starting point is deploying the Azure Logic App, and composing the workflow steps.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Deploy an Azure Logic App resource using the Consumption plan (pay per trigger)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Once deployed, open the &lt;strong&gt;Logic App Designer&lt;/strong&gt;, and choose **When an HTTP request is received&amp;quot; as trigger.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;When it asks for a JSON Schema in the Request Body, you can use the &amp;lsquo;use sample payload to generate schema&amp;rsquo;, by entering the different parameters you need for the email details itself, in the JSON format. In my setup, I have the following fields:&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Message, which is the actual body of the email, and gets send along as a PowerShell script object;&lt;/li&gt;&#xA;&lt;li&gt;Subject, which contains the actual subject of the email, and also coming from the PowerShell script object;&lt;/li&gt;&#xA;&lt;li&gt;To, which contains the recipient&amp;rsquo;s email address, and passed on from the PowerShell script object;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;#34;properties&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;#34;Message&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;#34;Subject&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;#34;To&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;#34;type&amp;#34;: &amp;#34;object&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;../images/2024-03-03_11-42-02.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;HTTP Trigger JSON Schema&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;4&#34;&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;When you save the Logic App with this step, it will provide you with the unique LogicApp HTTP Trigger URL to connect to. Save this URL on the side, since you need it later in the PowerShell script.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Add a new step to the workflow, choosing &lt;strong&gt;Send an Email&lt;/strong&gt;. Authenticate with your Office 365 credentials (although other security options such as Service Principal might be required in your production setup).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The required fields for this step are Body, Subject and To. Mapping with the 3 property fields from the HTTP Trigger. Note, I created the property &amp;ldquo;Message&amp;rdquo;, instead of calling it &amp;ldquo;Body&amp;rdquo;, since the full HTTP Trigger JSON response we get in through the PowerShell script, is known as &amp;ldquo;Body&amp;rdquo;. So I made some mistakes there initially in not getting the correct information mapped as expected.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The nice thing with Logic Apps, is that any next step in the workflow, can reuse input values from any previous step.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;For the Body-parameter of the Send an email step, we want to use the &amp;ldquo;Message&amp;rdquo; content from the HTTP Trigger response. Therefore, click in the &lt;strong&gt;Body-field&lt;/strong&gt;, which will open the &lt;strong&gt;Dynamic content&lt;/strong&gt; window. From here, it will show all known properties from the &amp;ldquo;When an HTTP request is received&amp;rdquo; step in the workflow.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2024-03-03_11-47-25.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Dynamic COntent&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;9&#34;&gt;&#xA;&lt;li&gt;&lt;strong&gt;Select&lt;/strong&gt; the necessary fields from the Dynamic content, and map them with the required fields of the Send an Email task:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Body -&amp;gt; Message&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Subject -&amp;gt; Subject&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;To -&amp;gt; To&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This is all for now to get the Logic App configured.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-powershell-script-for-sending-emails&#34;&gt;The PowerShell script for sending emails&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;The idea is that the PowerShell script gets triggered from the YAML pipeline task. I initially tried using the Inline option, but that didn&amp;rsquo;t recognize the here-strings (gets explained later if you don&amp;rsquo;t know what this means&amp;hellip;) as well as some other limitations. I also didn&amp;rsquo;t like having the actual Message/Body details - for which I&amp;rsquo;m using HTML and tables - in my YAML pipeline. So using the ScriptPath option was much cleaner. And also allowing a more flexible scenario, where I could call different &amp;lsquo;sendemail&amp;rsquo;.ps1 scripts, depending on the specifics of the pipeline tasks.&lt;/p&gt;&#xA;&lt;p&gt;Let me first explain the high-level setup of the script:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;define param settings, capturing/transferring the parameters from the YAML task ScriptArguments&lt;/li&gt;&#xA;&lt;li&gt;create a variable for the LogicApp HTTP Trigger Url&lt;/li&gt;&#xA;&lt;li&gt;create a variable for the LogicApp HTTP Trigger Body data, holding the &amp;ldquo;To&amp;rdquo;, &amp;ldquo;Subject&amp;rdquo; and &amp;ldquo;Message&amp;rdquo; content&lt;/li&gt;&#xA;&lt;li&gt;create a variable for the LogicApp HTTP Trigger Headers information&lt;/li&gt;&#xA;&lt;li&gt;create a variable for the actual Invoke-RestMethod, sending all previous info along&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Here are some of the snippets for each component of the script:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. define param settings, capturing/transferring the parameters from the YAML task ScriptArguments&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;param (&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    [string]$BuildDefinitionName,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    [string]$To&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    )&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2. create a variable for the LogicApp HTTP Trigger Url&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$logicappUrl = &amp;#34;https://yourlogicappurl .centralus.logic.azure.com:443/workflows/1676b43cc2904b/triggers/manual/paths/invoke?api-version=2016-10-01&amp;amp;sp=%2Ftriggers%2Fmanual%2Frun&amp;amp;sv=1.0&amp;amp;sig=OK-Z_dgspUufMWMlBL531&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3. create a variable for the LogicApp HTTP Trigger Body data, holding the &amp;ldquo;To&amp;rdquo;, &amp;ldquo;Subject&amp;rdquo; and &amp;ldquo;Message&amp;rdquo; content&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$body = @{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         To = $To&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         Subject = @&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MTTDemoDeploy - $BuildDefinitionName - Deployment Kicked Off Successfully&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;@&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        Message = @&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &amp;lt;actual email body content here - where I used a combination of text, HTML and CSS for the email layout&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;@                &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Note the usage of the @&amp;quot; &amp;ldquo;@, which is known as &lt;strong&gt;here-strings&lt;/strong&gt;. Here-strings allow you to define multiline strings without needing to escape special characters or use concatenation.&lt;/p&gt;&#xA;&lt;p&gt;In this code snippet, I&amp;rsquo;m using a here-string to define the value of the Subject property in the $body hash table. The @&amp;rdquo; at the beginning indicates the start of the here-string. The text within the here-string (between the @&amp;quot; and the closing &amp;ldquo;@) is preserved exactly as written, including line breaks and any special characters.&#xA;The variable $BuildDefinitionName is interpolated within the here-string, and corresponds to a param object as defined at the start of the script. This will hold the actual ScriptArguments object from the YAML pipeline steps later.&lt;/p&gt;&#xA;&lt;p&gt;Also note the positioning of the &amp;ldquo;@ all the way at the start of the line, as the here-strings cannot recognize and spaces or tabs before it - this will throw an error when running the script. (Told you I really wanted to document all by observations and issues before I got this working smoothly&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;4. create a variable for the LogicApp HTTP Trigger Headers information&lt;/strong&gt;&#xA;When you configured the HTTP Trigger step in the LogicApp, it shows a little popup message, saying the trigger expect the Header to have the content type of application/json. this is how you specify this.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$headers = @{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;#39;Content-Type&amp;#39; = &amp;#39;application/json&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;5. create a variable for the actual Invoke-RestMethod, sending all previous info along&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;$sendemail = @{&#xA;Uri = $logicappUrl&#xA;Method = &amp;lsquo;POST&amp;rsquo;&#xA;Headers = $headers&#xA;Body = $body | ConvertTo-Json&#xA;}&lt;/p&gt;&#xA;&lt;p&gt;Invoke-RestMethod @sendemail&lt;/p&gt;&#xA;&lt;p&gt;Eventually, save this file as &lt;strong&gt;start_email.ps1&lt;/strong&gt; or other filename that works for you, and make sure it is part of the ADO Repo where you have the YAML pipeline. To keep it a bit structured, I created a new subfolder &lt;strong&gt;Email&lt;/strong&gt; with another subfolder &lt;strong&gt;.ado&lt;/strong&gt; in which I stored the file.&lt;/p&gt;&#xA;&lt;p&gt;REPO-ROOT&#xA;/Email&#xA;/.ado&#xA;/start_email.ps1&lt;/p&gt;&#xA;&lt;p&gt;I call this script at the start of the YAML pipeline, but also created a finish_email.ps1, which I&amp;rsquo;m calling at the end of the YAML pipeline successful completion.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-yaml-pipeline-task&#34;&gt;The YAML pipeline task&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;With both LogicApp and PowerShell script created, the last step in the process is defining the YAML PowerShell task which sends the trigger and necessary parameters to the PowerShell script.&lt;/p&gt;&#xA;&lt;p&gt;Like any YAML Pipeline, this is just another task, relying on some variables and task settings.&lt;/p&gt;&#xA;&lt;p&gt;I created 2 new variables, one for the EmailDomain and one for the full EmailAddress:&lt;/p&gt;&#xA;&lt;p&gt;variables:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;name: pipelineName&#xA;value: $(Build.DefinitionName)&lt;/li&gt;&#xA;&lt;li&gt;name: EmailDomain&#xA;value: &amp;lsquo;@company.com&amp;rsquo;&lt;/li&gt;&#xA;&lt;li&gt;name: recipientEmail&#xA;value: &amp;ldquo;${{parameters.User}}`$(EmailDomain)&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;Critical here&lt;/strong&gt; is the usage of the &lt;strong&gt;`&lt;/strong&gt; in the 2nd part of the value setting. Since the &lt;strong&gt;@&lt;/strong&gt; in the emaildomain is breaking the string, known as &amp;ldquo;splatting&amp;rdquo;, I needed to add that character to avoid this issue.&lt;/p&gt;&#xA;&lt;p&gt;Next, within the stage / jobs / steps level of the YAML pipeline, I inserted the following task:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;steps:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: AzurePowerShell@5&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        displayName: &amp;#39;Email - Deployment Kicked Off&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          azureSubscription:  &amp;#39;&amp;lt;yourADOServiceConnection&amp;gt;&amp;#39; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          resourceGroupName: &amp;#39;RG where you deployed the LogicApp&amp;#39; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          azurePowerShellVersion: &amp;#39;LatestVersion&amp;#39; #required to use the latest version of Azure PowerShell&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          ScriptType: &amp;#39;filePath&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          ScriptPath: $(System.DefaultWorkingDirectory)/Email/.ado/start_email.ps1  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          ScriptArguments: &amp;#39;-BuildDefinitionName:$(pipelineName) -To:$(recipientEmail)&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The &lt;strong&gt;ScriptArguments&lt;/strong&gt; is the crucial step if you ask me, as it contains the different parameters you want to pass on to the PowerShell script; also, the parameters needed to map with the JSON properties in the HTTP Trigger step of the Logic App. (again, I needed multiple attempts to get all this working, hence my documentation on how I got this all glued together&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;It picks up a parameter called &lt;strong&gt;BuildDefinitionName&lt;/strong&gt;, corresponding to the same param-name at the start of the PowerShell script, which contains the value of the variable pipelineName I defined earlier in the YAML pipeline.&#xA;The 2nd parameter I&amp;rsquo;m passing on is the &lt;strong&gt;To&lt;/strong&gt;-field, which corresponds with the composed recipientEmail variable in the YAML pipeline.&lt;/p&gt;&#xA;&lt;p&gt;That&amp;rsquo;s pretty much it!!&lt;/p&gt;&#xA;&lt;p&gt;FYI, it it also possible to send more YAML pipeline parameters or variables along with the ScriptArguments, such as deployment output or passwords or any other. For example, I have a pipeline where I&amp;rsquo;m creating an Azure Container Registry with a random name, as well as a unique created password for the admin.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;##vso[task.setvariable variable=acrname]$acrname&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;which I then send on to the PowerShell script from the ScriptArguments like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ScriptArguments: &amp;#39;-BuildDefinitionName:$(pipelineName) -To:$(recipientEmail) -acrname:$(acrname) -location:${{ parameters.Location }} -adminPassword:&amp;#34;$(genPassword)&amp;#34;&amp;#39;  #needs quotes because split characters&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h1 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;Apart from the built-in ADO notification emails for the most &amp;lsquo;common&amp;rsquo; scenarios when using pipelines, your DevOps project might need other emails to be sent, as part of your pipeline flow. Where you could use existing Marketplace tools such as SendGrid or other, I decided to come up with my own PowerShell-based script, interacting with Azure LogicApps.&lt;/p&gt;&#xA;&lt;p&gt;While the setup involves jumping to several hoops, it is not all that difficult (easy to say once it all works, after spending half a day of troubleshooting at different levels - of which the main one was my rusty PowerShell skills&amp;hellip;) once all pieces fall in place.&lt;/p&gt;&#xA;&lt;p&gt;Let me know if you want to give this a try and share me your results!&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Trigger a YAML Pipeline from a Classic Release Pipeline in Azure DevOps</title>
            <link>http://localhost:1313/post/trigger-yaml-pipeline-from-classic-release-in-ado/</link>
            <pubDate>Sat, 30 Sep 2023 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/trigger-yaml-pipeline-from-classic-release-in-ado/</guid>
            <description>&lt;p&gt;Hi y&amp;rsquo;all!&lt;/p&gt;&#xA;&lt;p&gt;Over the last 18 months, I&amp;rsquo;ve been developing a tool for our internal Microsoft Trainer team, allowing them to deploy trainer demo scenarios in Azure using a Blazor Front-End web app, connecting to Azure DevOps pipelines using REST API calls.&lt;/p&gt;&#xA;&lt;p&gt;At the start of the project, Classic Release pipelines were still common, since YAML was too new, and rather unknown. However, over the last few months, more and more I was thinking of shifting from Classic to YAML Pipelines. But - although the app isn&amp;rsquo;t that big or complex - it means connecting to different API endpoints for YAML, reading out the status of ongoing pipelines would be different, and getting a listing of all deployed pipelines for a given trainer, would also be different.&lt;/p&gt;&#xA;&lt;p&gt;So you hear me coming&amp;hellip; I don&amp;rsquo;t want to rewrite the whole app, as it also means rewriting all Classic Pipelines to YAML syntax. While I know the export to YAML is available, I didn&amp;rsquo;t want to minimize the effort, nor like the time-pressure. As in the end, what is the added value to the end-user? (If that is not spoken like a true developer, I have no idea&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;Being more and more familiar with triggering DevOps Pipelines from REST API calls, I thought about the following&amp;hellip; &lt;strong&gt;what if I could create a Classic Release Pipeline, which triggers a YAML Pipeline?&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;After searching around a little bit on how curl would help here, it seemed possible, since there is a Classic Pipeline Task for #BASH.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-yaml-pipeline-components&#34;&gt;The YAML Pipeline components?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In order to trigger the YAML Pipeline from the Classic Release, you need to capture the YAML Pipeline Id, as well as capturing any parameter values you need to provide.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The YAML Pipeline Id; this is also known as the &lt;em&gt;definitionId&lt;/em&gt;, and can be found by going to the YAML Pipeline under the ADO Pipelines section, and checking the URL in the address bar - it will be something like &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://dev.azure.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://dev.azure.com/&lt;/a&gt;&lt;ORGANIZATION&gt;/&lt;PROJECT&gt;/_build?definitionId=101&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Take note of the definitionId number, as you need it in the Bash script later.&lt;/li&gt;&#xA;&lt;li&gt;In my example, the YAML Pipeline has a section with parameters, where I&amp;rsquo;m using the trainer alias, the Service Connection/Azure Subscription info and the selected Azure Region for the deployment, like this:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;parameters:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- name: MTTAlias&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  type: string&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  default: petender&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- name: azureSubscription&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  type: string&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  default: MTTAliasServiceConnection&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- name: Location&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  type: string&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  default: westus&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Everything else in the YAML Pipeline is rather standard, triggering an &lt;strong&gt;Azure Bicep template deployment&lt;/strong&gt;, using an &lt;strong&gt;Azure CLI Task&lt;/strong&gt; and pointing to the &lt;strong&gt;Bicep file (/.azure/main.bicep)&lt;/strong&gt;, like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-gdscript3&#34; data-lang=&#34;gdscript3&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;variables&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;RunName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${{parameters.MTTAlias}}&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;RGName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;MTTDemoDeployRG${{parameters.MTTAlias}}TBOOTH&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;dotnetFunctionZipPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Build&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArtifactStagingDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dotnet&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;nodeFunctionZipPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Build&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArtifactStagingDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;stages&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Infra&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;jobs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;job&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Bicep&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;steps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;checkout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AzureCLI&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deployBicep&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;azureSubscription&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parameters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;azureSubscription&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;scriptType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;pscore&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;scriptLocation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;inlineScript&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;inlineScript&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;az&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;create&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parameters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;az&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deployment&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;create&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;./&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FastCar&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TollBooth&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;azure&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bicep&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RGName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parameters&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;namingConvention&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;${{parameters.MTTAlias}}&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parameters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Location&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}}&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;o&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;properties&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;outputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ConvertFrom&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Json&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PSObject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Properties&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ForEach&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;Object&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Value&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;##vso[task.setvariable variable=$keyname;isOutput=true]$value&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;           &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-38-32.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;YAML Pipeline Example&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;composing-the-classic-release-pipeline&#34;&gt;Composing The Classic Release Pipeline&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;Create a new Classic Release Pipeline, with a single Stage &amp;ldquo;Azure Infra&amp;rdquo;, and add the &lt;strong&gt;#Bash Script&lt;/strong&gt; as Task&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-43-12.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Classic Release Pipeline Example&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;Select &lt;strong&gt;Inline&lt;/strong&gt; as Type, and in the Script box, copy the following script, which does the following:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;PIPELINE_ID = the number of the YAML PipelineId&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PIPELINE_ID=&amp;#34;101&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;URL = the URL of the actual DevOps YAML Pipeline REST API to use&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;URL=&amp;#34;$(SYSTEM.TEAMFOUNDATIONCOLLECTIONURI)$(SYSTEM.TEAMPROJECTID)/_apis/pipelines/$PIPELINE_ID/runs?api-version=6.0-preview.1&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;echo $URL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;Next, I specify 3 variables, for which the values (the $() notation) refer to Classic Release Pipeline Variables (These are passed on from the Blazor Web App to the Classic Pipeline).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MTTAliasValue=$(MTTAlias)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ServiceConnectionValue=$(ServiceConnection)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;LocationVarValue=$(LocationVar)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ul&gt;&#xA;&lt;li&gt;Next, I specify the actual &lt;strong&gt;curl&lt;/strong&gt; command to use, where I use the System.AccessToken Variable to allow OAuth authentication by the system account, followed by specifying we&amp;rsquo;re sending a JSON header, and the actual JSON snippet which holds the data to pass along to the YAML pipeline - finding the correct syntax to capture the variable values from earlier, was the biggest challenge here, taking a few failed attempts when triggering the pipeline :)&amp;hellip;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -s --request POST \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; -u &amp;#34;:$(System.AccessToken)&amp;#34; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; --header &amp;#34;Content-Type: application/json&amp;#34; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; --data &amp;#39;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;#34;resources&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;repositories&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           &amp;#34;self&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &amp;#34;refName&amp;#34;: &amp;#34;refs/heads/main&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;#34;templateParameters&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;MTTAlias&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${MTTAliasValue}&amp;#34;&amp;#39;&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;azureSubscription&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${ServiceConnectionValue}&amp;#34;&amp;#39;&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;Location&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${LocationVarValue}&amp;#34;&amp;#39;&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&amp;#39; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; $URL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The full #Bash script looks as follows:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PIPELINE_ID=&amp;#34;101&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;URL=&amp;#34;$(SYSTEM.TEAMFOUNDATIONCOLLECTIONURI)$(SYSTEM.TEAMPROJECTID)/_apis/pipelines/$PIPELINE_ID/runs?api-version=6.0-preview.1&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;echo $URL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MTTAliasValue=$(MTTAlias)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ServiceConnectionValue=$(ServiceConnection)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;LocationVarValue=$(LocationVar)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -s --request POST \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; -u &amp;#34;:$(System.AccessToken)&amp;#34; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; --header &amp;#34;Content-Type: application/json&amp;#34; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; --data &amp;#39;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;#34;resources&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;repositories&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           &amp;#34;self&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;               &amp;#34;refName&amp;#34;: &amp;#34;refs/heads/main&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   },&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &amp;#34;templateParameters&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;MTTAlias&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${MTTAliasValue}&amp;#34;&amp;#39;&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;azureSubscription&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${ServiceConnectionValue}&amp;#34;&amp;#39;&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       &amp;#34;Location&amp;#34;: &amp;#34;&amp;#39;&amp;#34;${LocationVarValue}&amp;#34;&amp;#39;&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&amp;#39; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; $URL&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-44-00.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Classic Release Pipeline Bash Task&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;specify-the-correct-permissions-on-the-yaml-pipeline&#34;&gt;Specify the Correct Permissions on the YAML Pipeline&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Remember we used the System.AccessToken variable, which refers to the Build-In DevOps System Process. In order to make this Classic Release Pipeline trigger work, the Build-In account must have &lt;strong&gt;Queue Build&lt;/strong&gt; permissions on the YAML Pipeline.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Navigate to the YAML Pipeline&lt;/li&gt;&#xA;&lt;li&gt;Click the elipsis (the 3 dots) at the end of the Pipeline line, and from the context menu, select &lt;strong&gt;Manage Security&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-46-45.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Manage Security&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;Select the &lt;strong&gt;&lt;ADOProjectName&gt; Build Service&lt;/strong&gt; Group, and set &lt;strong&gt;Allow&lt;/strong&gt; for the &lt;strong&gt;Queue Builds&lt;/strong&gt; permission&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-48-09.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Allow Queue Build&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;running-the-pipeline&#34;&gt;Running the Pipeline&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;Trigger the Classic Release Pipeline, wait for it to complete&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-50-53.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Trigger Classic Release&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;With the Classic Release completed, navigate to the YAML Pipeline, and see this one is getting triggered / already running&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-09-30_18-51-56.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Trigger YAML Pipeline&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In this post, I walked you through a use case within Azure DevOps, where it might be useful to build an integration between both Pipeline worlds, Classic Releases and YAML Pipeline Releases. By using a #Bash script with Curl to call the YAML Pipeline REST API endpoint, as well as passing some parameters in a JSON structure, it is possible to trigger YAML Pipelines from a Classic Release Pipeline.&lt;/p&gt;&#xA;&lt;p&gt;I am using this scenario to give myself some time to continue updating the development work on the Blazor Front-end, pointing to YAML Pipelines only at some point, but for now, it gives me the flexibility to keep the same Classic URL Endpoints for my REST APIs, why gradually setting up new YAML Pipelines, migrating Classic to YAML etc&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>You do not have permissions to view this directory or page after publishing to Azure App Service</title>
            <link>http://localhost:1313/post/you-do-not-have-permissions-error-after-publishing-to-azure-app-services/</link>
            <pubDate>Sun, 30 Apr 2023 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/you-do-not-have-permissions-error-after-publishing-to-azure-app-services/</guid>
            <description>&lt;p&gt;Earlier this week, I got an interesting phenomenon when publishing a code update to an existing Azure App Service. As this was a small project, I&amp;rsquo;ve always been deploying updates in a manual way from &lt;strong&gt;right-click / publish&lt;/strong&gt; in Visual Studio. But than I said to myself, Peter, as a passionate DevOps engineer and trainer, just go out and create a pipeline for this.&lt;/p&gt;&#xA;&lt;p&gt;And that&amp;rsquo;s what happened.&lt;/p&gt;&#xA;&lt;p&gt;Running the release pipeline came back successful, but the site threw an error:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-25-45.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;App Service Error&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;I was like well, OK, no worries, let&amp;rsquo;s go back to the &lt;strong&gt;manual deployment&lt;/strong&gt; from Visual Studio for now. Only to find out that one didn&amp;rsquo;t succeed either anymore, just giving me a &lt;strong&gt;spinning&lt;/strong&gt; publishing task.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-30-12.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Publish task hang&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;So this was not really helping me further. Time to open up the &lt;strong&gt;App Service Logs&lt;/strong&gt; settings on the App Service to dig in.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-32-06.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;App Service Logs&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;After which I could check the live logs using &lt;strong&gt;App Service Log Stream&lt;/strong&gt; (notice the &lt;strong&gt;verbose&lt;/strong&gt; option to get immediate and full feedback&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-33-49.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Verbose Logs&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;2 things here got my attention:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;HTTP Error 403.13 Forbidden&lt;/li&gt;&#xA;&lt;li&gt;A default document is not configured for the requested URL&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;So it seems like the index.html I use in my app, couldn&amp;rsquo;t be found on the Web Server. Let&amp;rsquo;s validate with &lt;strong&gt;App Service Editor&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-37-59.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Verbose Logs&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Interesting&amp;hellip; so I have my drop folder with the application zip package and some other deployment artifacts, but not the actual application files in an extracted format. The &lt;strong&gt;drop&lt;/strong&gt; folder was also something that made me curious&amp;hellip; As that is what Azure DevOps is using to publish the package&amp;hellip; Let&amp;rsquo;s go back to my Azure DevOps Release pipeline and check something&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-41-07.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;App Service Release settings&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;EUREKA!!! Looks like Peter made a mistake here, by not setting the &lt;strong&gt;package file&lt;/strong&gt; to use. So what the ADO Pipeline does here, is just copying the /drop folder with the artifact into the Azure App Service, but not extracting it.&lt;/p&gt;&#xA;&lt;p&gt;This is what this setting should look like:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-43-46.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Select ZIP package&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_11-44-43.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Zip Package Selected&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;With these new changes, let&amp;rsquo;s run the release deployment again and see what happens&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-04-30_12-21-49.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Actual files got deployed&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;and the website is running as expected!&lt;/p&gt;&#xA;&lt;p&gt;Last check, validating if a new deployment from Visual Studio is running as expected again&amp;hellip; and that runs successful again too!&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In this post, I wanted to help you sharing some troubleshooting steps for Azure App Services. And also admitting I made a minor mistake in my ADO pipeline setup. So additional lesson learned: always doublecheck your setting when something doesn&amp;rsquo;t work anymore as it should be :)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Collecting Feedback in ADO work items from Office Forms</title>
            <link>http://localhost:1313/post/collecting-feedback-in-ado-work-items-from-office-forms/</link>
            <pubDate>Sun, 26 Mar 2023 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/collecting-feedback-in-ado-work-items-from-office-forms/</guid>
            <description>&lt;p&gt;Hey folks,&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m a fond user of Azure DevOps for testing application builds, running CI/CD pipelines to publish Azure demo scenarios and train our Microsoft global customers on it every few weeks out of AZ-400 training deliveries.&lt;/p&gt;&#xA;&lt;p&gt;One of the lesser-known, yet AWESOMELY POWERFUL features besides &amp;lsquo;running pipelines&amp;rsquo; is &lt;a class=&#34;link&#34; href=&#34;https://azure.microsoft.com/en-us/products/devops/boards/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Boards&lt;/a&gt;, providing an &lt;strong&gt;end-to-end project methodology platform&lt;/strong&gt; using Scrum, Agile, CMMI or custom approach.&lt;/p&gt;&#xA;&lt;p&gt;In this post, I mainly wanted to zoom in on the &lt;strong&gt;custom&lt;/strong&gt; capabilities, capturing feedback from employees - which got entered through an &lt;strong&gt;Office Forms&lt;/strong&gt; form, picked up by &lt;strong&gt;Azure Logic Apps&lt;/strong&gt;, and stored in a customized &lt;strong&gt;Azure Boards Work Item&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In short, the following steps are needed:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Create custom Office Forms with questions and fields to complete&lt;/li&gt;&#xA;&lt;li&gt;Create custom Azure DevOps Process Methodology containing the custom Work Item fields and form layout&lt;/li&gt;&#xA;&lt;li&gt;Create new Azure DevOps Project, linked to the custom Project Methodology&lt;/li&gt;&#xA;&lt;li&gt;Create Azure Logic Apps flow, mapping each custom field from Office Forms to the custom Work Item fields&lt;/li&gt;&#xA;&lt;li&gt;See it in action :)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Here we go&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-custom-office-forms-with-questions-and-fields-to-complete&#34;&gt;Create custom Office Forms with questions and fields to complete&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;The first step involves creating a custom &lt;a class=&#34;link&#34; href=&#34;https://support.microsoft.com/en-us/office/what-is-microsoft-forms-6b391205-523c-45d2-b53a-fc10b22017c8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Office Form&lt;/a&gt;, which is probably one of the easiest parts in the process. This is a free service within Microsoft Office Online, typically used for collecting user input, such as surveys, quizzes and polls, and all you need is a Microsoft Account such as Outlook.com, Hotmail.com or an organizational Office 365 account.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Browse to &lt;a class=&#34;link&#34; href=&#34;https://forms.office.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://forms.office.com&lt;/a&gt;, and select &lt;strong&gt;New Form&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Next, specify the different questions, together with the answer type (e.g. multiple choice, text field,&amp;hellip;)&#xA;I won&amp;rsquo;t cover the details on how to do this, as I think it&amp;rsquo;s self-explanatory.&lt;/li&gt;&#xA;&lt;li&gt;A sample form I&amp;rsquo;ll be using in this post looks like this:&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2023-03-26_18-51-25.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Office Form&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;With the Office Form ready, we can move on to the next step, creating a new custom ADO Process Methodology.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-custom-azure-devops-process-methodology&#34;&gt;Create custom Azure DevOps Process Methodology&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Azure DevOps provides several &lt;em&gt;Process Methodologies&lt;/em&gt;, such as Scrum, Agile, Basic, but also allows you to create customized versions of those. (More info on each process and how to choose is documented &lt;a class=&#34;link&#34; href=&#34;https://learn.microsoft.com/en-us/azure/devops/boards/work-items/guidance/choose-process?view=azure-devops&amp;amp;tabs=agile-process&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;on Microsoft Learn&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Log on to Azure DevOps with an Organizational admin account&lt;/li&gt;&#xA;&lt;li&gt;Select Azure DevOps (the logo in the upper left corner), and select &lt;strong&gt;Organization Settings&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Within the Settings menu, select &lt;strong&gt;Process&lt;/strong&gt; under the Boards section&#xA;&lt;img src=&#34;../images/2023-03-26_19-00-24.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Boards and Process&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;This shows a list of default Azure Boards processes (Basic, Agile, Scrum, CMMI)&#xA;&lt;img src=&#34;../images/2023-03-26_19-02-11.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Boards Process&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;In this example, we will build a new &lt;em&gt;custom deviation&lt;/em&gt; from the &lt;strong&gt;Scrum&lt;/strong&gt; process, but you can choose any you want. Hover the mouse over the Scrum process, and select the ellipsis (the 3 dots). From the context menu, select &lt;strong&gt;Create inherited process&lt;/strong&gt;&#xA;&lt;img src=&#34;../images/2023-03-26_19-04-30.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Create inherited process&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Provide a name and (optional) description for the process. I called mine &lt;strong&gt;Forms Test Process&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Once created, select the new process. This opens a list of &lt;strong&gt;Work Item types&lt;/strong&gt; such as Bug, Epic, Task and other. As the new Work Item we create is so custom, it doesn&amp;rsquo;t really matter which one to choose. If you have about 50% or more that&amp;rsquo;s identical to an existing Work Item, you can use that as a baseline.&#xA;&lt;img src=&#34;../images/2023-03-26_19-09-30.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Work Item Types&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Click &lt;strong&gt;New Work Item Type&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Provide a Name, Description, Icon, Icon Color of choice. Confirm by pressing the &lt;strong&gt;Create&lt;/strong&gt; button.&lt;/li&gt;&#xA;&lt;li&gt;Once created, select the new work item type. This opens the &lt;strong&gt;Layout&lt;/strong&gt; editor, where we will add custom fields, reflecting the different questions/items from the Office Form earlier.&lt;/li&gt;&#xA;&lt;li&gt;A Work Item is based on Tabs. In my example, I only use a single tab, called &lt;strong&gt;Details&lt;/strong&gt;. Know you can as many Tabs as needed. Within each Tab, the Work Item layout is built-up of 3 panes, a left, holding a Description field, the middle pane, holding Custom fields, and the right pane, which has Deployment, Development and Related Work as default items - at least in my setup.&lt;/li&gt;&#xA;&lt;li&gt;Add the custom fields you want to have on the Work Item, specifying the field type (e.g. I added an &lt;strong&gt;open question&lt;/strong&gt;, set as &lt;strong&gt;Text Multiple Lines&lt;/strong&gt;, as well as adding the &lt;strong&gt;Geography&lt;/strong&gt; and &lt;strong&gt;Category&lt;/strong&gt; as &lt;strong&gt;Text Single Line&lt;/strong&gt; items). These fields &lt;em&gt;somewhat&lt;/em&gt; correspond with the different items on the Office Form.&#xA;&lt;img src=&#34;../images/2023-03-26_19-13-39.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Work Item Type Customization&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Although there are a lot more customizations possible, I hope these basic steps are helping you building the baseline for what I want to guide you through in this post.&lt;/p&gt;&#xA;&lt;p&gt;We now have the Azure DevOps Process created, as well as the customized version of the Work Item we want to use. Let&amp;rsquo;s hook this up to a new Azure DevOps Project.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-new-azure-devops-project-linked-to-the-custom-process&#34;&gt;Create new Azure DevOps Project, linked to the custom Process&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;Click the &lt;strong&gt;Azure DevOps&lt;/strong&gt; logo (upper left corner), and press the &lt;strong&gt;+ New Project&lt;/strong&gt; button.&lt;/li&gt;&#xA;&lt;li&gt;Provide a Project Name, (optional) Description, Visibility. Next, click &lt;strong&gt;Advanced&lt;/strong&gt; to specify the Work Item Process. Click the &lt;strong&gt;Work Item Process&lt;/strong&gt; field and select the &lt;strong&gt;custom process&lt;/strong&gt; created earlier.&#xA;&lt;img src=&#34;../images/2023-03-26_19-22-57.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Create New Project&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Once the project got created, navigate to &lt;strong&gt;Boards&lt;/strong&gt;. Here, click &lt;strong&gt;New Work Item&lt;/strong&gt;, notice the new Work Item type is available.&#xA;&lt;img src=&#34;../images/2023-03-26_19-42-26.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Custom Work Item Type&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Select the new Work Item, which shows the detailed view. Notice the custom fields we added earlier are nicely showing up here.&#xA;&lt;img src=&#34;../images/2023-03-26_19-43-34.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Custom Work Item Type&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The flexibility we now have, is that the Work Item can be created from both the Office Form, as well as still being available from within Azure DevOps. (Note: while we added custom fields, I didn&amp;rsquo;t add any field content to choose from, such as EMEA,APAC,USA in the Geography field - which would a viable option). In my use case, the only way to create a new Work Item is through the Office Form, as no typical users got access to Azure DevOps to do that (Permissions :)).&lt;/p&gt;&#xA;&lt;p&gt;Awesome, we are now about &lt;strong&gt;3/4&lt;/strong&gt; through the process, with the remaining part being the &lt;strong&gt;creation of the flow, using Azure Logic Apps&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-an-azure-logic-app-flow-to-capture-office-forms-data-to-ado-work-item&#34;&gt;Create an Azure Logic App flow to capture Office Forms data to ADO Work Item&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;Log on to Azure with administrative permissions to create an Azure Logic App resource.&lt;/li&gt;&#xA;&lt;li&gt;When creating the Logic App, specify a unique name, Resource Group, Location and Plan (consumption would be OK).&#xA;&lt;img src=&#34;../images/2023-03-26_19-50-47.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Create Azure Logic Apps Resource&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Once the resource got created, it automatically opens &lt;strong&gt;Logic App Designer&lt;/strong&gt;, which allows for the setup of the actual flow. From the list of sample scenarios, select &lt;strong&gt;Blank Logic App&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_20-28-02.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Blank Logic App&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;In the &lt;strong&gt;Search connectors and triggers&lt;/strong&gt; field, search for &lt;strong&gt;Microsoft Forms&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Next, select &lt;strong&gt;When a new response is submitted&lt;/strong&gt; as trigger.&lt;/li&gt;&#xA;&lt;li&gt;In the Form Id field, select the Office Form name you used earlier.&#xA;&lt;img src=&#34;../images/2023-03-26_20-30-02.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Office Forms Trigger&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Click &lt;strong&gt;+ New Step&lt;/strong&gt; to add the next step in the Logic App flow.&lt;/li&gt;&#xA;&lt;li&gt;In the &lt;strong&gt;Search connectors and triggers&lt;/strong&gt; field, search for &lt;strong&gt;Azure DevOps&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;From the list of &lt;strong&gt;Actions&lt;/strong&gt;, select &lt;strong&gt;Create a new work item&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_20-32-57.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;ADO New work item action&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Complete the fields, selecting your &lt;strong&gt;DevOps Organization&lt;/strong&gt;, the &lt;strong&gt;DevOps Project&lt;/strong&gt; and the &lt;strong&gt;Work Item Type&lt;/strong&gt; as created earlier.&#xA;&lt;img src=&#34;../images/2023-03-26_20-34-42.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;ADO New work item action&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Now, we map the custom fields, by selecting &lt;strong&gt;Add new parameter&lt;/strong&gt;, and selecting &lt;strong&gt;Other Fields&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_20-41-17.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Parameters / Other Fields&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Within the little table of Other Fields (the key/value), select the &lt;strong&gt;Key&lt;/strong&gt; object; this opens the Logic Apps &lt;strong&gt;Dynamic Content&lt;/strong&gt;. Here, click the &lt;strong&gt;See more&lt;/strong&gt; option&#xA;&lt;img src=&#34;../images/23-03-26_20-42-29.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Dynamic Content&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;This is where Logic Apps is awesome. It allows you to select (all) previous fields from all previous steps in the flow process.&#xA;&lt;img src=&#34;../images/2023-03-26_20-44-52.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Dynamic Content Results&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Notice how the Forms information is returned as &lt;strong&gt;Body&lt;/strong&gt;, which is not what we need. We want to reach out each answer to each Form&amp;rsquo;s question, instead of the full body. To make this possible, we have to add another step in-between the Forms step and the Azure DevOps step.&lt;/li&gt;&#xA;&lt;li&gt;Click on the &lt;strong&gt;+&lt;/strong&gt; sign in-between both steps, and select &lt;strong&gt;Add New Action&lt;/strong&gt;. Search for &lt;strong&gt;Microsoft Forms&lt;/strong&gt; again. This time, it will show an action called &lt;strong&gt;Get Response Details&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_20-49-10.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Get Response Details&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;In the &lt;strong&gt;Forms Id&lt;/strong&gt; field, select the &lt;strong&gt;name of the Office Forms&lt;/strong&gt;; In the &lt;strong&gt;Response Id&lt;/strong&gt; field, click &lt;strong&gt;See More&lt;/strong&gt; and select &lt;strong&gt;List of Response notifcations Response id&lt;/strong&gt; from the Dynamic Content list of options.&#xA;&lt;img src=&#34;../images/2023-03-26_20-51-48.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Get Response Id&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;With that step added, return to the &lt;strong&gt;Create a work item&lt;/strong&gt; step in the Logic App Flow, and navigate to the &lt;strong&gt;Other Fields&lt;/strong&gt; section in the parameters. Select the &lt;strong&gt;Enter Key&lt;/strong&gt; field, which opens the &lt;strong&gt;Dynamic Content&lt;/strong&gt; blade again. This time, notice how the different response details (the Form&amp;rsquo;s questions) are visible.&#xA;&lt;img src=&#34;../images/2023-03-26_20-57-17.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Select Response details&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;From here, the idea is that you &amp;lsquo;map&amp;rsquo; each custom field object from the ADO Work Item, with a corresponding value from the Office Forms. For example, the &lt;strong&gt;work item &amp;ldquo;geography&amp;rdquo;&lt;/strong&gt; created earlier, maps with &lt;strong&gt;what is your geography&lt;/strong&gt; question I have on the form.&#xA;&lt;img src=&#34;../images/2023-03-26_20-58-49.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Map Response details&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Once done with all field mappings, &lt;strong&gt;Save&lt;/strong&gt; the Logic App.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This completes the configuration of the Azure Logic Apps (Note: there is more work needed if you have more fields&amp;hellip;)&lt;/p&gt;&#xA;&lt;p&gt;Which brings us to the last step&amp;hellip; &lt;strong&gt;seeing it in action&lt;/strong&gt;&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;testing-the-azure-devops-work-item-creation&#34;&gt;Testing the Azure DevOps Work Item creation&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;Return to the Office Form, and click &lt;strong&gt;Collect Responses&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_21-03-52.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Collect Form Responses&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Complete the different questions and fields on the Form.&lt;/li&gt;&#xA;&lt;li&gt;Wait for about a minute, and return to the Azure Logic Apps flow created earlier. From the &lt;strong&gt;Overview&lt;/strong&gt; blade, navigate to &lt;strong&gt;Runs History&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_21-06-40.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Logic Apps Run History&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;The Forms completion resulted in a &lt;strong&gt;successful workflow trigger&lt;/strong&gt;. Select the line, which opens a more detailed view.&#xA;&lt;img src=&#34;../images/2023-03-26_21-08-20.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Logic Apps detailed Run History&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;.&lt;/li&gt;&#xA;&lt;li&gt;Last, return to the Azure DevOps Project, navigate to Boards and open Work Items. Notice the &lt;strong&gt;newly created Work Item&lt;/strong&gt;.&#xA;&lt;img src=&#34;../images/2023-03-26_21-12-16.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Logic Apps created Work Item&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;li&gt;Open the item, to see how the custom fields got completed.&#xA;&lt;img src=&#34;../images/2023-03-26_21-13-52.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Logic Apps created Work Item details&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;That&amp;rsquo;s pretty much it!! Nice isn&amp;rsquo;t it&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In this post, I wanted to share more details on how you can allow end-users (or customers) to create Azure DevOps Work Items (of pretty much any type with any custom fields), using an integration of Microsoft Forms and Azure Logic Apps.&lt;/p&gt;&#xA;&lt;p&gt;Don&amp;rsquo;t hesitate reaching out if you have any additional questions on this, or if you want to share how you used this in your own scenarios.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Cheers!!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>DevOps Workflow Generator</title>
            <link>http://localhost:1313/post/devops-workflow-generator/</link>
            <pubDate>Sun, 03 Apr 2022 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/devops-workflow-generator/</guid>
            <description>&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_16-07-28.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Hey awesome people,&lt;/p&gt;&#xA;&lt;p&gt;For the ones who know me, it shouldn&amp;rsquo;t be a surprise I&amp;rsquo;m interested in DevOps, mainly using Azure DevOps and GitHub as core technologies, as well as several side-solutions that integrate with them. So when I heard about the &lt;strong&gt;DevOps Workflow Generator&lt;/strong&gt;, a new free tool from the Microsoft Research Lab division, I wanted to give it a spin.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-concepts-of-devops&#34;&gt;The Concepts of DevOps&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;DevOps according to Microsoft’s Definition: The Union of People, Processes and Products, to enable continuous delivery of value to the business&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-01.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;The tricky part with DevOps is that it&amp;rsquo;s not just about 1 team using a single tool, but potentially a complex group of people (the DevOps engineering team), using a multitude of tools and solutions to perform their role. Obviously the main DevOps pipeline engine (Azure Pipelines, GitHub Actions, Octopus Deploy, Jenkins, GitLab, etc&amp;hellip;), but most probably, it also involves Infrastructure as Code tools such as Terraform, Azure Bicep or ARM Templates, Configuration as Code tools like PowerShell DSC, Ansible, Chef or Puppet, as well as DevSecOps tools where Snyk, Aqua, SonarQube, WhiteSource bolt and Veracode are just some of the popular ones. (Btw, if you missed my recent post on integrating DevSecOps by Shifting Left, which I wrote for Azure Spring Clean, you can find it &lt;a class=&#34;link&#34; href=&#34;https://www.007ffflearning.com/post/azure-spring-clean-devsecops-and-shifting-left-to-publish-secure-software/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;here&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;h2 id=&#34;when-to-use-what&#34;&gt;When to use what&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;If you went to the Azure Spring Clean post I referred to earlier, you now know that DevOps is relying on a lot of tools. I&amp;rsquo;m not saying it&amp;rsquo;s the most important aspect, but without tools, there is no DevOps. Period.&lt;/p&gt;&#xA;&lt;p&gt;So coming back to the &lt;strong&gt;DevOps Workflow Generator&lt;/strong&gt;, it literally helps organizations, and their DevOps teams, to get a clearer view on what the DevOps process is about, as well as what different tools are being used in each and every phase. You might ask, what&amp;rsquo;s the point in that.&lt;/p&gt;&#xA;&lt;p&gt;Well, let me tell you. Since DevOps is more about the culture than the tools, the better view your team has on what tools are being used, the better the team will operate. Apart from bringing - what&amp;rsquo;s traditionally 2 separate worlds - Developers and Operations teams together, there might actually be a sub-project as part of the DevOps adoption, to try and unify the tooling that is being used. Let&amp;rsquo;s say Developers are OK with using Visual Studio, or maybe Visual Studio Code. Where Operations folks are probably also using Visual Studio Code, in favor of Visual Studio. This might lead to an agreement that from now on, Visual Studio Code is a standard tool across the DevOps team. Maybe even sharing extensions (ARM Templates, Docker, Kubernetes, Bicep, Azure,&amp;hellip;) are just some of my favorites.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-to-use-the-devops-workflow-generator&#34;&gt;How to use the DevOps Workflow Generator&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;You most probably don&amp;rsquo;t need my help from this blog post to find out how the Workflow Generator is working, it&amp;rsquo;s really that easy to use. However, after a first quick look, I went back (in preparation to write this article) and actually discovered some new things. So hopefully there is still something useful for you to discover:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Browse to &lt;a class=&#34;link&#34; href=&#34;https://devopsworkflowgenerator.research.microsoft.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://devopsworkflowgenerator.research.microsoft.com/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_16-07-28.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;2&#34;&gt;&#xA;&lt;li&gt;From the top menu, select &lt;strong&gt;Map Workflow&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This presents you with a rather generic/standard DevOps workflow process; which at first, was what I used. Until I discovered you can actually make customizations to it. Following my own best practices - Shifting Left - I added some of the process steps as outlined in the referred article earlier. The updated workflow looks like this now:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_15-58-28.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;Next, move over the &lt;strong&gt;Select Tools&lt;/strong&gt; step in the top menu. This allows you to select DevOps solutions and tools (single or multiple) for each cycle in your DevOps Workflow. And the list is extensive&amp;hellip;!&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_15-58-55.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator Tools&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ol start=&#34;4&#34;&gt;&#xA;&lt;li&gt;Once all tools have been mapped with each phase, it&amp;rsquo;s time to compile a report, by navigating to the &lt;strong&gt;Download Report&lt;/strong&gt; menu option.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The outcome presents a nice-looking PDF document, which looks like this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_15-59-53.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator Report&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-26_16-00-07.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Workflow Generator Report Detailed Step&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Pretty cool, right?&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In this article, I wanted to introduce you to &lt;strong&gt;DevOps Workflow Generator&lt;/strong&gt; , a free tool by Microsoft Research Labs, allowing DevOps teams to get a better view on their DevOps process(es), as well as highlighting the different solutions and tools used for each phase of the DevOps process.&lt;/p&gt;&#xA;&lt;p&gt;Have a look at it, and let me know your thoughts!&lt;/p&gt;&#xA;&lt;p&gt;If you liked this article, consider giving back a small token of appreciation:&#xA;&lt;a class=&#34;link&#34; href=&#34;https://www.buymeacoffee.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;img src=&#34;../images/buy_me_a_coffee.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;BuyMeACoffee&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Azure Spring Clean - DevSecOps and Shifting Left</title>
            <link>http://localhost:1313/post/azure-spring-clean---devsecops-and-shifting-left-to-publish-secure-software/</link>
            <pubDate>Thu, 17 Mar 2022 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/azure-spring-clean---devsecops-and-shifting-left-to-publish-secure-software/</guid>
            <description>&lt;p&gt;&lt;img src=&#34;../images/AzureSpringClean-logo.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Azure Spring Clean&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Hey folks,&lt;/p&gt;&#xA;&lt;p&gt;Welcome to #AzureSpringClean, an initiative from &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/wedoazure&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Joe Carlyle&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/tamstar1234&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Thomas Thornton&lt;/a&gt;&lt;/strong&gt; which celebrates its 3rd edition this year. I&amp;rsquo;m thrilled to be part of this again for the 2nd time this year. My &lt;a class=&#34;link&#34; href=&#34;https://www.007ffflearning.com/post/azure-spring-clean-demystifying-service-principal-and-managed-identities/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;first article&lt;/a&gt; had security in mind, explaining the difference between Azure Service Principals and Managed Identity.&lt;/p&gt;&#xA;&lt;p&gt;For this second article, I&amp;rsquo;m staying in the security focus, helping you &lt;strong&gt;understand DevSecOps, and how you can optimize security in your application deployment lifecycle, by &amp;ldquo;shifting left&amp;rdquo;&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I hope you learn from it, enjoy reading through and got inspired to check back the whole week here at Azure Spring Clean, as there are A TON of great topics that will be covered.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-concepts-of-devops&#34;&gt;The Concepts of DevOps&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Microsoft’s Definition: The Union of People, Processes and Products, to enable continuous delivery of value to our end users&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-01.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;What DevOps teams are doing is providing an automated deployment process, starting from:&lt;/p&gt;&#xA;&lt;p&gt;a) checking in their application source code into a source control system, such as &lt;a class=&#34;link&#34; href=&#34;https://azure.microsoft.com/en-us/services/devops/repos/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure DevOps Repos&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/repositories&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;GitHub Repositories&lt;/a&gt; or similar;&#xA;b) Once the code has been checked in, it loops through a functional testing process;&#xA;c) This forms the starting point of Continuous Integration (CI), where the code gets compiled into an artifact or deployable package;&#xA;d) From here, the package typically gets deployed into a running state, known as Continuous Deployment (CD); this could be to a dev/test, staging or production environment;&#xA;e) Once the application workload is published, there&amp;rsquo;s a handover to the Operations team, who integrate monitoring, watch over incidents and fix the problem.&lt;/p&gt;&#xA;&lt;p&gt;This (somewhat simplified) process gets repeated over and over (CI/CD pipeline automation), and should lead to faster deployments, less bug fixes needed and reliable workloads.&lt;/p&gt;&#xA;&lt;p&gt;If we look at this process from a linear perspective, it would look like this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-02.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Linear DevOps&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;So now you know what DevOps stands for, let’s zoom in more on the DevSecOps extension&lt;/p&gt;&#xA;&lt;h2 id=&#34;shifting-left&#34;&gt;Shifting Left&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;When you look at this application lifecycle overview, most of the security handling, but also vulnerabiltiies, are getting detected and handled &lt;strong&gt;during the running phase&lt;/strong&gt;. That’s where we have DDOS attacks, identity or credential theft, networking attacks, crypto and similar malware etc…&lt;/p&gt;&#xA;&lt;p&gt;While there’s nothing wrong in handling security all the way at the end, it should not be &lt;strong&gt;ONLY&lt;/strong&gt; all the way at the end, but rather be moved &lt;strong&gt;all the way to the beginning&lt;/strong&gt;; and becoming part of each and every stage in our DevOps process&lt;/p&gt;&#xA;&lt;p&gt;That’s what the industry calls &lt;strong&gt;“shifting left”&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;So what are some of the security best practices DevOps teams can (easily) integrate into their DevSecOps process you ask? Actually there&amp;rsquo;s a lot of different options and possibilities. Good news is, you can apply different security features in the different DevOps stages:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-03.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Security&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;I’ll drill down a bit more on these obviously, but let’s look at some examples:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;DEV&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Threat Modeling&lt;/strong&gt; - Microsoft provides a &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/security/develop/threat-modeling-tool&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;free Threat Modeling Tool&lt;/a&gt;, which helps you outlining the potential threats and vulnerabilities for a generic application architecture;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Credentials &amp;amp; Secrets Management&lt;/strong&gt; - NEVER store your secrets and credentials hard-coded into your source control system. That&amp;rsquo;s just a NO GO!! Rather, look into &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&amp;amp;tabs=yaml%2Cbatch&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;secret variables&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops&amp;amp;tabs=yaml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;variable groups&lt;/a&gt; or even better, a secret store such as &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/azure/key-vault/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Key Vault&lt;/a&gt; or &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/actions/learn-github-actions/environment-variables&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;GitHub Secrets&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Peer Review&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;VALIDATE&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Code Analysis&lt;/strong&gt; - this is where you integrate source control code scanning tools such as Snyk, Sonar, WhiteSource Bolt and many others. The easiest way is going through them in your own DevOps pipelines. If you are using Azure DevOps, have a look at the &lt;a class=&#34;link&#34; href=&#34;&#34; &gt;Azure DevOps Marketplace&lt;/a&gt;, and search for &lt;strong&gt;security&lt;/strong&gt;&#xA;At present, there are &lt;strong&gt;91&lt;/strong&gt; different extensions available to integrate security into your DevOps Organization and Projects.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-04.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Security&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;PACKAGE&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Secured Containers&lt;/strong&gt; - Containers are becoming more and more popular to speed up the development process, simplifying the dependency on a platform and overall allowing for standardization thanks to Docker images. While containers are bringing in a lot of good things into a developer&amp;rsquo;s scenario, they also might bring in vulnerabiities and security risks, as you don&amp;rsquo;t always know where the image comes from, what&amp;rsquo;s running inside the container or who built it. That&amp;rsquo;s where I can definitely recommend a vulnerability scanner for containers. Tools such as Aqua or Twistlock are popular reference here. If you are using Azure as your container runtime environment, know that you can enable &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/defender-for-cloud/defender-for-containers-introduction&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Microsoft Defender for COntainers&lt;/a&gt;, which provides a built-in security vulnerabilty for your containers stored in Azure Container Registry.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Quality Gates&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Cloud Configuration&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Security &amp;amp; Pen-testing&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-05.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Security&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;RUN&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Cloud Platform Security&lt;/strong&gt; - Any cloud vendor provides robust security features as part of the platform. Azure comes with Azure Security Center for years, which recently got rebranded to &lt;strong&gt;[Microsoft Defender for Cloud]&lt;/strong&gt;(&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/defender-for-cloud/defender-for-cloud-introduction%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://docs.microsoft.com/en-us/azure/defender-for-cloud/defender-for-cloud-introduction)&lt;/a&gt;. Core characteristics are detecting your Secure Score, a value for your security posture, together with an extensive list of recommendations, on how to optimize your security.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;RBAC permissions&lt;/strong&gt; model - This corresponds to the concept of &amp;ldquo;least set of privileges&amp;rdquo;, which means your DevOps teams should only get the administrative permissions they really need to do there job, but no more. Or even better, only give them administrative permissions when they need to perform admin tasks. Services such as &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/active-directory/identity-protection/overview-identity-protection&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Identity Protection&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/active-directory/privileged-identity-management/pim-configure&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Privileged Identity Management&lt;/a&gt; are no luxury in any organization. Keep in mind these require an Azure AD Premium P2 license. Which - if you ask me - is more than worth the extra cost!&lt;/li&gt;&#xA;&lt;li&gt;Credentials &amp;amp; Secret Management&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2022-03-17-06.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Security&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;OPERATE&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Security Monitoring&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Threat Detection&lt;/strong&gt; - This brings us back to the &amp;ldquo;original&amp;rdquo; approach, having the necessary security guardrails in place to protect our runtime environments. SIEM solutions such as &lt;a class=&#34;link&#34; href=&#34;https://azure.microsoft.com/en-us/services/microsoft-sentinel&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Sentinel&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Mitigation&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;In this post, I gave you an overview of the typical DevOps process, and what challenges exist around security. Often coming in all the way at the end (during the operations cycle), security should be part of each and every step of the DevOps concept, preferably as early in the process as possible. This is what the industry calls &lt;strong&gt;shifting left&lt;/strong&gt;. I tried to share some &amp;ldquo;easy to implement solutions&amp;rdquo; to optimize security, by sharing several tools and services available today in Azure, Azure DevOps and GitHub. If you should have any questions on this, or you want to see a demo on what the tools can do, I&amp;rsquo;m only a nudge away ;)&lt;/p&gt;&#xA;&lt;p&gt;Once more, I very appreciated thank you for reading, and for &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/wedoazure&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Joe Carlyle&lt;/a&gt; and &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/tamstar1234&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Thomas Thornton&lt;/a&gt;&lt;/strong&gt; for having accepted my submission for this 2022 #AzureSpringClean edition. Enjoy your Spring Clean week, stay safe and healthy!&lt;/p&gt;&#xA;&lt;p&gt;Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>AzCopy failing in Azure Devops with error ServiceCode=AuthorizationPermissionMismatch</title>
            <link>http://localhost:1313/post/azcopy-failing-in-azure-devops/</link>
            <pubDate>Mon, 14 Dec 2020 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/azcopy-failing-in-azure-devops/</guid>
            <description>&lt;p&gt;Hi all,&lt;/p&gt;&#xA;&lt;p&gt;This is one of the nail biting challenges of our industry, failing in running a &lt;strong&gt;straight-forward&lt;/strong&gt; task. Especially when it is failing&amp;hellip;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-happened&#34;&gt;What happened?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;I was creating a pipeline in &lt;strong&gt;Azure DevOps&lt;/strong&gt; to deploy an ARM template for VM setups with VM Extensions. To prep this deployment, the artifacts (DSC scripts) should be copied to Azure Blob Storage, in order for the Azure DevOps build agent to &amp;ldquo;find&amp;rdquo; it. Easy-peasy, there is a predefined task for that, called &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/azure/devops/pipelines/tasks/deploy/azure-file-copy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Blob File Copy&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;I defined source (my Azure Repos folder) and target (Blob Container in Azure Storage Account), but saw the copy failing with an interesting error message:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_1.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;AzCopy Error&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;INFO: Authentication failed, it is either not correct, or expired, or does not have the correct permission&lt;/li&gt;&#xA;&lt;li&gt;RESPONSE Status: 403 This request is not authorized to perform this operation using this permission.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Knowing I&amp;rsquo;m running this deployment with a valid &lt;strong&gt;Service Principal&lt;/strong&gt; linked to my &lt;strong&gt;Azure DevOps Service Connection&lt;/strong&gt; which deployed Azure Resources successfully before (including a new Azure Storage Account from within the same Job earlier in the process), I had no immediate idea what was wrong. Also, I have used AzCopy for a while already, without issues.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-to-check&#34;&gt;What to check?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Next challenge is, where do I start troubleshooting?&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;My Service Principal only got created last week, so definitely not expired (and working for other Azure deployments);&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;My Service Principal got created with all default settings and scoped to my subscription as Contributor (az ad sp create)(&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli%29;&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli);&lt;/a&gt; While you should definitely limit the scope in a production environment, not that important for my demos. And thus also not the blocking factor;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Check the differences between a working AzCopy pipeline and the non-working version to try and identify any differences;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;bingo&#34;&gt;BINGO!&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Not yet, but at least I found the clue&amp;hellip; in the &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-v10#option-1-use-azure-active-directory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;AzCopy documentation&lt;/a&gt;&lt;/strong&gt; which specifies how to enable Azure Blob storage access using Azure Active Directory instead of the traditional SAS token (A Service Principal is an Azure Active Directory object, therefore I was not looking into SAS tokens anymore&amp;hellip;). Following the link under &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azcopy-authorize-azure-active-directory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Option 1 (Azure AD)&lt;/a&gt;, pointed me to the following updates in AzCOpy:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;- The level of authorization that you need is based on whether you plan to upload files or just download them.&#xD;&#xA;&#xD;&#xA;- *If you just want to download files, then verify that the Storage Blob Data Reader role has been assigned to your user identity, managed identity, or service principal.&#xD;&#xA;&#xD;&#xA;- If you want to upload files, then verify that one of these roles has been assigned to your security principal:&#xD;&#xA;&#xD;&#xA;    - Storage Blob Data Contributor&#xD;&#xA;    - Storage Blob Data Owner&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s give this a try:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;From your Azure DevOps Project, select &lt;strong&gt;Project Settings&lt;/strong&gt; / &lt;strong&gt;Service Connections&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_2.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Service Connections&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Select the &lt;strong&gt;Service Connection&lt;/strong&gt; you use for the given Pipeline deployment and choose &lt;strong&gt;Manage Service Principal Roles&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_3.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Service Connection Roles&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;This opens Azure Active Directory - Access Control from where you can add a role assignment by clicking &lt;strong&gt;Add Role Assignment&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_4.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Add Role Assignment&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;From the list of roles, select &lt;strong&gt;Storage Blob Data Contributor&lt;/strong&gt;, and search for your Service Principal name in the &lt;strong&gt;Select&lt;/strong&gt; field (if you don&amp;rsquo;t know the exact name of your Service Principal anymore, from Azure DevOps / Service Connections, select &amp;ldquo;Manage Service Principal&amp;rdquo;, which will open your Service Principal blade in Azure Active Directory for this specific object - the name will be visible from there)&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_5.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Add Role Assignment&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Save&lt;/strong&gt; your changes. (Note - I&amp;rsquo;m allowing this permission for this Service Principal across the full subscription; in a real-life scenario, it would be enough to allocate this Azure Role scoped to the specific storage account)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The result should look about similar to below screenshot:&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt;![Add Role Assignment](../images/2020-12-14_6.jpg)&#xD;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Run the Pipeline again from Azure DevOps, and behold&amp;hellip; a successful run this time :)!&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-12-14_6.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;AzCopy Successful&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;I hope this helps anyone bumping into the same issue as I did. For me lesson learned is reading the &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/azure/?product=featured&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Docs&lt;/a&gt; a bit more every now and then, especially when something isn&amp;rsquo;t working right away&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;thanks, Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Azure Back To School (with Azure DevOps)</title>
            <link>http://localhost:1313/post/azure-back-to-school/</link>
            <pubDate>Sun, 13 Sep 2020 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/azure-back-to-school/</guid>
            <description>&lt;p&gt;Hey everyone,&lt;/p&gt;&#xA;&lt;p&gt;Wow, it&amp;rsquo;s September already! Where has summer been? And honestly, where has the (nice) year been? Most of you, just like myself, are probably still working from home, and I guess the same are your kids.&lt;/p&gt;&#xA;&lt;p&gt;Where September used to feel like a fresh start (remember that smell of your new school outfit, the new school equipment, fresh-sharpened pencils, the excitement of learning new things, meeting new class mates,&amp;hellip; almost seems like I want to go back to school myself.&lt;/p&gt;&#xA;&lt;p&gt;Trust me, I live this moment almost every single week as an Azure Technical Trainer, feeling the excitement from the attendees to learn knew things about Azure, getting their solutions validated or hearing how there problems can be solved by using Azure cloud services. I even feel how nervous they are about taking a &lt;a class=&#34;link&#34; href=&#34;https://www.microsoft.com/learn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Microsoft Certification&lt;/a&gt; and become Azure certified.&lt;/p&gt;&#xA;&lt;h2 id=&#34;azure-back-to-school&#34;&gt;Azure Back To School&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;So to stay within the &amp;ldquo;spirit of continuous learning&amp;rdquo;, I was more than happy to contribute to &lt;a class=&#34;link&#34; href=&#34;https://captainhyperscaler.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Dwayne Natwick&amp;rsquo;s&lt;/a&gt; event &lt;a class=&#34;link&#34; href=&#34;https://captainhyperscaler.com/2020/03/03/azure-back-to-school/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&lt;strong&gt;Azure Back to School&lt;/strong&gt;&lt;/a&gt;,&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-09-13_01.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Cover_Azure_Back_to_school&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;and present a session on &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://youtu.be/K4ClwqEKNys&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;&amp;ldquo;Azure DevOps is not for IT Pro (says no one ever again)&amp;rdquo;&lt;/a&gt;&lt;/strong&gt;. Why was I so stupid enough to try and cram this amazing tool in a 30 minute session? I still don&amp;rsquo;t know why :)&lt;/p&gt;&#xA;&lt;p&gt;Anyway, during this session, I&amp;rsquo;m scratching the surface of Azure DevOps capabilities:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Azure Devops Repos&lt;/strong&gt; - GIT-compatible source/version control&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Azure DevOps Boards&lt;/strong&gt; - Following on Scrum, Agile and alike development project management, this component provides work items, bug tracking,&amp;hellip; including graphical boards&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Azure Pipelines&lt;/strong&gt; - Probably the core of the solution, allowing you to enable a complete CI/CD (continuous integration/continuous deployment) scenario using YAML or Classic Editor, and deploy our templates/workloads to Azure (or other platforms)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The goal in my 30 min session was to just show you the core capabilities, to at least get you looking into it. If I can get you creating your Azure DevOps Organization and creating your first Azure DevOps project&amp;hellip; I have reached my goal :).&lt;/p&gt;&#xA;&lt;p&gt;Everything else will follow in future blog posts here at 007FFFLearning.com, no worries.&lt;/p&gt;&#xA;&lt;p&gt;That said, if you made it all the way through this post, and you cannot wait to get started with &lt;a class=&#34;link&#34; href=&#34;https://azure.microsoft.com/nl-nl/services/devops/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure DevOps&lt;/a&gt;, send me a DM on Twitter or leave me an email with the &lt;em&gt;exact subject&lt;/em&gt; &amp;ldquo;@zure DevOps - Back To Sch00l&amp;rdquo; , and I&amp;rsquo;ll return you a little gift, allowing you to jump into Azure DevOps right away&amp;hellip;!&lt;/p&gt;&#xA;&lt;p&gt;One last thing, there is a lot more cool and interesting &lt;a class=&#34;link&#34; href=&#34;http://azure.microsoft.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure&lt;/a&gt; stuff to be found on &lt;strong&gt;&lt;a class=&#34;link&#34; href=&#34;https://captainhyperscaler.com/2020/03/03/azure-back-to-school/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Azure Back to School**&lt;/a&gt;&lt;/strong&gt; for the rest of the month, so grab that opportunity to keep your internal learning daemon happy ;).&lt;/p&gt;&#xA;&lt;p&gt;See you around! Take care,&lt;/p&gt;&#xA;&lt;p&gt;thanks, Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>DevOps for Dummies - Emily Freeman - Review</title>
            <link>http://localhost:1313/post/devops-for-dummies-review/</link>
            <pubDate>Sat, 22 Aug 2020 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/devops-for-dummies-review/</guid>
            <description>&lt;p&gt;Hey,&lt;/p&gt;&#xA;&lt;p&gt;As some of you know me for years already, you also know I’m rather bad in coding (although I&amp;rsquo;m learning &lt;a class=&#34;link&#34; href=&#34;https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Blazor&lt;/a&gt; since a few weeks, but more on that journey in future posts&amp;hellip;), and always “got scared” about DevOps. Especially the Dev part in the word 😊. I still remember being in Bangalore, India early 2016 to deliver an Azure workshop to Microsoft GSI Partners (Wipro, Tech Mahindra, Accenture,&amp;hellip;) as a freelance trainer together with Microsoft AzureCAT engineers. While my sessions were totally in my Azure comfort zone (Networking, Storage, Azure Active Directory), I also learned a lot from the Azure App sessions my colleagues delivered. But then all of a sudden, I had to jump in on Wednesday afternoon, taking over the “DevOps practices” session due to some urgent facts. Oh man, down went my comfort level. Me, the guy they saw earlier in the week, delivering Azure Infra sessions with ease, now needing to talk about DevOps, something I didn’t know at all? I hardly used Visual Studio at that time, let alone I could talk about this process.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-08-22_01.png&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Eco System&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;So instead of delivering the foreseen session (DevOps processes, Visual Studio integration with source control, CI/CD Pipelines,&amp;hellip;), I just talked about my personal perspective of DevOps, how ARM templates and Azure Automation was “the DEV part” in my world, helped me combining my +15 years background in building Microsoft datacenters at customers “the OPS guy”, and do amazing things with it. All in all, the talk got very much appreciated, as it was personal.&lt;/p&gt;&#xA;&lt;h2 id=&#34;i-already-know-azure-devops-so-why-bother&#34;&gt;I already know Azure DevOps, so why bother?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;Jumping 5 years further in time, I have been using Azure DevOps as a tooling myself for about 2 years now, and also delivered several successful Azure AZ-400 (&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/learn/certifications/exams/az-400&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://docs.microsoft.com/en-us/learn/certifications/exams/az-400&lt;/a&gt;) workshops  out of my Microsoft role as Azure Technical Trainer. And then I stumbled into &lt;strong&gt;Emily Freeman’s (&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/editingemily&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://twitter.com/editingemily&lt;/a&gt;)&lt;/strong&gt; Devops for Dummies book (&lt;a class=&#34;link&#34; href=&#34;https://www.amazon.com/DevOps-Dummies-Computer-Tech/dp/1119552222%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;https://www.amazon.com/DevOps-Dummies-Computer-Tech/dp/1119552222)&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-08-22_02.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;DevOps Eco System&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;At first, I wasn’t really interested in getting me a copy, given it was &lt;strong&gt;“for Dummies”&lt;/strong&gt;. And remembering what other “for Dummies” I read in the past, it was always on something I didn’t know at all, yet learned a lot from it. So I gave it a chance – also because the Kindle edition is only $15,99 USD – that’s like 3 Starbucks coffees 😊. &lt;strong&gt;And wow, I was hooked to it from the first chapter&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-got-me-hooked&#34;&gt;What got me hooked?&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;First of all, Emily is a subject matter expert, period. I’ve seen her presenting both in-person and at virtual conferences, and I enjoy learning from her stories. She manages to combine technical expertise with understandable explanations, calm presentation style, funny twists,&amp;hellip; everything you look for in a presenter. And next to that, passion for the topic. It is clear Emily can look back to a huge amount of in-the-field experience on helping customers implementing (or transforming for that matter) DevOps best practices into their IT lifecycle management.&lt;/p&gt;&#xA;&lt;p&gt;It was this natural flow of words, the logic of chapters, how the whole book is getting build up from basics to more complex scenarios and everything in between, that makes it worthwhile for anyone in IT to read it. This book is not about Azure DevOps just to be clear. It focuses on the processes, the challenges, how to get from where you are today to where you can be in the (near) future as an organization, and also nicely describes the real-life challenges that comes with it.&lt;/p&gt;&#xA;&lt;p&gt;Next, every couple of pages, she makes a nice annotation to an interesting quote, additional side-reference material, a funny story around DevOps,&amp;hellip; that makes it still “light to digest”, yet still hugely informational.&lt;/p&gt;&#xA;&lt;h2 id=&#34;about-the-book-structure&#34;&gt;About the book structure&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;The book is about 300 pages long, split up in 6 chapters:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Demystifying Devops&lt;/strong&gt; – this is one of the best 50 pages I know describing what DevOps REALLY is. What’s good about, where are the challenges, why/how around colleagues not liking it and how to convince them,&amp;hellip;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Establishing a Pipeline&lt;/strong&gt; – From planning to software lifecycle management, and how to get there, also explaining how your development code itself should take DevOps into account&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Connecting the circuit&lt;/strong&gt; – this section covers how to handle and get feedback, manage iterations, success and failure of the process&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Kaizen&lt;/strong&gt; – Not about a Japanese Hero, but how to continuously improve your processes, learn from mistakes and optimize the business overall&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;DevOps Tools&lt;/strong&gt; – A nice overview of different devops tools, useful for private and public cloud platforms&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Top 20&lt;/strong&gt; – 10 reasons where DevOps is crucial, and another 10 reasons where it can fail&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;what-i-remember-from-it&#34;&gt;What I remember from it&#xD;&#xA;&lt;/h2&gt;&lt;h3 id=&#34;devops-is-approachable-and-real-is-one-of-the-best-quotes&#34;&gt;“DevOps is approachable and real”, is one of the best quotes&#xD;&#xA;&lt;/h3&gt;&lt;p&gt;Aside from that, I took a lot of notes around processes, how to inspire people to start embracing DevOps practices, the challenges that comes with it, but mainly how it can help any organization to transform their current mode of operations and software lifecycle into an optimized, well-oiled flow, where IT is becoming a business driver, no longer a cost center or cost generator.&lt;/p&gt;&#xA;&lt;p&gt;I honestly wish I had this book 5 years ago, showing me there is nothing scary or anything to be afraid of when considering DevOps. &lt;strong&gt;It’s about people, processes and products&lt;/strong&gt;. It’s not about being a full-stack developer or being the expert datacenter specialist. It’s how both worlds can nicely work together. (Which in these difficult times of COVID-19 and racial disturbance could actually be baby-steps in the positive direction)&lt;/p&gt;&#xA;&lt;p&gt;Ping me if you got any questions on the book, DevOps or Azure DevOps in general.&lt;/p&gt;&#xA;&lt;p&gt;Cheers, Peter&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Azure DevOps Pipelines - YAML or Classic Designer</title>
            <link>http://localhost:1313/post/azure_devops-pipelines-yaml_or_classic_designer/</link>
            <pubDate>Sun, 21 Jun 2020 00:00:00 +0000</pubDate>
            <guid>http://localhost:1313/post/azure_devops-pipelines-yaml_or_classic_designer/</guid>
            <description>&lt;p&gt;During several of my &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/learn/certifications/exams/az-400&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;AZ-400 Designing and Implementing Microsoft DevOps Solutions&lt;/a&gt; training deliveries, one recurring point of conversation is &lt;strong&gt;Should we use YAML or the Classic Designer&lt;/strong&gt; for our Release pipelines?&lt;/p&gt;&#xA;&lt;p&gt;So I thought sharing my view in another blog post could be helpful.&lt;/p&gt;&#xA;&lt;p&gt;Before answering the question more accurately, let&amp;rsquo;s go over each scenario a bit more in detail:&lt;/p&gt;&#xA;&lt;h1 id=&#34;classic-designer&#34;&gt;Classic Designer&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;Classic Designer has been the long-standing approach on how Azure DevOps Pipelines have been created. Using a user-friendly graphical User Interface, one can add tasks to create a pipeline just by searching for them from a list of tasks, and complete necessary parameters.&lt;/p&gt;&#xA;&lt;p&gt;Below example is what I use for building Docker Containers:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-06-21_1.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Build Pipeline Classic Designer&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;As you can see, this looks quite straight forward to anyone, even if you are totally new to Azure DevOps.&lt;/p&gt;&#xA;&lt;p&gt;If I want to update my pipeline with another task, for example &lt;strong&gt;Docker CLI Installer&lt;/strong&gt;, I just click on &lt;strong&gt;add task&lt;/strong&gt; and search for all &lt;strong&gt;&amp;ldquo;Docker&amp;rdquo;&lt;/strong&gt; related tasks from the list,&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-06-21_2.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Docker Task Classic Designer&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;and select the related task I want:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;../images/2020-06-21_3.jpg&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    loading=&#34;lazy&#34;&#xD;&#xA;    &#xD;&#xA;      alt=&#34;Docker Install Task Classic Designer&#34;&#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;    &#xD;&#xA;  &gt;&lt;/p&gt;&#xA;&lt;p&gt;Once you are familiar with the &lt;strong&gt;actual steps&lt;/strong&gt; on how to build and compile containers from a command line, moving the manual steps to an Azure Pipeline are &lt;strong&gt;almost 100% the same&lt;/strong&gt;. In the end, you are literally automating your manual approach.&lt;/p&gt;&#xA;&lt;h1 id=&#34;yaml&#34;&gt;YAML&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;Now, let&amp;rsquo;s take a look at the YAML (Yet Another MarkUp Language) approach. There is no graphical designer here, but rather a &lt;strong&gt;text config file&lt;/strong&gt; you need to build up, describing the different steps you want to run as part of your Azure Release Pipeline.&lt;/p&gt;&#xA;&lt;p&gt;YAML got introduced into Azure DevOps mid 2018 already, but I still see a lot of customers not using it that often yet.&lt;/p&gt;&#xA;&lt;p&gt;Using a similar example as before, the YAML file looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pool:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  name: Azure Pipelines&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;steps:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: qetza.replacetokens.replacetokens-task.replacetokens@3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Replace tokens in appsettings.json&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    rootDirectory: &amp;#39;$(build.sourcesdirectory)/src/MyHealth.Web&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    targetFiles: appsettings.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    escapeType: none&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    tokenPrefix: &amp;#39;__&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    tokenSuffix: &amp;#39;__&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: qetza.replacetokens.replacetokens-task.replacetokens@3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Replace tokens in mhc-aks.yaml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    targetFiles: &amp;#39;mhc-aks.yaml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    escapeType: none&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    tokenPrefix: &amp;#39;__&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    tokenSuffix: &amp;#39;__&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: DockerInstaller@0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Install Docker 17.09.0-ce&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: DockerCompose@0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Run services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFile: &amp;#39;docker-compose.ci.build.yml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    action: &amp;#39;Run services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    detached: false&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: DockerCompose@0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Build services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFile: &amp;#39;docker-compose.yml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFileArgs: &amp;#39;DOCKER_BUILD_SOURCE=&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    action: &amp;#39;Build services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    additionalImageTags: &amp;#39;$(Build.BuildId)&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: DockerCompose@0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Push services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFile: &amp;#39;docker-compose.yml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFileArgs: &amp;#39;DOCKER_BUILD_SOURCE=&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    action: &amp;#39;Push services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    additionalImageTags: &amp;#39;$(Build.BuildId)&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: DockerCompose@0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Lock services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFile: &amp;#39;docker-compose.yml&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    dockerComposeFileArgs: &amp;#39;DOCKER_BUILD_SOURCE=&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    action: &amp;#39;Lock services&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: CopyFiles@2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Copy Files&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Contents: |&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     **/mhc-aks.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     **/*.dacpac&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    TargetFolder: &amp;#39;$(Build.ArtifactStagingDirectory)&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- task: PublishBuildArtifacts@1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  displayName: &amp;#39;Publish Artifact&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  inputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ArtifactName: deploy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s rather different, isn&amp;rsquo;t?&lt;/p&gt;&#xA;&lt;p&gt;Each individual &lt;strong&gt;task&lt;/strong&gt; I just had to select before, now requires a &lt;strong&gt;set of instructions&lt;/strong&gt; in a config file. Luckily, Azure DevOps still provides a graphical interface to pick the tasks, which could be helpful in the beginning, when YAML is too new to you.&lt;/p&gt;&#xA;&lt;p&gt;Good news is, from a Build Pipeline perspective, both methods provide the same result. So the key question is, which one to go for?&lt;/p&gt;&#xA;&lt;h1 id=&#34;classic-designer-or-yaml&#34;&gt;Classic Designer or YAML&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;After discussing on this topic with several students during my deliveries, I came up with a &lt;strong&gt;good and bad&lt;/strong&gt; list for each. Know this is far from complete, not trying to push you in a certain direction at all, but merely providing an overview.&lt;/p&gt;&#xA;&lt;h2 id=&#34;advantages-of-classic-editor&#34;&gt;Advantages of Classic Editor&#xD;&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;Ease of Use&lt;/li&gt;&#xA;&lt;li&gt;Clear overview of what tasks the pipelines is based on&lt;/li&gt;&#xA;&lt;li&gt;Lots of preconfigured task snippets available&lt;/li&gt;&#xA;&lt;li&gt;No &amp;ldquo;development&amp;rdquo; language to learn&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;disadvantages-of-classic-editor&#34;&gt;Disadvantages of Classic Editor&#xD;&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;Less obvious Source Control/Version Control&lt;/li&gt;&#xA;&lt;li&gt;Specific to Azure DevOps&lt;/li&gt;&#xA;&lt;li&gt;Slow to create or update your pipelines&lt;/li&gt;&#xA;&lt;li&gt;Microsoft-native&lt;/li&gt;&#xA;&lt;li&gt;While not immediately, it will phase out at some point&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;advantages-of-yaml&#34;&gt;Advantages of YAML&#xD;&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;100% code-based, which means you can manage it like your application source code in source/version control&lt;/li&gt;&#xA;&lt;li&gt;Easy to make changes (once you know how the language works)&lt;/li&gt;&#xA;&lt;li&gt;Easier to compare changes (e.g. Azure Repos &amp;ldquo;file compare feature&amp;rdquo;)&lt;/li&gt;&#xA;&lt;li&gt;Code snippets can be shared easily with colleagues, much easier than screenshots&lt;/li&gt;&#xA;&lt;li&gt;Same YAML concept is used by Docker, Kubernetes,&amp;hellip; and several other &amp;ldquo;configuration as code&amp;rdquo; tools&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;View YAML&lt;/strong&gt; option in Classic Editor to see the snippet of GUI task translated to YAML&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;disadvantages-of-yaml&#34;&gt;Disadvantages of YAML&#xD;&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;Scary at first, especially if you are not a developer&lt;/li&gt;&#xA;&lt;li&gt;Harder to learn the &amp;ldquo;language&amp;rdquo;, when you are used to using the Graphical UI&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;summary&#34;&gt;Summary&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;Again, this list is probably far from complete, and mostly depends on your personal preferences. For me, I still see myself going often to the Classic Editor rather than using YAML, but I also try to change my behavior :). Knowing YAML is somehow becoming a standard in other tools and platforms (think of Docker, Kubernetes,&amp;hellip;), it makes total sense to also adopt this into Azure DevOps. Next, there is a tendency to move to a &lt;strong&gt;anything as code&lt;/strong&gt; (Infrastructure as Code, Configuration as Code, now &lt;strong&gt;Pipelines as Code&lt;/strong&gt;,&amp;hellip;) which allows for easier creation, change, version control and collaboration across teams. And isn&amp;rsquo;t that the ultimate idea about DevOps after all?&lt;/p&gt;&#xA;&lt;p&gt;Ping me on &lt;a class=&#34;link&#34; href=&#34;http://www.twitter.com/pdtit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xD;&#xA;    &gt;Twitter&lt;/a&gt; or send me an &lt;a class=&#34;link&#34; href=&#34;mailto:peter@pdtit.be&#34; &gt;Email&lt;/a&gt; if you want to share your feedback on this.&lt;/p&gt;&#xA;&lt;p&gt;Stay safe and healthy you all!&lt;/p&gt;&#xA;&lt;p&gt;/Peter&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
