Writing

Notes & how-tos.

Occasional thoughts on engineering, AI, and building for developers — published on Medium.

Aug 2021

Serverless Series: Microservices and Azure Functions⚡

<blockquote>Azure Functions provide us with greater flexibility in our application architecture. Let’s see how we can build a serverless microservices architecture with Azure Functions and Azure API Management.</blockquote> <figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*6ZOoKck_X5Itd2YE.jpg"><figcaption>image credit: <a href="https://i.pinimg.com/originals/4d/73/e6/4d73e60bca8b09f679be99d6e7a878f7.jpg">dribble.com</a></figcaption></figure><p>These days, adopting a Microservices architecture seems to be commonly implemented through the use of containers. Microservices can be deployed in a number of ways and ultimately the best choice is the one that suits your needs.</p> <p>In a <a href="https://kylermintah.medium.com/when-do-i-choose-cloud-and-when-datacenter-4e8add8132fa">previous article</a> in this series, I gave a quickstart tutorial for Azure Functions. Today let’s see how one can build out microservices with Azure Functions and some help from Azure API Management (APIM).</p> <h3>1| Getting Started</h3> <p><strong>Azure Functions</strong> allow us to leverage trigger-based serverless capabilities to fulfill our development goals without the traditional overhead associated with, hosting, management, scaling, etc.</p> <p><strong>Azure API Management </strong>is a cloud service that allows developers to manage, secure, and maintain their APIs in-depth including relevant configurations (API gateways, rate-limiting, versioning, and more…) regardless of where the servers are hosted.</p> <p>To attempt this walkthrough you will need to have:</p> <ul><li>An active Azure account and subscription. You can <a href="https://azure.microsoft.com/free/?ref=microsoft.com&amp;utm_source=microsoft.com&amp;utm_medium=docs&amp;utm_campaign=visualstudio">create an account for free</a> and <a href="https://azure.microsoft.com/en-us/free/">obtain a free Azure trial subscription</a>.</li></ul> <h3>2| Architecture Design</h3> <p>In this walkthrough, we will be going serverless and leveraging APIM to build a simple Microservices architecture building off of the quotes Azure Function we built in <a href="https://kylermintah.medium.com/when-do-i-choose-cloud-and-when-datacenter-4e8add8132fa">this previous article</a>. If you would like to follow along reference that article first!</p> <h4><strong>Our Microservices</strong></h4> <p>The focus of this walkthrough is to get a hands-on introduction to APIM and Azure Functions. We will build a very simple microservices architecture.</p> <p>We will have two services our client applications can access.</p> <p><strong>Quotes Service </strong>— supplies clients with randomly served quotes.</p> <p><strong>Author Service — </strong>allows clients to look up information about an Author.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/934/1*AJUtH3X6MX6mh5hm-ulz4g.png"><figcaption>The client application can access both the author and quotes services</figcaption></figure><h3>3| Create Author Service Function</h3> <p>From the Azure portal, create a new function app and fill out the following basic settings:</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/832/1*tdha5VLMcXe3Ri7WcwTHSw.png"></figure><p>You can keep all other settings the same. Select <strong>Review + create </strong>and then select <strong>Create.</strong></p> <p>Next, open the newly created Function App which I have named <strong>author-quite-service </strong>(you will come up with your own unique name), select <strong>Functions </strong>from the side menu, and then <strong>+Create</strong>.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/717/1*Nlj8RNwBbq75Mxag6XEYqw.png"></figure><p>You will be prompted with the <strong>Create function menu</strong>. To expedite things, select <strong>Develop in portal </strong>for the Development environment option and <strong>HTTP trigger </strong>for the template, and fill out the rest of the prompts like so:</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/677/1*I7dwVX1nJs1ymH2nfW6Ygg.png"></figure><p>Once in the portal of the <strong>author-lookup-function, </strong>select <strong>Code + Test</strong> from the side menu so we can implement the service functionality.</p> <p>Copy the following code into the function body:</p> <a href="https://medium.com/media/92dcba16605564f051124bc901d189ca/href">https://medium.com/media/92dcba16605564f051124bc901d189ca/href</a><p>Don’t forget to hit <strong>save</strong>! feel free to select <strong>Test/Run </strong>to try out the implementation.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/732/1*Lsl-twIJRe9UHHjniWdKqg.png"></figure><p>Next, modify and visit the following URL to ensure that it is working</p> <blockquote><em>https://{Your Author Function App Name}.azurewebsites.net/api/author-lookup-function?authorName=Maya%20Angelou</em></blockquote> <p>Note the addition of the query parameter <strong>authorName </strong>which we can set to one of our authors.</p> <h3>4| Create Quotes Service Function</h3> <p>If you haven’t already, check out this <a href="https://kylermintah.medium.com/when-do-i-choose-cloud-and-when-datacenter-4e8add8132fa">previous article</a> where we run through creating the Quotes Azure Function which we will be using as one of our microservices.</p> <p><a href="https://kylermintah.medium.com/when-do-i-choose-cloud-and-when-datacenter-4e8add8132fa">Serverless Series: Quickstart with Azure Functions ⚡</a></p> <h3>5| Creating Azure API Management Resource</h3> <p>In your Azure Portal, select API Management Services and click <strong>+Create</strong>.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/531/1*enw16a-twbkefR6sPX6uZQ.png"><figcaption>If you do not see it, select “Create a resource” and search for it on the next page</figcaption></figure><p>Then proceed to create an API Management Resource with an appropriate set of Basic configuration settings. Here is mine for reference:</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*K70s8OR58Q1rvDsX2Z5ZcQ.png"></figure><p>Note, I am using the <strong>Consumption pricing tier</strong> as it is perfect for a microservices-based architecture. It runs on shared infrastructures, is billed on a per-execution-basis, and can scale up or down with demand.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hbklsFQ6VwSvotMPxqW66g.png"><figcaption>Take note of the Consumption Tier constraints as of August 2021</figcaption></figure><p>We can leave all other settings as they are. Select <strong>Review + create </strong>and then select <strong>Create.</strong></p> <h3>6| Add Function Apps to API Management Resource</h3> <p>Now that we have created both our <strong>Author </strong>and <strong>Quotes </strong>services, we will connect them with our APIM in Azure so that we can leverage them through a shared gateway as microservices.</p> <p>In the Azure portal, open up your quote app APIM. From the side menu, select <strong>APIs</strong>, and then from the blade select <strong>Function App </strong>to add our services.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/860/1*rNGvyyTq8KEPl1OrJVI_Cg.png"></figure><p>From here we can search for our Function Apps and follow the prompts to add them. Make sure to repeat this process for both Function Apps.</p> <p>Once completed you should be able to access both functions via your APIM gateway.</p> <h3>7| The Result 🎉</h3> <p>We now have two endpoints accessible through a single APIM gateway that provide client access to our microservices.</p> <h4><strong>Quote Service Endpoint Running</strong></h4> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1023/1*fza5yVf8l9R90iySZIVJ9g.gif"><figcaption>Quote Service endpoint</figcaption></figure><h4>Author Service Endpoint Running</h4> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8MeQ0Iyihc0g49clPCvmzw.gif"><figcaption>Author Service endpoint</figcaption></figure><h4><strong>You can easily leverage your new services in a client application</strong></h4> <figure><img alt="" src="https://cdn-images-1.medium.com/max/622/1*rrqzM6pQR9LMJck4tAa-JA.gif"><figcaption>Simple Android Application that uses our microservices</figcaption></figure><p>In my last article, I showcased an Android app I put together that used our quote Azure Function. I have now expanded the app model to include our newly created author service!</p> <p>Our quotes application now has two microservices, one to randomly generate quotes, and another to look up information about the quote author.</p> <p>This is a simple example that serves as a basic introduction to leveraging Azure Functions in a microservices model and as additional usage and complexity are introduced to the application the model should prove more useful especially when aided by Azure API Management.</p> <p>I hope this was a helpful introduction to using APIM with Azure Functions. Feel free to reach out if you have any questions or suggestions regarding this article.</p> <p>Until next time, Happy building! 😀</p> <h4>Further Reading &amp; Exercises</h4> <ul> <li><a href="https://azure.microsoft.com/en-us/solutions/microservice-applications/">Microservices on Azure - What Is Microservices | Microsoft Azure</a></li> <li><a href="https://azure.microsoft.com/en-us/services/functions/">Azure Functions Serverless Compute | Microsoft Azure</a></li> <li><a href="https://azure.microsoft.com/en-us/services/api-management/">API Management - Manage APIs | Microsoft Azure</a></li> </ul> <img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=f2b4435015e9" width="1" height="1" alt="">

