<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mike Pfeiffer on Medium]]></title>
        <description><![CDATA[Stories by Mike Pfeiffer on Medium]]></description>
        <link>https://medium.com/@mike.pfeiffer?source=rss-bf1e58ccb70b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*my7sEoN25B9QLFNw4Ifxaw.jpeg</url>
            <title>Stories by Mike Pfeiffer on Medium</title>
            <link>https://medium.com/@mike.pfeiffer?source=rss-bf1e58ccb70b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 10:39:01 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mike.pfeiffer/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Build Your First CI/CD Pipeline using Azure DevOps]]></title>
            <link>https://medium.com/@mike.pfeiffer/build-your-first-ci-cd-pipeline-using-azure-devops-b9dc930cefe1?source=rss-bf1e58ccb70b------2</link>
            <guid isPermaLink="false">https://medium.com/p/b9dc930cefe1</guid>
            <category><![CDATA[continuous-delivery]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[azure]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <dc:creator><![CDATA[Mike Pfeiffer]]></dc:creator>
            <pubDate>Mon, 14 Jan 2019 13:14:41 GMT</pubDate>
            <atom:updated>2019-12-12T23:35:22.567Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2m3KMdgxdbOOcqcmCsvBpg.jpeg" /></figure><p>Continuous integration and continuous delivery (CI/CD) are considered by most to be the backbone of DevOps. Things start to get really interesting when you combine these practices with programmable infrastructure and a suite of services that allow you to automate the entire lifecycle of an application.</p><p>The goal with this guide is to give you a practical example of what that all looks like when you’re building, testing, and deploying applications with Azure DevOps Services. I’ll walk you through the end-to-end process of building a fully automated build and release pipeline for a Node and Express application. We’ll use Azure DevOps Services to create the CI/CD pipeline and Azure App Service for deploying to development/staging and production.</p><p>To follow along, you’ll need a GitHub account and Azure Subscription. The demo application is open source, so the Azure DevOps pipeline infrastructure we build will be covered under the <a href="https://azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/">free tier</a>.</p><h3><strong>Create Your Azure DevOps Organization</strong></h3><p>The first step is to navigate to <a href="https://dev.azure.com/">dev.azure.com</a> and sign in to Azure DevOps. If you’ve never done this before, you’ll need to create a new organization.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/0*nQSX7KVcYZ3BgQEN.jpg" /><figcaption><strong><em>Figure 1.</em></strong><em> Creating an Azure Organization.</em></figcaption></figure><p>You need to have at least one organization, which is used to store your projects, structure your repositories, set up your teams, and manage access to data. The guidance from Microsoft is to keep things simple and start with a single organization. For more advanced scenarios, take a look at <a href="https://docs.microsoft.com/en-us/azure/devops/user-guide/plan-your-azure-devops-org-structure?view=vsts">plan your organization structure</a> in Microsoft’s documentation.</p><p>After clicking on continue, you may end up with an organization name that was generated at random. You can change this as shown in <strong>Figure 2</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/658/0*BM06Z0K8HzCofOjU.jpg" /><figcaption><strong><em>Figure 2.</em></strong><em> Updating Your Azure Organization Name.</em></figcaption></figure><p>Simply navigate to <strong>Organization Settings</strong> &gt; <strong>Overview</strong> and update the name.</p><h3>Fork the Node &amp; Express Demo App Repository</h3><p>I wanted to demonstrate an application that was somewhat realistic but not overly complex for this walkthrough. The Node and Express app is a simple website for a fictitious company. This app uses Express and Handlebars to serve up a few common pages you’d see on any company website. Also included are some unit tests that ensure those routes are working and serving up the right content.</p><p>You can head over to my GitHub account to <a href="https://github.com/mikepfeiffer/node-express-azure">fork this repository</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/828/0*c10qZ7nkehfjDqWm.jpg" /><figcaption><strong><em>Figure 3.</em></strong><em> Fork the </em><strong><em>node-express-azure</em></strong><em> Repository.</em></figcaption></figure><p>Next, we can move on to deploying the infrastructure to support both development and production deployment slots using Azure App Service.</p><h3>Deploy the App Service Infrastructure</h3><p>We’re going to use an Azure Web App for Linux resource to power our Node and Express application. We’ll set things up so our CI/CD pipeline can build and deploy the app into a development/staging slot. Then we’ll set up up a manual approval into the production slot.</p><p>We’ll use an Azure Resource Manager (ARM) template to build the App Service infrastructure.</p><p>Navigate to the <strong>node-express-azure</strong> repository you forked in the previous step. You’ll see a “Deploy to Azure” button about halfway down the screen.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/719/0*yDoeu_ZgZd9k5aii.jpg" /><figcaption><strong><em>Figure 4.</em></strong><em> Deploying the ARM Template.</em></figcaption></figure><p>Clicking the “Deploy to Azure” button will redirect you to the Azure portal as shown in <strong>Figure 5</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/583/0*BV2ZoTX3qcBbksYs.jpg" /><figcaption><strong><em>Figure 5.</em></strong><em> Launching the ARM Template.</em></figcaption></figure><p>Notice that you’ll need to set a globally unique hostname for your web application, along with a name for the new app service plan. I’d recommend deploying these resources into a new resource group. That way when you’re done with this walkthrough, you can clean up the Azure resources easily by deleting the resource group.</p><p>Click “Purchase” to launch the template to agree that you’ll have to pay for the App Service resources that this template deploys on your behalf.</p><p>After you launch the template you should see a successful deployment message, and you should have a new resource group similar to the one shown in <strong>Figure 6</strong>. Notice that there is an App Service Plan, a web app that represents the production deployment slot, and a slot for development called “dev”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/788/0*y2e8dbvhiLRMx_K8.jpg" /><figcaption><strong><em>Figure 6.</em></strong><em> Reviewing the Resources.</em></figcaption></figure><p>Quick side note about the ARM template: the <em>Deploy to Azure</em> button references the <strong>azuredeploy.json</strong> ARM template in <em>my GitHub repository</em>. If you want to update the template, update the version in your own repo, and don’t forget to change the target of the button in the source of your <strong>README.md</strong> file.</p><h3>Create a Build Pipeline</h3><p>We’re ready to move on and set up a build pipeline in Azure DevOps. Head back to dev.azure.com and create a new project inside your organization. Use the settings shown in <strong>Figure 7</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/592/0*hILJTzg9j5H38jS0.jpg" /><figcaption><strong><em>Figure 7.</em></strong><em> The New Project Settings.</em></figcaption></figure><p>After clicking on the “Create project” button, you’ll see a summary page for the project. Navigate to <strong>Pipelines</strong> and click on <strong>Builds</strong> as shown in <strong>Figure 8</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/804/0*0tSc5FvFigV_iaND.jpg" /><figcaption><strong><em>Figure 8.</em></strong><em> Creating a New Build Pipeline.</em></figcaption></figure><p>Next, click the button to create a new build pipeline. You’ll be prompted to choose a repository. Select <strong>GitHub</strong>. You’ll see a screen like the one in <strong>Figure 9</strong> where you’ll need to authorize the Azure DevOps service to connect to your GitHub account on your behalf. Click <strong>Authorize</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/609/0*b5IeILiynyLGn_7y.jpg" /><figcaption><strong><em>Figure 9.</em></strong><em> Authorizing the GitHub Connection.</em></figcaption></figure><p>After your connection to GitHub has been authorized select the <strong>node-express-azure</strong> repo that you forked in the first step. You should end up seeing a “New pipeline” screen like the one shown in <strong>Figure 10</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/991/0*ri3OeQotgy5tOuyB.jpg" /><figcaption><strong><em>Figure 10.</em></strong><em> Creating the New Build Pipeline.</em></figcaption></figure><p>The new pipeline wizard should recognize that we already have an <strong>azure-pipelines.yml</strong> in the repository. This file contains all of the settings that the build service should use to build and test our application, as well as generate the output artifacts that will be used to deploy the app later in our release pipeline.</p><p>After you click “Run” to kick off your first build, you should see a screen like the one shown in <strong>Figure 11</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/747/0*IRFXFliP02d1LosK.jpg" /><figcaption><strong><em>Figure 11.</em></strong><em> Reviewing the Build Status.</em></figcaption></figure><p>Notice that a lot went on with the build. The service used an Ubuntu 16.04 build agent to grab the code from GitHub, installed our development dependencies, and then ran our unit tests to validate the application. Finally, the code was bundled into an output artifact and published so we can use it as an input artifact for our upcoming release pipeline.</p><p>Click on the release button at the top of this screen to create a new release pipeline.</p><h3>Create a Release Pipeline</h3><p>When you get into the release pipeline screen, you’ll need to select a template. For this scenario, we are going to choose “App Service deployment with slot”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/635/0*ZadJf2kfPZZb0SGA.jpg" /><figcaption><strong><em>Figure 12.</em></strong><em> Selecting the Deployment Template.</em></figcaption></figure><p>Click on the apply button to create the new deployment stage within the release pipeline. On the next screen, you’ll be able to configure this stage. Change the name to “development” as shown in <strong>Figure 13</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/943/0*0L9ZxwB7aEh0mUDX.jpg" /><figcaption><strong><em>Figure 13.</em></strong><em> Updating the Development Stage.</em></figcaption></figure><p>While on this screen, click on the link that says “2 tasks” inside your development stage. This will take you to a screen where you can configure the deployment task. Make sure you fill out all the fields as shown in <strong>Figure 14</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9LV5Dy1Lbo2hjXkK.jpg" /><figcaption><strong><em>Figure 14.</em></strong><em> Configuring the Deployment Task.</em></figcaption></figure><p>Next, highlight and remove the second deployment task for swapping the slots.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1011/0*SQUABNVL2DyiKa8P.jpg" /><figcaption><strong><em>Figure 15.</em></strong><em> Removing the Slot Swap Task.</em></figcaption></figure><p>Finally, click Save.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1004/0*d-8AaPJ6Ebagvmk3.jpg" /><figcaption><strong><em>Figure 16.</em></strong><em> Save the Changes to the Development Stage.</em></figcaption></figure><p>Head back over to the “Pipeline” tab at the top left of the screen. Inspect the deployment triggers for the artifacts as shown in <strong>Figure 17</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/0*AVkdEjzKf4CSK2nN.jpg" /><figcaption><strong><em>Figure 17.</em></strong><em> Reviewing the Deployment Trigger.</em></figcaption></figure><p>Notice that continuous deployment is enabled by default. Going forward, each new build will trigger a deployment to our development slot in Azure App Service.</p><p>First, let’s trigger a manual release.</p><h3>Create Your First Release to Development</h3><p>Click the “Release” button on the top right of the release pipeline screen and create a new release. Use the settings as shown in <strong>Figure 18</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/547/0*CLMB4jpMF9DPcO25.jpg" /><figcaption><strong><em>Figure 18.</em></strong><em> Triggering a Release.</em></figcaption></figure><p>Click on the “Create” button to deploy the application to the development deployment slot. You should see a successful status in the properties of the release.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/0*ptaZ1RURtpWCCrBO.jpg" /><figcaption><strong><em>Figure 19.</em></strong><em> Reviewing the Release Status.</em></figcaption></figure><p>Navigate to the public URL of the “dev” deployment slot in your web browser. The hostname will have “-dev” appended to it. For example, my web app is named “node-express-demo” and the “dev” deployment slot URL is <a href="https://node-express-demo-dev.azurewebsites.net./">https://node-express-demo-dev.azurewebsites.net.</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/905/0*0q3nfefoDChI-fbg.jpg" /><figcaption><strong><em>Figure 20.</em></strong><em> The Demo Node App Running in the “dev” Deployment Slot.</em></figcaption></figure><p>You should see the sample web application when you visit the “dev” slot URL. The production slot will show the default Azure App Service splash page since it is virtually untouched at this point. Let’s change that in the next step.</p><h3>Create a Release Stage for Production</h3><p>Head back over to the Azure DevOps portal and go to <strong>Pipelines</strong> &gt; <strong>Releases</strong>. Click on the “Edit” button to modify the pipeline. Highlight the <strong>Development</strong> stage and click the dropdown to clone the stage.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/659/0*aBo_oRNOm2QV3gbU.jpg" /><figcaption><strong><em>Figure 21.</em></strong><em> Cloning the Development Stage.</em></figcaption></figure><p>Rename the stage to “Production”.</p><p>Next, click the pre-deployment conditions button for the <strong>Production</strong> stage. Enable pre-deployment approvals and add yourself as an approver.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/971/0*4u2aVF-JacX9IrpR.jpg" /><figcaption><strong><em>Figure 22.</em></strong><em> Requiring Approval for Production Deployment.</em></figcaption></figure><p>We’re doing this because we don’t want automated deployments going straight into production. We’re not building a continuous deployment pipeline for production. We’re building continuous delivery pipeline.</p><p>Continuous delivery is a process that ensures our application is production ready. When we are doing a scheduled deployment we can do so with confidence since we know the application has been through a pipeline of tests before-hand.</p><p>Next, click on the “task” link on the <strong>Production</strong> stage. We need to modify this task so that it does not deploy our code into the development slot.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/450/0*ZLIOdSerGjm4JKsq.jpg" /><figcaption><strong><em>Figure 23.</em></strong><em> Updating the Deployment Task.</em></figcaption></figure><p>Simply uncheck “slot” and this will infer that the production slot of the web app should be used during the deployment. Click save when complete.</p><h3>Validating the Pipeline</h3><p>Navigate to your GitHub account and into the views folder of the demo application. Edit the index.handlebars file to update the app to version 2.0.0.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/975/0*m0f6uGQFUbsyiPi-.jpg" /><figcaption><strong><em>Figure 24.</em></strong><em> Radically Modifying the Code Base for the App.</em></figcaption></figure><p>Committing the change in this repo should automatically trigger a build, perform our tests, and publish a deployment package. We can confirm this by reviewing the build status.</p><p>After the build, you should see a new release. The development stage should be green indicating that the deployment succeeded. The production stage should be blue and show that it’s pending approval.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/692/0*kQZtcZJ2_RZgohW1.jpg" /><figcaption><strong><em>Figure 25.</em></strong><em> Reviewing the Release Status.</em></figcaption></figure><p>Click approve to kick-off the production deployment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/0*tL4StOPDWqz1n0O1.jpg" /><figcaption><strong><em>Figure 26.</em></strong><em> Deploying to Production. Never do this on a Friday!</em></figcaption></figure><p>Go back to your pipeline view and you should see the deployment to production succeeded.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/824/0*WTsKMg7VBzIsasIl.jpg" /><figcaption><strong><em>Figure 27.</em></strong><em> Validating the Status.</em></figcaption></figure><p>Finally, head over to the web app URL for the production slot to confirm the correct version is running.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*6yAYyjfayDSSU1B9.jpg" /><figcaption><strong><em>Figure 28.</em></strong><em> Reviewing the Version.</em></figcaption></figure><p>You should see version 2.0.0 on the homepage.</p><h3>Set up a Build Badge for Your Project</h3><p>Have you ever seen those build pass/fail badges when browsing projects on GitHub? They’re really cool because you can tell at a glance if the code is still working or if it’s old and busted.</p><p>Let’s set up a badge for this project.</p><p>Go back to your Builds section and click the status badge button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/733/0*3BieP_ZKi5x-Clir.jpg" /><figcaption><strong><em>Figure 29.</em></strong><em> Locating the Status Badge Button.</em></figcaption></figure><p>Copy the markdown code for the status badge.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/566/0*R87ADGTMWzMiW2rY.jpg" /><figcaption><strong><em>Figure 30.</em></strong><em> Copying the Markdown.</em></figcaption></figure><p>Now, go back to GitHub and modify the README.md file in your <strong>node-express-azure</strong> repo. Paste the markdown you copied from the status badge page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/935/0*MCm3jolPa26Wdi4X.jpg" /><figcaption><strong><em>Figure 31.</em></strong><em> Updating README.md.</em></figcaption></figure><p>Commit the change and view the README. You should see a build passing status icon.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/915/0*poNyK8dUwI_VK41J.jpg" /><figcaption><strong><em>Figure 32.</em></strong><em> Badge Status Icon in Action.</em></figcaption></figure><p>If you’re still reading after all this time, respect! You now know who to build a CI/CD pipeline on Azure.</p><p>You can simply delete all the resources to clean things up. Delete the resource group you created for this project, delete the Node demo project in the Azure DevOps portal, and delete the GitHub repo that you forked from my account (unless you want to keep a copy).</p><h3>Where to go from here</h3><p>Isn’t this awesome stuff? There’s so much more. For now, check out these resources to dive deeper.</p><ul><li><a href="https://docs.microsoft.com/en-us/learn/modules/get-started-with-devops/">Get started with Azure DevOps</a></li><li><a href="https://docs.microsoft.com/en-us/azure/devops/learn/">DevOps Resource Center</a></li><li><a href="https://academy.microsoft.com/en-us/professional-program/tracks/devops/">Microsoft Professional Program for DevOps</a></li></ul><p><em>Originally published at </em><a href="https://cloudskills.io/blog/azure-devops-pipeline"><em>cloudskills.io</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b9dc930cefe1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Amplify Your IT Career by Building Infrastructure Development Skills]]></title>
            <link>https://medium.com/@mike.pfeiffer/amplify-your-it-career-by-building-infrastructure-development-skills-a293110c8188?source=rss-bf1e58ccb70b------2</link>
            <guid isPermaLink="false">https://medium.com/p/a293110c8188</guid>
            <category><![CDATA[azure]]></category>
            <category><![CDATA[version-control]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[configuration-management]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <dc:creator><![CDATA[Mike Pfeiffer]]></dc:creator>
            <pubDate>Thu, 03 Jan 2019 21:27:34 GMT</pubDate>
            <atom:updated>2019-12-15T18:33:25.468Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7Fv7y4HzFQ0lT1o3M2H9kA.jpeg" /></figure><p>Public and private cloud platforms have changed the IT landscape. With virtualization and cloud computing, it’s easier than ever to spin up a fully functional application environment with a single button click or API call. The world of server deployment and administration is much different than it was ten years ago, and it will never be the same.</p><p>This is great news because businesses can now move much faster than ever before. And the reality is, many of them must do so in order to keep up with their competitors.</p><p>The challenge is, you’ll want to start thinking like a software developer if you plan to stay in the trenches over the long term in the tech industry.</p><p>Here’s why. Most technologies are shifting to a new paradigm where software development practices are being applied to infrastructure. Speed, agility, consistency, and predictability are all characteristics of platforms that power modern day applications. The infrastructure engineers of the future will be expected to have deep automation expertise.</p><p>IT pros who want to thrive in the tech industry in the coming years should learn the core principles of infrastructure development. Those who do will hold in-demand skills in a world where almost everything is software defined.</p><p>Here are four areas to focus on to start building infrastructure development skills.</p><h3>Infrastructure as Code</h3><p>Imagine being able to click a button in a web console, and like magic, you have a fully built server environment, complete with Domain Controllers, SQL Servers, and a new SharePoint farm ready to serve users.</p><p>Sounds far-fetched, but this is something that you can do today using an <a href="https://azure.microsoft.com/en-us/resources/templates/sharepoint-server-farm-ha/">Azure Resource Manager (ARM)</a> template.</p><p>Here’s how it works. All the infrastructure required to power the servers is declared in a plain text file. Technically, it’s a JSON template, which means it’s really just a set of key/value pairs. Think of it as a list of resources with their required settings. For example, in the file, there are blocks of code that describe the virtual network, storage, servers, and along with all of their detailed settings.</p><p>All of the infrastructure for the deployment is referenced in the template. It’s human readable, and anyone with a basic understanding of the syntax can look at the template and understand it’s intent.</p><p>These templates can be deployed interactively in a web browser, or via an API call as part of an automated process.</p><p>With infrastructure written in code, you always know exactly how the environment is supposed to be configured. You literally have a blue-print of the entire environment that you can execute if you ever need to rebuild it.</p><p>Imagine the possibilities this opens up when you want to test something.</p><p>Your first step to becoming an infrastructure developer is to <a href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-quickstart-create-templates-use-the-portal">start learning the basics</a> of infrastructure as code. If you’re working with Azure, start educating yourself about ARM templates. Try to build one that does something simple, like building a standalone server.</p><h3>Configuration Management</h3><p>Servers that are launched from an infrastructure template also need to be configured. They need software installed and configured, and there needs to be a mechanism to keep them in their desired state. That’s where configuration management comes into play.</p><p>For example, that ARM template that spins up the SharePoint environment is mostly focused on building the server infrastructure. It’s creating the virtual network, storage, VM’s, and so on. The servers actually boot with a plain operating system.</p><p>Once the servers are up and running, a configuration management solution is used to boot strap the applications. In this case, the technology happens to be <a href="https://docs.microsoft.com/en-us/azure/virtual-machines/extensions/dsc-template">PowerShell DSC</a>.</p><p>Most configuration management solutions follow similar patterns. Like infrastructure templates, configuration management code tells each server what software should be installed, and how it should be configured.</p><p>As an infrastructure developer, you’ll need skills with a configuration management solution like PowerShell DSC. The good news is that once you’ve learned one, it’ll be easier to pick up another. For example, DSC implements many patterns used in other configuration management tools like Chef, Puppet, and Ansible, to name a few.</p><p>Infrastructure as code templates, along with startup scripts or configuration management scripts, can provide an end-to-end automated solution for an application and all of its dependencies.</p><h3>Version Control</h3><p>When developers build applications, they typically do so in teams. In order to make life easier for everyone, the code is typically stored in a central location, like a version control repository.</p><p>It’s a common practice for developers to make very small, incremental changes to the code base for an application. Those changes get committed into the code base in the version control repository. If there’s an issue, the change can be reverted easily, since it was a small change.</p><p>Each time code is committed to the repository, meaningful notes are included about the change. This gives everyone a clear picture of what changed from one version to the next. Teams can even compare the new version of the code with the previous one side-by-side to see what was done.</p><p>This is exactly what infrastructure developers need to do as well. All of your infrastructure templates and configuration management scripts should live in a version control repository. Git-based version control systems, <a href="https://guides.github.com/activities/hello-world/">like GitHub</a>, are widely used.</p><p>As an infrastructure developer, you’ll want to learn how to use Git, which is a version control tool. You can use it to store your code in a repository on GitHub, which is simply a platform for hosting git-based version control repositories.</p><h3>Continuous Integration and Delivery (CI/CD)</h3><p>When a software developer commits a small code change to a version control repository, that change is often tested. For example, if it’s a C# application, an automated process can take the code and make sure it compiles without any errors. It can also run other tests to make sure the code was written correctly. This process is known as continuous integration (CI).</p><p>The idea with CI is that developers get fast feedback on whether or not their changes are working. If they get build errors or the tests fail, they know they need to address thing right away.</p><p>Once the code has passed through those basic checks, it might be useful to perform further analyses, like performance or user interface tests. This, of course, requires infrastructure to run the code.</p><p>As a next step in the process, the team could invoke an infrastructure as code template to build a clone of the production environment. Once the servers are up and running, the latest version of the code can be deployed and tested.</p><p>If everything checks out, the team knows they have a known-good version of the code that is production ready, which is the basis for Continuous Delivery (CD).</p><p>As an infrastructure developer, you’ll want to be able to work with software developers and understand their world. To do that, learn the basics of the CI/CD release pipeline workflow. It’s simply a chain of events that takes code committed in version control to being fully validated and considered ready for production use. Azure focused infrastructure developers will want to look into the <a href="https://azure.microsoft.com/en-us/blog/introducing-azure-devops/">Azure DevOps platform</a>.</p><h3>Where to go from here</h3><p>There’s a lot to learn as an infrastructure developer. The good news is; most organizations are still in the very early stages of figuring out how to do this efficiently. There will be big opportunities for those who decide to take advantage of this shift in the industry. Here are some resources to help you get started:</p><ul><li><a href="https://docs.microsoft.com/en-us/learn/modules/get-started-with-devops/">Get started with Azure DevOps</a></li><li><a href="https://docs.microsoft.com/en-us/learn/modules/build-azure-vm-templates/">Build Azure Resource Manager templates</a></li><li><a href="https://blogs.msdn.microsoft.com/mvpawardprogram/2018/05/01/azure-resource-manager/">Best Practices For Using Azure Resource Manager Templates</a></li></ul><p>Infrastructure as Code is the topic for my next podcast episode on <a href="https://cloudskills.fm/">CloudSkills.fm</a>. Please subscribe if you’re interested in this topic and feel free to send me your questions. I’ll answer them on the show.</p><p><em>Originally published on </em><a href="https://www.linkedin.com/pulse/amplify-your-career-building-infrastructure-skills-mike-pfeiffer/"><em>LinkedIn</em></a><em> and </em><a href="https://cloudskills.io/blog/infrastructure-developer"><em>CloudSkills.io</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a293110c8188" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build, Run, and Continuously Deploy Docker Containers on Azure App Service]]></title>
            <link>https://medium.com/@mike.pfeiffer/build-run-and-continuously-deploy-docker-containers-on-azure-app-service-83974329e9d6?source=rss-bf1e58ccb70b------2</link>
            <guid isPermaLink="false">https://medium.com/p/83974329e9d6</guid>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[azure]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[docker]]></category>
            <dc:creator><![CDATA[Mike Pfeiffer]]></dc:creator>
            <pubDate>Thu, 27 Dec 2018 17:38:12 GMT</pubDate>
            <atom:updated>2020-01-03T16:00:07.869Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IW5vuEViNkTIX5DMqnNYyA.jpeg" /></figure><p>If you’re thinking about investing your time to pick up new skills, you can’t go wrong with learning how to build, run, and manage containers.</p><p>That’s probably not a big surprise. Based on all the excitement, headlines, and success stories coming out of tech news every day, there’s no doubt we’ll see even more container adoption going forward. But, it’s still very early in the game. And that means there’s a massive opportunity for those who embrace this new approach to building modern applications.</p><p>My goal with this tutorial is to hopefully spark your interest in this topic or give you some new ideas to try out on your own. I’ll show you a quick and easy way to store and run your container images on Microsoft’s Azure platform.</p><p>We’ll take a look at how to build a container image locally, push that image to the Azure Container Registry, and then run and continuously deploy updates to that container using Azure Web App for Containers. It’s a great way to run a single container for a web application.</p><p>We’ll keep things simple, but practical. And, if you want to follow along, all you’ll need is Git and Docker Desktop installed locally, along with an Azure account.</p><h3>Building the Azure Container Registry (ACR) Resource</h3><p>Container images provide the foundation for applications running inside Docker containers. You can think of an image as an executable package that includes everything you need to run an application. Your container images include application code, the runtime environment, libraries, configuration files, and environment variables. Containers that you spin up to power an application are merely a running instance of a container image.</p><p>Container images live in public or private container registries, and servers running the Docker engine download those images to start and run containers. The default container registry for Docker containers is <a href="http://hub.docker.com/">hub.docker.com</a>, which offers over 100,000 container images from ISVs, open-source projects, and community contributors. You can use this service to store your images in public or private repositories.</p><p>Microsoft also offers the Azure Container Registry (ACR), which is a managed Docker registry service based on the open-source Docker Registry 2.0 platform.</p><p>Using ACR for container deployments allows you to store your custom container images privately in the Azure cloud. ACR natively integrates with multiple Azure services, and teams can use ACR tasks to automate deployments when building new images, or when code is committed to version control. ACR also provides a low-latency endpoint to pull images from when your Docker hosts are running in the Azure cloud.</p><p>For this tutorial, we’re going to provision a new ACR instance. We’ll build a custom Docker image and push it to ACR so we can use it later with Azure Web App for containers.</p><p>In the Azure portal, select <strong>Create a resource</strong>, select <strong>Containers</strong> in the Azure Marketplace, and choose <strong>Container Registry</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/540/0*dVHer0Ik6Oz98bgE.jpg" /></figure><p><strong><em>Figure 1.</em></strong><em> Creating an ACR Resource.</em></p><p>Enter a globally unique, DNS-compliant hostname for your registry under the azurecr.io namespace. Set the destination resource group and make sure you enable the option for <strong>admin user</strong> and click on Create.</p><p>Once provisioning is complete, navigate to your ACR resource in the portal and select <strong>Access Keys</strong> under the settings section. Here you will see your login server, admin username, and passwords.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/751/0*fWpevXES52nv9i4y.jpg" /></figure><p><strong><em>Figure 2.</em></strong><em> Retrieving the ACR Credentials.</em></p><p>Finally, fire up a terminal and use the docker login command to authenticate to ACR and validate the credentials.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/737/0*24yOF_mUXHqXKZv3.jpg" /></figure><p><strong><em>Figure 3.</em></strong><em> Logging into the ACR.</em></p><p>You should see a message that says “login succeeded” as shown in <strong>Figure 3</strong>.</p><h3>Cloning the Sample Node &amp; Express Application</h3><p>Next, we’re ready to package up an application into a container image. For this example, we’ll use a bare-bones Node.js and Express application from my <a href="https://github.com/mikepfeiffer/">Github</a> account. The app is really basic and simply returns a “hello world” message when you visit the web application.</p><p>Open a terminal or command prompt and switch to a directory where you want to store the source code locally. Use the following command to clone the repo:</p><pre>git clone <a href="https://github.com/mikepfeiffer/node-docker-demo.git">https://github.com/mikepfeiffer/node-docker-demo.git</a></pre><p>After you’ve cloned the repo, switch into the application directory:</p><pre>cd node-docker-demo/</pre><p>Inside the local repo you’ll see the following set of files and folders:</p><pre>├── Dockerfile<br>  ├── LICENSE<br>  ├── README.md<br>  ├── app.js<br>  ├── config.js<br>  ├── package-lock.json<br>  ├── package.json<br>  └── test<br>      └── index_test.js</pre><p>The main thing to focus on here is the <strong>Dockerfile</strong> included with the application. This will give Docker all the instructions to build our container image. Open the Dockerfile in a text editor to review the commands. You’ll see something like the output in <strong>Figure 4</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/16aa913805dccdd219a8d6ead0e9e5c5/href">https://medium.com/media/16aa913805dccdd219a8d6ead0e9e5c5/href</a></iframe><p><strong><em>Figure 4.</em></strong><em> Reviewing the Dockerfile.</em></p><p>The commands in the Dockerfile will be used to build the image locally before we push it to ACR. Let’s break it down line by line.</p><ul><li><strong>Line 1: </strong>The <strong>FROM</strong> command defines the base container image. In this case, we’ll use the official Node.js image available in the Docker Hub. Notice we’re not explicitly referencing a container registry for this image. This means we’ll pull down the Node.js container image from the default container registry (Docker Hub). Also note that the image uses an <strong>alpine</strong> tag. This means we’ll use the Node.js container image based on Alpine Linux, which is a Linux distro designed for security and resource efficiency. It will allow us to keep the container image very small at less than 90 MB in size.</li><li><strong>Line 3:</strong> The <strong>WORKDIR</strong> command sets the working directory and is where we’ll store the application code. If the path indicated doesn’t exist it will get created during the build process.</li><li><strong>Line 5:</strong> The <strong>COPY</strong> command will be used during the build process to add the package.json and package-lock.json files to the working directory. Note that, instead of copying the entire application at this stage, we are only copying the package*.json files. This allows us to take advantage of cached Docker layers to improve our development workflow, which you can read about <a href="http://bitjudo.com/blog/2014/03/13/building-efficient-dockerfiles-node-dot-js/">here</a>.</li><li><strong>Line 6:</strong> Next, the <strong>RUN</strong> command is used to execute <strong>npm install</strong> which will ensure our application dependencies are included within the container image.</li><li><strong>Line 7:</strong> The <strong>COPY</strong> command is used to copy the application source files into the working directory.</li><li><strong>Line 9:</strong> Finally, <strong>CMD</strong> defines the default command to execute when the container starts. In this case, <strong>npm start</strong> will run the start script defined in the package.json file to get our node server up and running.</li></ul><p>Now that we understand what will be included in our container image, we’re ready to run a build.</p><h3>Building the Container Image</h3><p>Head back over to the command-line. Make sure your context is set to the root of the application. You should be in the same directory as the Dockerfile. Use the docker build command to create your container image.</p><pre>docker build -t &lt;YOUR REGISTRY NAME&gt;.azurecr.io/node-docker-demo:latest .</pre><p>This command will tell Docker to build your image using the Dockerfile in the current directory. It will also tag your image with your ACR repository name, an image name, and version set to <strong>latest</strong> to indicate that this image is the current version of the application.</p><p>Since the registry name is included in the image tag, the Docker client will intuitively know where to send the image when we run a push in the next step.</p><h3>Pushing the Image to ACR</h3><p>Since we already logged in using <strong>docker login</strong>, all that’s left to do is push the image up to ACR using the following syntax.</p><pre>docker push &lt;YOUR REGISTRY NAME&gt;.azurecr.io/node-docker-demo:latest</pre><p>After the command completes successfully, you can head back to the Azure portal to verify that your image is now available in ACR.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/984/0*7lmG7oalD7nspWX6.jpg" /></figure><p><strong><em>Figure 5.</em></strong><em> Reviewing the image in ACR. Building the Web App Resource.</em></p><p>With the image available in ACR, we’re ready to build a Web App resource that can host the application. In the Azure portal, select <strong>Create a resource</strong>, select <strong>Web</strong> in the Azure Marketplace, and choose <strong>Web App</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/0*sOzgD6w8vvU3zD76.jpg" /></figure><p><strong><em>Figure 6.</em></strong><em> Creating the Web App Resource.</em></p><p>Enter a globally unique, DNS-compliant hostname for your web app under the azurewebsites.net namespace. Set the destination resource group and choose Linux as the OS. Make sure the publish settings are configured to use a container as shown in <strong>Figure 6</strong>. You’ll be able to browse and find your custom container image in ACR. Click on <strong>Apply</strong> and <strong>Create</strong>.</p><p>Open a web browser and navigate to the URL for your new Azure Web App. You should see “Hello World!” on the home page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/724/0*dynsYzJWe3nToNHW.jpg" /></figure><p><strong><em>Figure 7.</em></strong><em> Testing the Web App.</em></p><p>Now that we have the app up and running we can setup continuous deployment.</p><h3>Enabling and Validating Continuous Deployment</h3><p>Navigate to your Web App resource in the Azure portal. Select <strong>Container settings</strong> as shown in <strong>Figure 8</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/868/0*8nwpsYvFrEKLi5Ud.jpg" /></figure><p><strong><em>Figure 8.</em></strong><em> Updating the Web App.</em></p><p>Switch Continuous Deployment to <strong>On</strong> and click on <strong>Save</strong>.</p><p>This will create an ACR webhook behind the scenes. Anytime we push an updated image to ACR it will trigger a deployment in Azure App Service. This means we can update and rebuild our image locally, push it back to ACR, and the website will be updated without us having to do anything else. You’ll see the webhook in the same resource group as your web app in the Azure portal.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/583/0*QrWzLmRt1JXcPtkl.jpg" /></figure><p><strong><em>Figure 9.</em></strong><em> Reviewing the Webhook.</em></p><p>Now that continuous deployment is enabled, we can test out. Fire up your code editor and open the app.js file in the root of the application that we cloned earlier. Modify line 7 to return a new message. For this example, I’ll update the code to return “Hello World v2!” when a user visits the page.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5085c0865d72399b39b5f03d9472bc37/href">https://medium.com/media/5085c0865d72399b39b5f03d9472bc37/href</a></iframe><p><strong><em>Figure 10.</em></strong><em> Updating the app.js file.</em></p><p>Once the code has been updated, rebuild the container image:</p><pre>docker build -t &lt;YOUR REGISTRY NAME&gt;.azurecr.io/node-docker-demo:latest .</pre><p>Then push the new container image to ACR:</p><pre>docker push &lt;YOUR REGISTRY NAME&gt;.azurecr.io/node-docker-demo:latest</pre><p>The push will trigger the webhook.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/577/0*1R3lMZqWr0YK8hiV.jpg" /></figure><p><strong><em>Figure 11.</em></strong><em> Reviewing the Webhook History.</em></p><p>Then we can visit our web app and see that it’s serving the new version of the application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/723/0*Kr0irDmOJzm-DuTI.jpg" /></figure><p><strong><em>Figure 12.</em></strong><em> Validating the Deployment.</em></p><p>Isn’t that awesome? This is a really slick solution for those who want to streamline the deployment process for single container-based web apps.</p><h3>Where to go from here</h3><p>There’s so much more when it comes to running Docker containers on Azure. Check out some of these resources to help you get started.</p><ul><li><a href="https://docs.microsoft.com/en-us/azure/containers/">Azure for Containers</a></li><li><a href="https://labs.play-with-docker.com/">Play with Docker (If you’re new to Docker)</a></li><li><a href="https://docs.microsoft.com/en-us/learn/modules/build-and-store-container-images/">Build and store container images with Azure Container Registry</a></li><li><a href="https://docs.microsoft.com/en-us/azure/app-service/containers/tutorial-custom-docker-image">Use a custom Docker image for Web App for Containers</a></li></ul><p><em>Originally published at </em><a href="https://cloudskills.io/blog/azure-docker-containers"><em>https://cloudskills.io/blog/azure-docker-containers</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83974329e9d6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build Your First Serverless Web Application on Azure]]></title>
            <link>https://medium.com/@mike.pfeiffer/build-your-first-serverless-web-application-on-azure-551e6debbae3?source=rss-bf1e58ccb70b------2</link>
            <guid isPermaLink="false">https://medium.com/p/551e6debbae3</guid>
            <category><![CDATA[azure]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[serverless]]></category>
            <dc:creator><![CDATA[Mike Pfeiffer]]></dc:creator>
            <pubDate>Mon, 17 Dec 2018 23:19:20 GMT</pubDate>
            <atom:updated>2018-12-17T23:22:50.762Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0zkDBKk5kZdMtDCjH233kA.jpeg" /></figure><p>This is a tutorial for absolute beginners.</p><p>Whether you’re a developer or an operations engineer, it’s a good idea to start wrapping your brain around the fundamental concepts of serverless computing. The technology is still in its infancy, but I believe it will radically shift how many applications are built in the years to come.</p><p>In this guide, I’ll walk you through setting up a <strong>super basic</strong> serverless web application on Azure. Just a simple webform that sends and receives data <em>to</em> and <em>from</em> an Azure Function.</p><p>The HTML page for this serverless application will be hosted in an Azure Storage account. Users will visit the webpage and submit a message. The form will trigger an Azure Function that will send a message back to the user. There will be no virtual machines involved. Just code. Hence the term serverless ;)</p><p>Here’s the good news; you don’t need to be an experienced programmer to follow along with this tutorial. I’ll show you how to build the resources you’ll need in Azure, and I’ll give you some sample code to try out.</p><p>Sound good? Let’s go.</p><h3><strong>Before We Begin</strong></h3><p>We need to build a handful of Azure resources to support both the front-end and the back-end of the application. We’ll create an Azure Storage account, build an Azure Function, and then deploy and test a simple HTML web page.</p><p>Yes, we could automate all of this work, but that’s a topic for another post. My goal here is to help you grasp the concept of a serverless web app using a simple example with minimal steps.</p><p>However, we will use the Azure CLI as much as possible as we build the infrastructure. I’ll try to minimize the steps required in the portal since the UI tends to change frequently.</p><p>Don’t worry about installing the Azure CLI locally unless you want to. You can use <a href="https://shell.azure.com/">shell.azure.com</a> to run the CLI in a web browser, or you can run it <a href="https://www.michaelcrump.net/azure-tips-and-tricks49/">inside VS Code</a>.</p><h3><strong>Step 1. Building the Azure Storage Account</strong></h3><p>Fire up the Azure CLI. If you have more than one Azure subscription you should make sure your CLI session is set accordingly. You can get a list of your subscriptions and their id’s by running:</p><pre>az account list --query [].[name,id]</pre><p>If you have more than one subscription, use the output from the above command to scope your CLI session to the desired subscription id using the syntax below:</p><pre>az account set --subscription &lt;YOUR SUBSCRIPTION ID&gt;</pre><p>Next, create a resource group to store the resources for the application. If you’re not sure what the region names are you can use the “az account list-locations” command. I’m using <strong>westus2</strong>.</p><pre>az group create --location &lt;YOUR REGION&gt; --name &lt;YOUR GROUP NAME&gt;</pre><p>Now we are ready to create the Storage Account. Make sure you use a globally unique DNS-compliant name for the storage account using the <strong>— name</strong> flag. Also note that only GPv2 storage accounts allow you to serve static content like HTML, CSS, JavaScript, and images. Therefore, the <strong>— kind</strong> flag must be set to <strong>StorageV2</strong> as shown below.</p><pre>az storage account create \ <br>    --location &lt;YOUR REGION&gt; \<br>    --name &lt;YOUR STORAGE ACCOUNT NAME&gt; \ <br>    --resource-group &lt;YOUR GROUP NAME&gt; \ <br>    --sku Standard_LRS \ <br>    --kind StorageV2</pre><p>Now that the storage account is created, we need to enable static website hosting. As I am writing this article, static website hosting for GPv2 storage accounts is generally available, but we still need to install the storage preview extension to enable it via the CLI. Run the following command to install the extension:</p><pre>az extension add --name storage-preview</pre><p>The final step is to enable static website hosting. Make sure to update the <strong>— name</strong> flag to reflect your storage account name:</p><pre>az storage blob service-properties update \ <br>    --account-name &lt;YOUR STORAGE ACCOUNT NAME&gt; \ <br>    --static-website \ <br>    --index-document index.html</pre><p>If you run into problems creating the storage account or enabling static website hosting from the CLI, you can do this work through the Azure portal using the steps outlined in <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website">this guide</a> in the Azure documentation.</p><p>Here’s what you should see in the portal after running the above CLI commands or manually enabling static website hosting:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/865/0*i9TVAswgTenf3NQH.jpg" /></figure><p><strong>Figure 1.</strong> Reviewing the static website properties.</p><p>Notice that the default document is set to <strong>index.html</strong>. That file doesn’t exist yet. We’ll deploy it later. Go ahead and record the primary endpoint URL for the static website as shown in <strong>Figure 1</strong> because we’ll need this value in the next step.</p><h3><strong>Step 2. Building the Azure Function App</strong></h3><p>Now it’s time to create a function app. Think of a function app as a resource that hosts the execution of one or more serverless functions. The way the function app is configured will be unique for each application because it controls the underlying OS platform and runtime stack. The function app settings also control the billing model you’ll use for your serverless functions.</p><p>Take a look at the CLI command below. You can see we’ll be using the <strong>az functionapp create</strong> command to build the function app. The <a href="https://github.com/Azure/Azure-Functions/wiki/Consumption-Plan-Cost-Billing-FAQ">consumption plan</a> location defines where our code will run and how we’re billed. Azure Functions consumption plan is billed based on per-second resource consumption and executions and includes a monthly free grant of 1 million requests. Also, pay close attention to the <strong>— name</strong> flag. Like Azure Storage, the name must be a DNS-compliant globally unique value as it will be used as the host portion of the URL for the function app. We’ll set the runtime <strong>node</strong>. Make sure you update all the values in the example below and then run the command to create the function app.</p><pre>az functionapp create \ <br>    --resource-group &lt;YOUR GROUP NAME&gt; \ <br>    --consumption-plan-location &lt;YOUR REGION&gt; \ <br>    --name &lt;YOUR FUNCTION APP NAME&gt; \ <br>    --storage-account &lt;YOUR STORAGE ACCOUNT NAME&gt; \ <br>    --runtime node</pre><p>After the function app has been created we need to update the Cross-Origin Resource Sharing (CORS) configuration. <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> is a mechanism that tells a web browser connected to one origin (domain) that its OK to access resources on another server.</p><p>Here’s why this is important; we’re going to have a static HTML page in the Azure Storage account acting as the front-end of the serverless application. There will be JavaScript in that page that executes when users fill out and submit a form, and that client-side code will be connecting to a different endpoint (the function URL) to communicate with the back-end of the application. CORS allows us to define where that traffic is allowed to originate from (in this case, the static website in Azure Storage), and it will tell web browsers used by our clients that its not a security risk to do this.</p><p>So, what we need to do is run the <strong>az functionapp cors add</strong> command as shown below. We’ll need to target the previous resource group and function app resources we created, and also define the allowed origin which will be the primary endpoint URL from the Storage Account from <strong>Step 1</strong>.</p><pre>az functionapp cors add \ <br>    --resource-group &lt;YOUR GROUP NAME&gt; \ <br>    --name &lt;YOUR FUNCTION APP NAME&gt; \ <br>    --allowed-origins &lt;YOUR STATIC WEBSITE URL&gt;</pre><p>Once the CORS configuration has been set you’ll be able to see the change in the platform features section of the function app in the Azure portal, as shown in <strong>Figure 2</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/430/0*tkQy9ys7jzfUcLLa.jpg" /></figure><p><strong>Figure 2.</strong> Reviewing the CORS configuration.</p><p>Again, if you run into any problems doing this from the CLI, you can manually create the <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-function-app-portal">Function App</a> and add the static website primary endpoint URL to the CORS configuration.</p><h3><strong>Step 3. Creating an Azure Function</strong></h3><p>Now that we have a function app, we can create a new function. While the Azure CLI makes it easy to create the function app from the command-line, we need to use other tools to create our functions. One way we could do it is by using the <a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function-azure-cli">Azure Core Tools</a>, but I’m not going to get into that here. Instead, we’ll create the function inside the Azure portal.</p><p>Navigate to your function app and highlight <em>Functions</em>. Click the <strong>New function</strong> button to start the process as shown in <strong>Figure 3</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/570/0*fTbb0B8oqdRloe9V.jpg" /></figure><p><strong>Figure 3.</strong> Locating the new function button.</p><p>Next, we can select a template for our function. Select the <em>HTTP trigger</em> template as shown in <strong>Figure 4</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/0*uSOpIj5RfmudhNZB.jpg" /></figure><p><strong>Figure 4.</strong> Selecting the HTTP trigger template.</p><p>The last step is to name the function and set the authorization level. Change the name of the function to <em>SayHello</em> and set the authorization level to <em>Anonymous</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/932/0*UZeD1hC5bm806SV3.jpg" /></figure><p><strong>Figure 5.</strong> Setting the function name and auth level.</p><p>After the function has been created you’ll see the default code for the HTTP trigger template as shown below in <strong>Figure 6</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2776b34d9323dfb0d3119192d9e7602b/href">https://medium.com/media/2776b34d9323dfb0d3119192d9e7602b/href</a></iframe><p><strong>Figure 6.</strong> Reviewing the Function App Settings.</p><p>This is the exported JavaScript function that will execute when triggered via HTTP. Let’s break it down a bit so we know what&#39;s going on when we call the function.</p><ul><li><strong>Line 1:</strong> You can see the first argument sent to the function is a <em>context</em> object which, among other things, is used for communicating with the Azure Functions runtime. The second argument (<em>req</em>) is the request object that contains the details about what was sent to the function. We’ll be able to use the <em>req</em> object to access the data sent to this function from our web form.</li><li><strong>Line 4:</strong> Here we’re using some conditional logic to make sure the request contains a <em>name</em> key within the query string parameters or request body.</li><li><strong>Line 5:</strong> If a <em>name</em> was provided with the request, we use the <em>context.res</em> object to send a response. In this case, we send back a “hello” message to the caller.</li><li><strong>Line 11:</strong> If a <em>name</em> wasn’t provided, we’ll send back an HTTP 400 error with a message explaining what the problem is.</li></ul><p>While you’re viewing this code in the Azure portal, you’ll see a link at the top of the screen that says <em>Get function URL</em> as shown in <strong>Figure 7</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/809/0*KQLfkBKeAT9Iio6O.jpg" /></figure><p><strong>Figure 7.</strong> Copying the function URL.</p><p>Copy the URL from this screen as we’ll need it for the next step.</p><h3><strong>Step 4. Configuring the HTML Front-end</strong></h3><p>Now we are ready to configure the HTML page for the serverless application like the one shown in <strong>Figure 8</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/811/0*vqON9edLYLULCWIp.jpg" /></figure><p><strong>Figure 8.</strong> The UI for our serverless app.</p><p>This page uses <a href="https://getbootstrap.com/">Bootstrap 4</a> which is an easy to use open source toolkit for developing with HTML, CSS, and JavaScript. Let me point out some of the basics that are going on inside the HTML code for this form that is relevant to the functionality of our serverless application.</p><p>Check out the snippet from <strong>Figure 9</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b4ab2ba0996e88344026d0dc3b78d8b/href">https://medium.com/media/8b4ab2ba0996e88344026d0dc3b78d8b/href</a></iframe><p><strong>Figure 9.</strong> The HTML form for the app.</p><p>Here’s what you need to know:</p><ul><li><strong>Line 4:</strong> There’s an empty <em>output</em> div we can update based on the response from our Azure function. We’ll use this element to provide a success or failure message to the user.</li><li><strong>Line 7:</strong> The input field where the user submits their name. Notice that the <em>id</em> is set to <em>name</em>. We’ll grab the value from this input and send it along with the request to our Azure Function.</li><li><strong>Line 9:</strong> When the user clicks the submit button we’ll post the form to our Azure function.</li></ul><p>Now that you understand what is going on with the HTML code, let me explain a couple of points about the client side javascript that will send the form data to our serverless function.</p><p>Take a look at the code in <strong>Figure 10</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2bf4a4077e5e6634ac29e5e9efc58cea/href">https://medium.com/media/2bf4a4077e5e6634ac29e5e9efc58cea/href</a></iframe><p><strong>Figure 10.</strong> The client-side JavaScript that calls our serverless function.</p><p>This is a vanilla JavaScript function that will be called when the user clicks the <em>Submit</em> button. Here are some important points about the code in <strong>Figure 10</strong>:</p><ul><li><strong>Line 4:</strong> We grab the value of the input field in the HTML form.</li><li><strong>Line 5:</strong> The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a> will be used to facilitate the request/response process. You’ll obviously need to update this line with your own function URL.</li><li><strong>Line 12:</strong> The value for the <em>name</em> input will be sent as part of the body of the POST request.</li><li><strong>Line 15:</strong> fetch() returns a promise containing the response, and that gets passed to another client-side function called <em>processResponse()</em> which will update the UI.</li></ul><p>Still awake? Good :)</p><p>All of this code is included in a single HTML file for the sake of convenience. Grab the <a href="https://gist.githubusercontent.com/mikepfeiffer/1419d7e8798ae07c211909a70b12203c/raw/d0541c9a0523e6651bde73a8c428d6671db6de14/index.html">Index.html</a> page from GitHub. Don’t forget to replace “&lt;YOUR FUNCTION URL GOES HERE&gt;” with the URL of your function that you recorded in <strong>Step 3</strong>.</p><h3><strong>Step 5. Deploying the HTML Front-end</strong></h3><p>Let’s take the index.html file and upload it into our Azure Storage account. Since <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website">static website hosting</a> is already enabled for the storage account, we simply need to upload the file/blob to the <em>$web</em> container.</p><p>This can be done easily in the portal, but here’s how you can do it via the Azure CLI:</p><pre>az storage blob upload-batch \ <br>    --source &lt;YOUR SOURCE FOLDER&gt; \ <br>    --destination \$web \ <br>    --account-name &lt;YOUR STORAGE ACCOUNT NAME&gt;</pre><p>Notice that I had to escape the “$” character with “\” when executing the CLI in bash. Also, note the <strong>— source</strong> flag expects a directory since this command is designed to upload multiple files as a batch process. This makes sense as most sites will have multiple HTML, CSS, JavaScript, and image files that need to be uploaded.</p><h3><strong>Step 6. Testing the Serverless Web Application</strong></h3><p>Finally, its time to test our serverless application. Navigate to the static website primary endpoint URL to view your application. After filling out and submitting the form, you should see a response similar to the one in <strong>Figure 11</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/771/0*D_p_k_4y47o4FOMj.jpg" /></figure><p><strong>Figure 11.</strong> The UI for our serverless app in action.</p><p>Isn’t that awesome?</p><p>You might be wondering how the success message was created on the page. That work is done as part of the response where we call the processResponse() function shown in <strong>Figure 12</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2648444ce850692b0bbf4ca012e3853c/href">https://medium.com/media/2648444ce850692b0bbf4ca012e3853c/href</a></iframe><p><strong>Figure 12.</strong> The processResponse() function.</p><p>What we’re doing with this function is checking the HTTP response code sent back from the Azure function. Regardless of the result, we use processResponse() to update the <em>output</em> element on the page. We’re taking advantage of Bootstrap <a href="https://getbootstrap.com/docs/4.1/components/alerts/">alerts</a> to add some flare.</p><p>Here’s what it would look like if there was a problem:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/772/0*mC8cuk7eBqzh5nkR.jpg" /></figure><p><strong>Figure 13.</strong> The UI for our serverless app when there is an error.</p><p>This is a good example of how we can give feedback to users based on the result of a function invoked over HTTP. Obviously, we could do client-side validation and more error handling on the back-end but I think you get the idea.</p><h3><strong>Where to go from here</strong></h3><p>We’ve only scratched the surface, but I hope this tutorial has given you a little more perspective. Going forward, I’d recommend these resources from Microsoft to learn more about serverless on Azure:</p><ul><li><a href="https://docs.microsoft.com/en-us/learn/paths/create-serverless-applications/">Create Serverless Applications (Microsoft Learn)</a></li><li><a href="https://docs.microsoft.com/en-us/azure/azure-functions/">Azure Functions Documentation</a></li><li><a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-serverless-api">Create a Serverless API using Azure Functions</a></li><li><a href="https://docs.microsoft.com/en-us/azure/functions/tutorial-static-website-serverless-api-with-database">Build a Serverless Web App in Azure</a></li><li><a href="https://serverlesslibrary.net/">Azure Serverless Community Library</a></li></ul><p><em>Originally published at </em><a href="https://mikepfeiffer.io/azure-serverless-101.html"><em>mikepfeiffer.io</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=551e6debbae3" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>