{"id":61679,"date":"2021-05-13T10:00:50","date_gmt":"2021-05-13T18:00:50","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/devops\/?p=61679"},"modified":"2021-05-11T04:40:03","modified_gmt":"2021-05-11T12:40:03","slug":"on-prem-to-the-cloud-lets-rub-some-devops-on-it-ep-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/on-prem-to-the-cloud-lets-rub-some-devops-on-it-ep-3\/","title":{"rendered":"On Prem To the Cloud: Let&#8217;s Rub Some DevOps On It! (Ep 3)"},"content":{"rendered":"<p>In episode 2 of this series, <a href=\"https:\/\/twitter.com\/jaydestro\">Jay<\/a> helped Abel <a href=\"https:\/\/devblogs.microsoft.com\/devops\/on-prem-to-the-cloud-lift-and-shift-ep-2?WT.mc_id=devops-9478-dabrady\">migrate the Mercury Health application environment into Azure<\/a>. So we&#8217;re in the cloud! But what about future changes? How do we get them out to customers? The answer is DevOps.<\/p>\n<p><iframe title=\"On Prem To The Cloud: Rub Some DevOps On It (episode 3)\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/KEYOsMWA5ak?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<h2>Rubbing Some DevOps on a &#8220;Legacy&#8221; App<\/h2>\n<p>It&#8217;s not unusual for older products to just stay where they are. Because they&#8217;re built on &#8220;legacy technology&#8221;, and aren&#8217;t sporting shiny new cloud-native architecture, it can seem like they&#8217;re not built for things like Continuous Integration or Continuous Deployment. But that doesn&#8217;t have to be the case!<\/p>\n<p>So rather than pat ourselves on the back and think, &#8220;job well done&#8221;, it&#8217;s time for the team to start applying some DevOps practices to the application we&#8217;ve now got in the cloud.<\/p>\n<p>Importantly, configuring CI\/CD this early in the migration piece will help us in the long run. The final cloud-native version of our application is likely to look very different from what we have now, and our CI\/CD pipeline will as well. But if we have working pipeline, any changes we make to our application architecture will only require tweaks to something we know already works. We&#8217;ll be iterating on the pipeline as we modernize rather than trying to create it whole at the end.<\/p>\n<p>It&#8217;s a little like the legend of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Milo_of_Croton\">Milo of Croton<\/a> who was able to lift a bull because he started in childhood lifting a newborn calf every day until it grew to maturity!<\/p>\n<h2>Building our Application<\/h2>\n<p>Let&#8217;s split the pipeline into CI and CD parts &#8211; continuous integration, and continuous deployment.<\/p>\n<p>In our continuous integration stage, we want to build our application, run our tests, and package it up ready for deployment. Any CI\/CD system is capable of doing this, but I like <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/get-started\/what-is-azure-pipelines?WT.mc_id=devops-9478-dabrady\">Azure Pipelines<\/a> or <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a>. I&#8217;m going to build similar pipelines in both tools, just to show how it can be done.<\/p>\n<p>Let&#8217;s start with Azure Pipelines.<\/p>\n<p>In Azure Pipelines, this is really easy! We can start by creating a new YAML pipeline in the Azure DevOps portal and tell it where the code lives. Azure Pipelines is capable of pulling code from nearly anywhere &#8211; Azure Repos, GitHub, Bitbucket, or any accessible Git or Subversion repository.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/where-code.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/where-code.png\" alt=\"Azure Pipelines can get your code from nearly anywhere\" width=\"983\" height=\"547\" class=\"alignnone size-full wp-image-61681\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/where-code.png 983w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/where-code-300x167.png 300w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/where-code-768x427.png 768w\" sizes=\"(max-width: 983px) 100vw, 983px\" \/><\/a><\/p>\n<p>Next, the code is analysed and a few templates are suggested. Because this application has plenty of C#, the suggested templates include ASP.NET, ASP.NET Core, and even Xamarin for iOS. If we choose ASP.NET, we&#8217;ll get most of the way to a successful build.<\/p>\n<p>One important step for a multi-stage YAML definition, is to add the <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/tasks\/utility\/publish-pipeline-artifact?WT.mc_id=devops-9478-dabrady\">Publish Pipeline Artifact<\/a> task. This allows us to upload the output of our build as well as the database DACPAC to the pipeline. In a future stage (or stages) we can download these artifacts for deployment.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/artifact-upload.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/artifact-upload.png\" alt=\"Upoading our build artifact\" width=\"321\" height=\"92\" class=\"alignnone size-full wp-image-61682\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/artifact-upload.png 321w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/artifact-upload-300x86.png 300w\" sizes=\"(max-width: 321px) 100vw, 321px\" \/><\/a><\/p>\n<h2>Deploying our Application<\/h2>\n<p>One great feature of Azure Pipelines is Environments. You can think of these as logical locations where you deploy your software.<\/p>\n<p>Each environment has a name, and can also contain references to virtual machines or Azure Kubernetes Service resources. In the pipeline, you can reference an environment by name, or even a specifically resource or set of resources.<\/p>\n<p>In our case, we&#8217;re using virtual machines (for the moment), so we can add those resources to environments representing our test and production servers. When we do that, we&#8217;re given a PowerShell script we can use to install an agent on those virtual machines.<\/p>\n<p>The best part about this feature is when we run a <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/pipelines\/process\/deployment-jobs?WT.mc_id=devops-9478-dabrady\">deployment job<\/a> that refers to our virtual machine resource, the deployment happens <em>on<\/em> that virtual machine!<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/new-environment.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/new-environment.png\" alt=\"Environments in Azure Pipelines\" width=\"949\" height=\"482\" class=\"alignnone size-full wp-image-61683\" srcset=\"https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/new-environment.png 949w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/new-environment-300x152.png 300w, https:\/\/devblogs.microsoft.com\/devops\/wp-content\/uploads\/sites\/6\/2021\/05\/new-environment-768x390.png 768w\" sizes=\"(max-width: 949px) 100vw, 949px\" \/><\/a><\/p>\n<p>We have two artifacts we need to deploy. The SQL DACPAC file can be deployed really easily with the <a href=\"https:\/\/github.com\/Microsoft\/azure-pipelines-tasks\/tree\/master\/Tasks\/SqlDacpacDeploymentOnMachineGroupV0\">&#8220;Deploy SQL Dacpac Deployment Group&#8221; task<\/a>, and the web app can be deployed to IIS with the <a href=\"https:\/\/github.com\/microsoft\/azure-pipelines-tasks\/tree\/master\/Tasks\/IISWebAppDeploymentOnMachineGroupV0\">&#8220;IIS Web Application Deployment&#8221;<\/a> task.<\/p>\n<h2>What about GitHub Actions?<\/h2>\n<p>The great news is you can do all of this in a very similar way with <a href=\"https:\/\/github.com\/features\/actions\">GitHub Actions<\/a> if you prefer!<\/p>\n<p>While the YAML syntax looks a little different, the concepts are very similar.<\/p>\n<p>Two major differences (at time of writing) are:<\/p>\n<ol>\n<li>You&#8217;ll need to use <a href=\"https:\/\/docs.github.com\/en\/actions\/hosting-your-own-runners\/adding-self-hosted-runners\">self-hosted runners<\/a> on the VMs you want to deploy to. In practice, they work the same way as VM resources in Environments in Pipelines, but they&#8217;re not treated as deployment targets &#8211; rather just agents that actions are run on.<\/li>\n<li>The out-of-the-box Azure Pipelines steps for IIS and DACPAC deployment aren&#8217;t available as Actions. You&#8217;ll either need to find replacement Actions, or just use the command line.<\/li>\n<\/ol>\n<h2>Summary<\/h2>\n<p>Now we have an end-to-end pipeline that will build our application and deploy it to a virtual machine in the cloud!<\/p>\n<p>This is a huge step forward. Now, our developers can focus on writing code, and each push or merge to our main branch will trigger a pipeline that takes that code all the way to production.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In episode 2 of this series, Jay helped Abel migrate the Mercury Health application environment into Azure. So we&#8217;re in the cloud! But what about future changes? How do we get them out to customers? The answer is DevOps!<\/p>\n","protected":false},"author":39350,"featured_media":61680,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[224,1],"tags":[],"class_list":["post-61679","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-devops"],"acf":[],"blog_post_summary":"<p>In episode 2 of this series, Jay helped Abel migrate the Mercury Health application environment into Azure. So we&#8217;re in the cloud! But what about future changes? How do we get them out to customers? The answer is DevOps!<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/61679","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/39350"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=61679"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/61679\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/61680"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=61679"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=61679"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=61679"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}