Read
Jul 2021

Serverless Series: Quickstart with Azure Functions ⚡

<blockquote>This is a quick tutorial to get you started with Azure Functions! This is a Cloud Function solution that empowers developers with effective serverless capabilities.</blockquote> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qeNEbARCTl6kafzM.png"></figure><h3><strong>Objective</strong></h3> <p>We will build an Azure Function to return a random quote from a list of provided quotes via an HTTP request. This toy example should be good to get started using Azure functions and add another tool to your arsenal when evaluating options for your backend services.</p> <h3><strong>Language Choice</strong></h3> <p>There are a number of languages to choose from when creating Azure Functions including Go, Rust, C#, Python, Java, JavaScript, TypeScript, and PowerShell at the time of writing.</p> <p>For this tutorial, I will be using <strong>JavaScript/Node.js</strong>.</p> <h3>Tools</h3> <p>For this tutorial, I will be using Visual Studio Code but note that there are a number of IDE/tooling choices available to work with Azure Functions!</p> <h3>1| Getting Started</h3> <p>To get started you will need to have:</p> <ul> <li>An active Azure account and subscription. You can <a href="https://azure.microsoft.com/free/?ref=microsoft.com&amp;utm_source=microsoft.com&amp;utm_medium=docs&amp;utm_campaign=visualstudio">create an account for free</a> and <a href="https://azure.microsoft.com/en-us/free/">obtain a free Azure trial subscription</a>.</li> <li> <a href="https://nodejs.org/en/">Node.js</a> (reference <a href="https://docs.microsoft.com/en-za/azure/azure-functions/functions-reference-node?tabs=v2#node-version">list of supported versions</a>)</li> <li> <a href="https://code.visualstudio.com/">Visual Studio Code</a> with <a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions">Azure Functions extension</a>.</li> </ul> <h3>2| Create Local Functions Project</h3> <p>In VSCode, create a local Functions project (we will publish it to Azure later).</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/477/1*ktfLU6juqTPUBcV2O6mJyw.png"><figcaption>If you are already signed in to your Azure account, you should be able to see your subscriptions. If not, sign in.</figcaption></figure><p>When prompted, select <strong>JavaScript</strong> as language choice</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*eFpaFloHl0G6RXKZ6h8u1w.png"></figure><p>Next, select <strong>HTTP trigger</strong> for project template</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/597/1*pWdz5bh4MIC9OHR8Acm1dA.png"></figure><p>Next, input a relevant function name. I chose <strong>QuoteSampleFunction.</strong></p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/601/1*HA3w3yX9FtnlM4LrPlStaQ.png"></figure><p>Next, for the Authorization level, select <strong>Anonymous</strong> so that anyone can call the function endpoint.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*T4Cojn0TLJ801Leh_eYVvQ.png"></figure><p>Lastly, select <strong>Add to workspace</strong></p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*WZtRHjtoVmRaGRhiuqamfA.png"></figure><p>You should now have an Azure Functions project with generated files to get started with!</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/385/1*x_8Niw4Yzo2M9ulQnSBQ7g.png"><figcaption>Generated file structure for Azure Function</figcaption></figure><h3>3| Run default Azure Function Locally</h3> <p>Let’s try out our function so far to make sure it’s working.</p> <p>Hit the<strong>F5</strong> key to run the QuoteSampleFunction. If successful you should see the localhost URL.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/957/1*qPrcJhuQ2vWGpYuHLWocYw.png"><figcaption>Azure Function running on localhost address</figcaption></figure><p>Open the URL and it will take you to the default GET request page</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GyAH3hiuPsAgd9nYWdDOsw.png"><figcaption>Default template HTTP trigger Azure Function response</figcaption></figure><p>If you pass in a ‘name’ as a query parameter the function should return a personalized message</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/688/1*RpjUjHEM4VVCIvjr3I1VaQ.png"><figcaption>Default template HTTP trigger Azure Function response with query parameter</figcaption></figure><h3>4| Add Our Custom Logic</h3> <p>As highlighted, our objective here is to return a random quote from a list hosted on our Azure Function.</p> <p>Open <strong>QuoteSampleFunction/index.js </strong>and replace the content with the following code:</p> <a href="https://medium.com/media/7f60eea96dac67dc9ab1f8c3bf6c0ba9/href">https://medium.com/media/7f60eea96dac67dc9ab1f8c3bf6c0ba9/href</a><p>Lines 5 through 27 contain our list. Lines 29 contains our logic to randomly generate a quote, and lastly, line 31 through 35 is how we are sending our response object.</p> <p>In VSCode, hit the<strong>F5</strong> key to run the QuoteSampleFunction with our new logic. Open the localhost URL printed in the console and you should be greeted by one of four quotes.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/627/1*DFOjvtuRCszA9CB7dY8W3w.gif"><figcaption>Hit refresh on your browser to see a randomly sampled quote from our list. (note yours should display JSON instead of a raw message).</figcaption></figure><h3>5| Hosting Our Function in Azure</h3> <p>We would like for our Azure Function to be publically accessible, so let’s follow some simple steps to host it on Azure.</p> <p>Firstly, make sure you are signed into the Azure extension. If you do not have an account now would be a good time to create one!</p> <p>Then find the <strong>Deploy to Function App… </strong>button and select it.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/679/1*BrbN9OFcllKLs1Ci6Z524Q.png"><figcaption>Select Deploy to Function App</figcaption></figure><p>You will be prompted to select a subscription, so choose the one you would like to use. Then select <strong>Create New Function App </strong>when prompted.</p> <p>Then, enter a globally unique name for our hosted function. I called mine <strong>quoteSampleFunction</strong>.</p> <p>Choose a relevant runtime stack. I chose <strong>Node.js 14 LTS</strong>.</p> <p>Lastly, select a relevant region where you would like to host your Azure function. I chose <strong>East US</strong>.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/561/1*k3u4TCKhX2AK95IWArl7tw.png"><figcaption>Deployment to Azure is underway!</figcaption></figure><p>Your Azure Function will then begin deployment. This may take a moment or two.</p> <p>Once the deployment is complete, you will be able to make requests to your Azure function from anywhere via the hosted URL!</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1002/1*a1mFIVPjXguAQRwL8ak5Lw.gif"><figcaption>Now able to make global requests to Azure Function</figcaption></figure><h3>5| So What’s the Big Deal?</h3> <p>Well… we just quickly created a service that we can leverage in our backend without the traditional overhead associated with managing servers, hosting, and scaling. In a couple of minutes, we now have a service we can use anywhere.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1002/1*lomSf-WaIcjMkK1QspOP9Q.gif"><figcaption>Android App powered by our Azure Function</figcaption></figure><p>I scratched together a simple Android app that uses our Azure Function in its backend to showcase this. The app can easily leverage our Azure Function in its service configuration.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BzgkJW1WqeBto8gaEteMGQ.png"><figcaption>Getting into Gradient Design these days</figcaption></figure><p>This example barely scratches the surface. There are tons of opportunities to leverage Azure Functions to your benefit more.</p> <p><a href="https://docs.microsoft.com/en-us/samples/browse/?products=azure-functions&amp;languages=azurecli%2Cazurepowershell%2Ccsharp%2Chcl%2Chtml%2Cjavascript%2Cjson%2Cnodejs%2Cpython%2Cscala%2Csql%2Cterraform%2Ctsql%2Ctypescript%2Cyaml">Check out this page for some real-world Azure Functions examples</a>.</p> <p>Happy Building! 🙂</p> <img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=4e8add8132fa" width="1" height="1" alt="">

