{"id":2115,"date":"2017-01-17T12:00:00","date_gmt":"2017-01-17T12:00:00","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2017\/01\/17\/the-deploy-to-azure-button\/"},"modified":"2020-03-15T06:03:37","modified_gmt":"2020-03-15T13:03:37","slug":"the-deploy-to-azure-button","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/the-deploy-to-azure-button\/","title":{"rendered":"The Deploy to Azure Button"},"content":{"rendered":"<p>The \u2018Deploy to Azure\u2019 button enables quick and easy deployment of your open source projects to Microsoft Azure. We\u2019ll walk through how we added a \u2018Deploy to Azure\u2019 button to the <a href=\"http:\/\/rauchg.com\/slackin\/\">slackin<\/a> project, and show how you can do the same.<\/p>\n<h1 id=\"what-is-slackin\">What is slackin?<\/h2>\n<p>https:\/\/devblogs.microsoft.com\/cse\/wp-admin\/revision.php?revision=11045<\/p>\n<p><a href=\"http:\/\/rauchg.com\/slackin\/\">slackin<\/a> is an open source web application used by projects such as <a href=\"http:\/\/atom-slack.herokuapp.com\/\">GitHub Atom<\/a>, <a href=\"http:\/\/socket.io\/slack\/\">Socket.IO<\/a>, and <a href=\"https:\/\/vscodevim-slackin.azurewebsites.net\/\">VsCodeVim<\/a>. One of the pain points of managing a public <a href=\"https:\/\/slack.com\">Slack<\/a> team is inviting new members. slackin makes it easy for people to find and join public Slack communities by providing a self-service landing page for new users where they can fill in their emails and receive an invite to a Slack team.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2017\/01\/slackin_invite22161415-300x270-1.png\" alt=\"Image slackin invite22161415 300 215 270\" width=\"300\" height=\"270\" class=\"aligncenter size-full wp-image-11044\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>To use slackin, project owners must deploy and configure their own instance of the slackin web application.<\/p>\n<h1 id=\"the-problem\">The Problem<\/h2>\n<p>Deploying an application is normally a fairly involved workflow:<\/p>\n<ol>\n<li>Identify what resources are required. Does the application require a virtual machine? a load balancer? storage? a database?<\/li>\n<li>Provision resources. For every resource identified in the above step, allocate and create the resource on the cloud provider (e.g. Microsoft Azure).<\/li>\n<li>Build the application. In addition to compiling the source code, this step includes identifying and installing the necessary build tools.<\/li>\n<li>Deploy the build assets to the newly provisioned resources.<\/li>\n<li>Properly configure the newly deployed application.<\/li>\n<\/ol>\n<p>These steps require a level of understanding that should not be required of users and customers.<\/p>\n<h1 id=\"overview-of-the-solution\">Overview of the Solution<\/h2>\n<p>Adding a <a href=\"https:\/\/azure.microsoft.com\/en-us\/blog\/deploy-to-azure-button-for-azure-websites-2\/\">\u2018Deploy to Azure\u2019 button<\/a> to a project\u2019s readme provides users with a simple mechanism to easily and quickly deploy your application to Microsoft Azure.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2017\/01\/deploybutton.png\" alt=\"Image deploybutton\" width=\"161\" height=\"34\" class=\"aligncenter size-full wp-image-11042\" \/><\/p>\n<p>The animation below shows the experience when deploying slackin through the button, which hides much of the deployment complexity from the user. Behind the scenes, the tool is:<\/p>\n<ol>\n<li>Prompting the user for a series of configurations that will be used to configure slackin<\/li>\n<li>Provisioning a Web App on Microsoft Azure<\/li>\n<li>Retrieving the slackin source code from GitHub and compiling\/building the project<\/li>\n<li>Deploying the build assets to the Azure Web App<\/li>\n<li>Configuring the slackin instance with the settings defined earlier by the user (e.g. Slack team name, API name, hostname, etc.)<\/li>\n<\/ol>\n<p><!-- TODO - missing image\n[caption id=\"attachment_3445\" align=\"alignnone\" width=\"990\"]<img decoding=\"async\" class=\"wp-image-3445 size-full\" src=\"\/developerblog\/wp-content\/uploads\/deploy-to-azure.gif\" alt=\"\" width=\"990\" height=\"720\" \/> Deploying slackin through the \"Deploy to Azure\" button[\/caption]\n--><\/p>\n<p>For your users to leverage this easy deployment mechanism, there are a couple of things a project owner will need to prepare. The following sections will use slackin as a working example and outline the changes necessary to support the \u2018Deploy to Azure\u2019 button.<\/p>\n<h2 id=\"define-the-cloud-assets\">Define the Cloud Assets<\/h2>\n<p>slackin relied on certain tools such as <code class=\"highlighter-rouge\">make<\/code> that limited its execution to Linux-based environments and therefore required a Linux virtual machine. In order to provide users with the ability to deploy slackin to a free tier of Microsoft Azure, the build chain was updated to use <code class=\"highlighter-rouge\">gulp<\/code> instead of <code class=\"highlighter-rouge\">make<\/code>. Not only did this change allow slackin to be deployable on both Windows and Linux virtual machines, but we could also leverage the cheaper\/free <a href=\"https:\/\/azure.microsoft.com\/services\/app-service\/web\/\">Azure Web Apps<\/a>, a Platform as a Service (PaaS) offering on Azure.<\/p>\n<p>For slackin, the required cloud assets were:<\/p>\n<ul>\n<li>Azure Web Application<\/li>\n<\/ul>\n<h2 id=\"azure-resource-manager-template\">Azure Resource Manager Template<\/h2>\n<p>Once you\u2019ve determined what cloud resources are required, create an <a href=\"https:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/resource-group-authoring-templates\/\">Azure Resource Manager (ARM) template<\/a>. We won\u2019t go into detail about authoring ARM templates, but once constructed, save it as <code class=\"highlighter-rouge\">azuredeploy.json<\/code> into the root of your project repository.<\/p>\n<p>The <a href=\"https:\/\/github.com\/rauchg\/slackin\/blob\/master\/azuredeploy.json\">ARM template used for slackin<\/a> is available on GitHub, and there are two sections to highlight:<\/p>\n<h3 id=\"parameters\">Parameters<\/h3>\n<p>The <a href=\"https:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/resource-group-authoring-templates\/#parameters\">parameters<\/a> section of the ARM template defines the set of configurations that the user needs to input. These configurations will appear on the first page of the deployment wizard.<\/p>\n<pre class=\"lang:default decode:true \">    \"parameters\": {\r\n        ...\r\n        \"slackTeamId\" : {\r\n          \"type\": \"string\",\r\n          \"metadata\": {\r\n            \"description\": \"Slack Team ID. (e.g. https:\/\/{this}.slack.com)\"\r\n          }\r\n        },\r\n        \"slackApiToken\" : {\r\n          \"type\": \"string\",\r\n          \"metadata\": {\r\n            \"description\": \"Slack API token (find it on https:\/\/api.slack.com\/web)\"\r\n          }\r\n        },\r\n        \"slackinRelease\" : {\r\n          \"type\": \"string\",\r\n          \"allowedValues\": [\r\n            \"stable\",\r\n            \"latest\"\r\n          ],\r\n          \"defaultValue\": \"stable\",\r\n          \"metadata\": {\r\n            \"description\": \"Slackin Release to Deploy (stable\/latest)\"\r\n          }\r\n        }\r\n        ...\r\n      },<\/pre>\n<p>&nbsp;<\/p>\n<h3 id=\"resources\">Resources<\/h3>\n<p><a href=\"https:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/resource-group-authoring-templates\/#resources\">Resources<\/a> define the Azure resources to be deployed and their desired state when deployed. For instance, the definition used in slackin will:\n1. Deploy a free tier (F1 SKU) web application to the Azure Region <code class=\"highlighter-rouge\">siteLocation<\/code> defined by the user\n2. Configure the web application to enable WebSockets and configure the appropriate environment variables (i.e. SLACK_SUBDOMAIN, etc.)<\/p>\n<pre class=\"lang:default decode:true \">     \"resources\": [\r\n        {\r\n          \"apiVersion\": \"2015-08-01\",\r\n          \"name\": \"[parameters('hostingPlanName')]\",\r\n          \"type\": \"Microsoft.Web\/serverfarms\",\r\n          \"location\": \"[parameters('siteLocation')]\",\r\n          \"properties\": {\r\n          },\r\n          \"sku\": {\r\n            \"name\": \"F1\"\r\n          }\r\n        },\r\n        {\r\n          \"apiVersion\": \"2015-08-01\",\r\n          \"name\": \"[parameters('siteName')]\",\r\n          \"type\": \"Microsoft.Web\/sites\",\r\n          \"location\": \"[parameters('siteLocation')]\",\r\n          \"dependsOn\": [\r\n            \"[resourceId('Microsoft.Web\/serverfarms', parameters('hostingPlanName'))]\"\r\n          ],\r\n          \"properties\": {\r\n            \"serverFarmId\": \"[parameters('hostingPlanName')]\"\r\n          },\r\n          \"resources\": [\r\n            {\r\n              \"apiVersion\": \"2015-08-01\",\r\n              \"name\": \"web\",\r\n              \"type\": \"config\",\r\n              \"dependsOn\": [\r\n                \"[resourceId('Microsoft.Web\/Sites', parameters('siteName'))]\"\r\n              ],\r\n              \"properties\": {\r\n                \"siteProperties\": {\r\n                  \"webSocketsEnabled\": true\r\n                }\r\n              }\r\n            },\r\n            {\r\n              \"apiVersion\": \"2015-08-01\",\r\n              \"name\": \"appsettings\",\r\n              \"type\": \"config\",\r\n              \"dependsOn\": [\r\n                \"[resourceId('Microsoft.Web\/Sites', parameters('siteName'))]\"\r\n              ],\r\n              \"properties\": {\r\n                \"SLACK_SUBDOMAIN\": \"[parameters('slackTeamId')]\",\r\n                \"SLACK_API_TOKEN\": \"[parameters('slackApiToken')]\",\r\n                \"SLACKIN_RELEASE\": \"[parameters('slackinRelease')]\",\r\n                \"WEBSITE_NPM_DEFAULT_VERSION\": \"3.3.12\",\r\n                \"WEBSITE_NODE_DEFAULT_VERSION\": \"5.1.1\",\r\n                \"command\": \"bash scripts\/azuredeploy.sh\"\r\n              }\r\n            },\r\n            {\r\n              \"apiVersion\": \"2015-08-01\",\r\n              \"name\": \"web\",\r\n              \"type\": \"sourcecontrols\",\r\n              \"dependsOn\": [\r\n                \"[resourceId('Microsoft.Web\/Sites', parameters('siteName'))]\",\r\n                \"[concat('Microsoft.Web\/Sites\/', parameters('siteName'), '\/config\/web')]\"\r\n              ],\r\n              \"properties\": {\r\n                \"RepoUrl\": \"[parameters('repoURL')]\",\r\n                \"branch\": \"[parameters('branch')]\",\r\n                \"IsManualIntegration\": true\r\n              }\r\n            }\r\n          ]\r\n        }\r\n      ],<\/pre>\n<p>&nbsp;<\/p>\n<h2 id=\"add-the-button\">Add the Button<\/h2>\n<p>Lastly, with the ARM script defined, add the following line to your project\u2019s readme to add the \u2018Deploy to Azure\u2019 button:<\/p>\n<p><span class=\"lang:default decode:true crayon-inline \"><a href=\"https:\/\/azuredeploy.net\/\"> <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2017\/01\/deploybutton.png\" alt=\"Image deploybutton\" width=\"161\" height=\"34\" class=\"aligncenter size-full wp-image-11042\" \/><\/a><\/span><\/p>\n<p>When a user clicks on the button, an HTTP referrer header is sent to azuredeploy.net denoting the URL and branch of the Git repository to deploy. By default, it is the master branch. However, you can specify an alternative repository and branch like so:<\/p>\n<pre class=\"lang:default decode:true\"><a href=\"https:\/\/azuredeploy.net\/?repository=https:\/\/github.com\/[USERNAME]\/[REPOSITORY-NAME]\/tree\/[BRANCH-NAME]\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n    <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2017\/01\/deploybutton.png\" alt=\"Image deploybutton\" width=\"161\" height=\"34\" class=\"aligncenter size-full wp-image-11042\" \/>\r\n<\/a><\/pre>\n<h1 id=\"opportunities-for-reuse\">Opportunities for Reuse<\/h2>\n<p>With a couple of lines of code, we were able to add a \u2018Deploy to Azure\u2019 button to the slackin project giving users a simple and easy way to deploy a slackin instance to their cloud.<\/p>\n<p>Using this example, you can add a \u2018Deploy to Azure\u2019 button to your project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Deploy your project to Microsoft Azure with a single click of a button. We&#8217;ll walk through how we simplified deployment of slackin through the &#8216;Deploy to Azure&#8217; button, and show how you can do the same to enable easy deployment of your project to Azure.<\/p>\n","protected":false},"author":21365,"featured_media":11043,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[10,16],"tags":[60,91,97,329,330],"class_list":["post-2115","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-app-services","category-devops","tag-azure","tag-azure-resource-manager-arm","tag-azure-web-apps","tag-slack","tag-slackin"],"acf":[],"blog_post_summary":"<p>Deploy your project to Microsoft Azure with a single click of a button. We&#8217;ll walk through how we simplified deployment of slackin through the &#8216;Deploy to Azure&#8217; button, and show how you can do the same to enable easy deployment of your project to Azure.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21365"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2115"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2115\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media\/11043"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}