Read
Jun 2021

Building a color palette generator in Python

<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rhGuHcYLLriOzDxQld2htQ.gif"></figure><blockquote> <a href="https://procreate.com/insight/2020/procreate5x">Procreate 5X</a> has this really cool feature that allows you to generate the color palette of a provided image. For those of us who don’t have an iPad (and enjoy spontaneous coding projects), here’s one way you could make your own color palette generator in python.</blockquote> <figure><img alt="instagram user @frostedthreads showing off color palette generator in Procreate" src="https://cdn-images-1.medium.com/max/462/1*qJOG-63MxnaVbULuBJ1zsw.gif"><figcaption>Instagram User <a href="https://www.instagram.com/p/CMe2XdBh6ZQ/?utm_source=ig_web_copy_link">@frostedthreads</a> shows off Procreate’s color palette generation feature.</figcaption></figure><p>As an illustration enthusiast, I thought this feature of Procreate was awesome! Not only can an artist break down color palettes from photo references really easily, but one could also consolidate the palettes of their own finished works, ‘study’ the choices of their favorite artists, etc. I mean… I’d <em>probably </em>use the feature this way.</p> <blockquote>Only, one problem…</blockquote> <p>I am a Samsung Galaxy Tab user and have never had the privilege of using Procreate — an iOS exclusive. I’m sure there are plenty of color palette generator options out there, but I decided to create my own for fun over a weekend. Here’s how I went about it.</p> <h3>Goal</h3> <p>Let’s define a simple objective to get going — <strong>given a path to an image, generate its color palette, and slap it on top of the original image.</strong> like so:</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sCQYo6HWpYuUIFzi2wMINg.png"><figcaption>An illustration of mine from some time back</figcaption></figure><h3>Let’s Get Started</h3> <blockquote>Now I know what you’re thinking — “can we get to the code already?” Sure why not. Here’s what I used for this:</blockquote> <ul> <li>Python</li> <li>Google Colab</li> <li>Any public image URL</li> </ul> <figure><img alt="" src="https://cdn-images-1.medium.com/max/150/0*4to1kWk6tOLGT0jP"><figcaption>I will be generating the palette of <a href="https://images.unsplash.com/photo-1575995872537-3793d29d972c?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=665&amp;q=80">this image</a> as an example</figcaption></figure><h3>Set up your Google Colab</h3> <blockquote>To get started, head over to <a href="https://colab.research.google.com/notebooks/intro.ipynb?utm_source=scs-index#recent=true">Google Colab</a> and create a new notebook. If you are new to Google Colab, <a href="https://www.youtube.com/watch?v=inN8seMm7UI">watch this video</a> for a quick intro. I will be providing the code necessary for each <a href="https://colab.research.google.com/notebooks/basic_features_overview.ipynb#scrollTo=KR921S_OQSHG">cell</a> in the steps ahead.</blockquote> <figure><img alt="" src="https://cdn-images-1.medium.com/max/678/1*h7k0jQWtmJe37Agt9wP1Aw.png"><figcaption>Start from an empty Google Colab notebook. If your editor is not in dark mode, it’s never too late to switch.</figcaption></figure><h3>Code Cells</h3> <h4>1. Python Modules</h4> <blockquote>In our first code cell, we need to install/import a couple of modules for use in our functions:</blockquote> <a href="https://medium.com/media/ff77220462220fbb6ca151c132dc5779/href">https://medium.com/media/ff77220462220fbb6ca151c132dc5779/href</a><h4>2. Parent function</h4> <blockquote>In our second code cell, we define our top-level function. The <strong>study_image() </strong>function will orchestrate our process. We will need to define each of the helper functions defined.</blockquote> <a href="https://medium.com/media/3929c7aaa611683494cc98a50c31e3ad/href">https://medium.com/media/3929c7aaa611683494cc98a50c31e3ad/href</a><h4>3. Helper functions</h4> <blockquote>In our third code cell, we define our helper functions. Let’s talk about them.</blockquote> <ul> <li> <strong>fetch_image(image_path), </strong>grabs our image via HTTP request, and stores it in local memory.</li> <li> <strong>extract_colors(img), </strong>extracts the most frequently appearing colors from our image up to a defined <strong>limit </strong>and based on a <strong>tolerance </strong>threshold. This returns an array of tuples of type ‘(color.rgb, color.count)’</li> <li> <strong>render_color_palette(colors), </strong>takes the extracted colors array and uses it to generate a grid of colors on a canvas that we can plot.</li> <li> <strong>overlay_palette(img, color_palette), </strong>takes the original image and rendered color palette and creates a new image using matplotlib.</li> </ul> <a href="https://medium.com/media/f2a777fcce077c9550e638c2d589e8b5/href">https://medium.com/media/f2a777fcce077c9550e638c2d589e8b5/href</a><h4>4. Execution cell</h4> <p>We simply need to call our study_image() function and pass in a valid image URL in our final cell.</p> <a href="https://medium.com/media/0a1c26cd2a5c95399f146563938f5a99/href">https://medium.com/media/0a1c26cd2a5c95399f146563938f5a99/href</a><h3>Run the Colab</h3> <p>Once we have defined the cells above, select <strong><em>Runtime&gt;Run</em></strong> <strong><em>All</em></strong> from the Colab menu options. If you get an error (which may sometimes happen on the first run) select <strong><em>Runtime&gt;Restart and Run All</em></strong>.</p> <p>Then sit back and watch the magic happen!</p> <h3>Et <strong>Voilà</strong> </h3> <p>You should have a generated image with the color palette overlaid on top. You can right-click on it and save it if you’d like!</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*tpLzbCGaJRcXqtg6fPHWLg.png"><figcaption>Generated image with its color palette</figcaption></figure><h3><strong>What Next?</strong></h3> <p>Since this first-pass implementation, I have added some extra bells and whistles, including automatic Google Drive uploads for each image and the generated color asset files.</p> <p>Should I give this little side project a front-end next? Build a larger system that keeps track of these palettes?</p> <p>Who knows, maybe I’ll expand on this and turn it into a series. We’ll see!</p> <img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=b10df37834ae" width="1" height="1" alt="">

Read
May 2021

Azure DevOps Build &amp; Release with YAML Templates

<blockquote>In this piece, we explore a technique for YAML pipeline modularization in Azure DevOps using YAML templates.</blockquote> <figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*iAedW70w8hH1g1LizZ0HWQ.gif"><figcaption>image credit: <a href="https://docs.microsoft.com/en-us/samples/azure-samples/azure-logic-apps-deployment-samples/connect-to-an-integration-account-from-azure-logic-apps-and-deploy-by-using-azure-devops-pipelines/media/create-pipeline.gif">Microsoft Docs</a></figcaption></figure><p>Whether you are on a development team or working on a solo project, there are a few reasons why you might consider using templates for your Azure DevOps pipelines.</p> <p>Organizing your pipeline into multiple file components in your version control system allows for ease of substitution &amp; reuse of each job , stage or step.</p> <p>In terms of team collaboration — templates allow for ease of code reviews for individual pipeline components, efficiency gains through modularity as your pipelines mature, and <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/security/templates?view=azure-devops">even better security</a>.</p> <h3>Getting Started</h3> <blockquote>This walkthrough assumes experience working with <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/what-is-azure-pipelines?view=azure-devops">Azure Pipelines</a> and at least familiarity with <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&amp;tabs=schema%2Cparameter-schema">Azure Pipeline YAML syntax</a>.</blockquote> <p>In this example, I will be building and releasing the <strong>PartsUnlimited</strong> template website from the ADO Demo Generator through the use of a pipeline built using multiple YAML files.</p> <p>Here are the requirements one should take note of in order to complete these steps:</p> <ul> <li> <strong>Azure DevOps Account</strong> — visit <a href="https://dev.azure.com/">dev.azure.com</a> and sign in with your account.</li> <li> <strong>PartsUnlimted Project</strong> — visit <a href="https://azuredevopsdemogenerator.azurewebsites.net/">the Azure DevOps Demo Generator</a> and sign in with your ADO account. Follow the prompts to generate a <strong>PartsUnlimited</strong> project into your ADO organization</li> <li> <strong>Azure Subscription</strong> — to release our website via an Azure App Service you need a linked subscription from <a href="https://portal.azure.com/">portal.azure.com</a>.</li> <li> <strong>Azure Service Connection</strong> — to use Azure resources you will also need <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints?view=azure-devops&amp;tabs=yaml#create-a-service-connection">a valid service connection</a>.</li> <li> <strong>YAML for ADO Pipelines</strong> — In the example below we will be using pure YAML for our ADO build &amp; release pipeline. Make sure you are at least familiar with this process. <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/key-pipelines-concepts?view=azure-devops">Pipeline basics</a> &amp; <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&amp;tabs=schema%2Cparameter-schema">YAML schema</a> for reference.</li> </ul> <h3>1 | Creating the YAML files</h3> <p>Before we create our Pipeline, we need to create the following YAML files in our project directory:</p> <ul> <li>azure-pipelines.yaml - create in root directory</li> <li>build.yaml - create in ./pipeline-templates directory</li> <li>release.yaml - create in ./pipeline-templates directory</li> </ul> <h3>The Main Pipeline File 🔧</h3> <p>We will use the <strong>azure-pipelines.yaml</strong> file as our top-level YAML file.</p> <p><strong>This is the file we will directly link to our Pipeline.</strong> In this file, we specify the template files to use for the individual pipeline stages. <em>See line 11 &amp; 12</em>.</p> <p>We use the build.yaml template file for our build stage, and the release.yaml template file for our release stage :-)</p> <p>Note that these files exist in a directory in our repository and that we could add additional stages using other custom templates as necessary (e.g. QA)</p> <p>Also note, that in our release stage, we need to pass parameters from our <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&amp;tabs=yaml%2Cbatch">Pipeline variables</a>. In this case, I have specified these variables through the ADO pipeline UI. <em>See line 13 to 18</em>.</p> <a href="https://medium.com/media/7cb784b83297a04ad7953fd680f36146/href">https://medium.com/media/7cb784b83297a04ad7953fd680f36146/href</a><h3>The Build Stage 📦</h3> <p>Here we examine the <strong>build.yaml</strong> template file.</p> <p><strong>This is the file that defines the build stage of our pipeline.</strong> In this file, we specify the various build parameters involved in packaging our project ahead of the release stage.</p> <p>Notice the various tasks, associated here, including VSTest@2 task on <em>line 39</em> which will run a series of test cases.</p> <a href="https://medium.com/media/2e7f62efc6f5951e10f956678ae16802/href">https://medium.com/media/2e7f62efc6f5951e10f956678ae16802/href</a><h3>The Release Stage 🔖</h3> <p>Here we examine the <strong>release.yaml</strong> template file.</p> <p><strong>This is the file that defines the release stage of our pipeline.</strong> This is where we create our deployment to an Azure App Service. Notice how we define the default parameters in case they are not explicitly passed from the top-level file.</p> <p>Also note that on <em>line 28</em> you will need to substitute the azureResourceManagerConnection value for an appropriate service connection, and add your subscriptionId to <em>line 29</em> below. On <em>line 47</em> replace the azureSubscription value with your service connection name.</p> <a href="https://medium.com/media/ab3e811ab360741240ca9448403dec40/href">https://medium.com/media/ab3e811ab360741240ca9448403dec40/href</a><h3>2 | Creating the Pipeline</h3> <h3>Select Main YAML file 📃</h3> <p>In Azure DevOps, create a new pipeline <strong>with YAML</strong> and when you get to the <strong>Configure</strong> step, make sure to choose the <strong>Existing Azure Pipelines YAML file</strong>. Select <strong>azure-pipelines.yaml</strong> from the <strong>Path</strong> dropdown as shown below.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/625/0*ng9zVbR_z-IEvywn.png"><figcaption>Creating pipeline from YAML file in Azure DevOps</figcaption></figure><h3>The Result 🎯</h3> <p>After executing your pipeline, you should see the two stages <strong>Build</strong> &amp; <strong>Deploy</strong>.</p> <figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g4rxIsUZ705_xpvG.png"><figcaption>PartsUnlimted Pipeline Execution Result</figcaption></figure><p><em>If you have correctly configured your </em><strong><em>pipeline environment variables, service connection, and Azure subscription</em></strong><em> you should be able to deploy this example site successfully.</em></p> <p>From here you should be able to visit the URL associated with your website to see the deployed site.</p> <h3>Conclusion</h3> <p>Using templates can be helpful in defining comprehensive pipelines that would provide more functional value when modularized. Feel free to take this concept and apply it to your own development efforts. With YAML you can create a range of complex processes made simple through modularization.</p> <h4><strong>Further Reading</strong></h4> <h4> <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops">Pipeline Templates</a><br><a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&amp;tabs=yaml">Building GitHub Repositories</a><br><a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/release/approvals/?view=azure-devops">Release Approvals and Gates Overview</a><br><a href="https://stackoverflow.com/questions/61656077/implementing-gates-in-azure-yaml-pipelines">Gates in YAML Pipelines</a> </h4> <figure><a href="https://faun.to/i9Pt9"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t_MOgMTr_f1N4qHN_R7KVA.png"></a></figure><p>Join FAUN: <a href="https://faun.to/i9Pt9"><strong>Website</strong></a><strong> </strong>💻<strong>|</strong><a href="https://faun.dev/podcast"><strong>Podcast</strong></a><strong> </strong>🎙️<strong>|</strong><a href="https://twitter.com/joinfaun"><strong>Twitter</strong></a><strong> </strong>🐦<strong>|</strong><a href="https://www.facebook.com/faun.dev/"><strong>Facebook</strong></a><strong> </strong>👥<strong>|</strong><a href="https://instagram.com/fauncommunity/"><strong>Instagram</strong></a><strong> </strong>📷|<a href="https://www.facebook.com/groups/364904580892967/"><strong>Facebook Group</strong></a><strong> </strong>🗣️<strong>|</strong><a href="https://www.linkedin.com/company/faundev"><strong>Linkedin Group</strong></a><strong> </strong>💬<strong>|</strong> <a href="https://faun.dev/chat"><strong>Slack</strong></a> 📱<strong>|</strong><a href="https://thechief.io/"><strong>Cloud Native</strong> <strong>News</strong></a><strong> </strong>📰<strong>|</strong><a href="https://linktr.ee/faun.dev/"><strong>More</strong></a><strong>.</strong></p> <p><strong>If this post was helpful, please click the clap 👏 button below a few times to show your support for the author 👇</strong></p> <img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=d55f25a4928c" width="1" height="1" alt=""><hr> <p><a href="https://faun.pub/azure-devops-build-release-with-yaml-templates-d55f25a4928c">Azure DevOps Build &amp; Release with YAML Templates 🚀</a> was originally published in <a href="https://faun.pub/">FAUN.dev() 🐾</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>

Read