Tuesday, October 31, 2017

Microsoft 70-487: Choose a deployment strategy for an Azure web application

Exam Objectives

Perform an in-place upgrade and VIP swap; configure an upgrade domain; create and configure input and internal endpoints; specify operating system configuration; deploy applications using Azure Web Site


Quick Overview of Training Materials



Perform in-place upgrade and VIP swap


The Microsoft document "How to update a cloud service" covers the upgrade options available.  In addition to in-place upgrades and VIP swap, deleting and redeploying the application is also an option, and in some limited cases is the only appropriate choice.  I think it's worth noting that there are two major offerings in Azure for hosting web applications: Cloud Services and App Services.  Most of the listed topics apply to Cloud Services, while the last (Azure Websites) pretty much covers the App Services side (websites was rolled into App Services).


In-place upgrade


In place upgrades to cloud services are accomplished though the use of upgrade domains.  Upgrade domains are logical groupings of role instances that Azure updates together.  When an application is updated, all the instances in a given upgrade domain are stopped, the new code is deployed, and then the instances are all brought back up.  This kind of "rolling update" minimizes the disruption to the running service. This mechanism goes back to 2009.


VIP Swap and Staged Deployments


A VIP swap upgrade works by first deploying the new version of the app to a "staging" environment, and then swapping the virtual IP addresses of the staging environment with production.  To deploy to the staging environment just select it in the publish configuration:



Information on this staging environment is also available from the portal. Instead of the production style URL, which is <service name>.cloudapp.net, it uses <guid>.cloudapp.net:



Hitting the "Swap" menu option brings up the confirmation screen.  I tried creating an app that would display some interesting metadata about what environment and instance it was on, but it proved to be way more involved than it was worth, so I skipped it.  Sorry.



Azure App Services have a similar notion for swapping deployments using "deployment slots".  The difference is that you can define multiple deployment slots and chose the pair to swap arbitrarily.






Configure an upgrade domain


[Based on the "How to update a cloud service" article and the Azure Service Definition schema]

By default an application can have up to 5 of these groups, but setting an optional attribute on the <ServiceDefinition> element in the service definition file will allow you to set this number as high as 20.


<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureCloudService2" 
                   xmlns="http://schemas.microsoft.com/..." 
                   schemaVersion="2015-04.2.6"
                   upgradeDomainCount="5">
  <WebRole name="WebRole1" 
           vmsize="Small">
    ...
  </WebRole>
</ServiceDefinition>


The blog post by Plankytronixx goes into detail on fault domains and upgrade domains.  It kind of takes the infrastructure angle, but it's a decent quick read none the less.  It shows how new role instances are provisioned into the upgrade domains in a round robin kind of fashion.



Create and configure endpoints


The Enable communication for role instances in azure article goes into full detail on how to create the various endpoints on a cloud service, and configure network traffic rules to control communication flow.  What follows is basically a synopsis...

Endpoints fall into two categories:  input endpoints that are exposed externally, and internal endpoints that communicate only to other Azure roles.  Compared to endpoints in WCF, the configuration of these endpoints is pretty trivial, requiring just a name, protocol, and a port.  Input endpoints can specify both a port and local port (which will map traffic from the external port to a different port local to that instance).  Web roles require at least one input endpoint using http.

Input endpoints can also be specified at the individual role level, in which case they are called an instance input endpoint.  Unlike standard input endpoints, however, instance input endpoints only operate on tcp and udp. Standard input endpoints can use http, https, udp, or tcp.

On internal endpoints the port is optional; when omitted the port is assigned dynamically (from a range if one is provided).  Internal endpoints can communicate over http, tcp, or udp protocols, and there is a limit of five per role.

In addition to creating the endpoints in the configuration file, you can specify network rules that will restrict which roles can talk to each other.  The following ServiceDefinition.csdef file was cobbled together from what I had in the base template with what was included in the article.  It demonstrates defining a external and internal endpoints, and restricting traffic to the worker role.


<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureCloudService2" 
                   xmlns="http://schemas.microsoft.com/..." 
                   schemaVersion="2015-04.2.6"
                   upgradeDomainCount="5">
  <WebRole name="WebRole1" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" 
                   endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
      <Setting name="APPINSIGHTS_INSTRUMENTATIONKEY" />
    </ConfigurationSettings>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
  </WebRole>

  <!-- Add a worker role-->
  <WorkerRole name="WorkerRole1">
    <Endpoints>
      <InternalEndpoint name="InternalTCP2" protocol="tcp" />
    </Endpoints>
  </WorkerRole>

  <!-- Add a traffic rule only allowing WebRole1 to talk to worker -->
  <NetworkTrafficRules>
    <OnlyAllowTrafficTo>
      <Destinations>
        <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
      </Destinations>
      <AllowAllTraffic/>
      <WhenSource matches="AnyRule">
        <FromRole roleName="WebRole1"/>
      </WhenSource>
    </OnlyAllowTrafficTo>
  </NetworkTrafficRules>
  
</ServiceDefinition>



Specify Operating System Config


The operating system of the underlying role instance can be controlled via the ServiceConfiguration file.  The ServiceConfiguration element has two attributes, osFamily and osVersion that can be used to specify the family and version of the operating system respectively.  OsFamily uses a number from 1 to (currently) 5 to specify the general OS product:

  1. Windows Server 2008 (retired)
  2. Windows Server 2008 R2 SP1
  3. Windows Server 2012
  4. Windows Server 2012 R2
  5. Windows Server 2016

The various os families come with different versions of the .NET framework installed.  All the current (2-5) families include at least 4.0 through 4.5.2, while family 2 goes back to 3.5, and family 5 includes 4.6.x.

The OsVersion attribute can be used to specify a specific version of the os family, or it can be specified as "*" to just use the most recent.  Since Microsoft only supports the last few versions, it is probably generally wise to just use asterisk and use the latest version.


<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="AzureCloudService2" 
                      xmlns="http://schemas.microsoft.com/ServiceHosting..." 
                      osFamily="4" osVersion="*" schemaVersion="2015-04.2.6">
  <Role name="WebRole1">
    <Instances count="2" />
    <ConfigurationSettings>
      <Setting name="..."  value="..." />
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>


The OS family in use on a service also has implications with regard to which Azure SDK versions will work.

  • Family 2 - SDK 1.3+
  • Family 3 - SDK 1.8+
  • Family 4 - SDK 2.1+
  • Family 5 - SDK 2.9.5.1+



Deploy using Azure Web Sites


"Azure Web Sites" is now part of "App Services", an Azure product that offers a variety of templates for web and mobile applications.  The service that was Azure Web Sites is now the "Web App" service:



An old post by Scott Hanselman on Azure Websites gives a flavor of what they were like before they were rolled into App Service, and many of the concepts still apply.  The same can be said of the PluralSight course on Azure Web Sites, which really helped me map out which concepts were important as far as deployment goes.

Deploy with FTP 


The old school stand-by deployment method, FTP is available to move files into and out of Azure Web Sites.  The big caveat with this method is that it requires you to set up a credential, which has it's very own menu item in the portal:



You'll also need the ftp host address (it isn't just the website address with "ftp" instead of "http").  This is located under the "Properties" menu, which is grouped in with "Settings":



Taken together, just plug these into an ftp client and you'll be able to explore, download, and upload files:



The documentation on ftp deployments notes that you do give up certain automation functionality with this method.  Unlike the other deployments, you don't get Nuget package restore, compilation of .NET binaries, or web.config generation.


Web Deploy


Web Deploy can be used from Visual Studio to deploy a website to Azure.  The first step is to create a publish profile.  This can be done through Visual Studio directly, connecting to your Azure account to download the relevant settings, or the publish settings file can be downloaded from the portal and imported into a publish profile.  In either case, the first step is to right click the role project and select "Publish":



To create the publish profile directly from Visual Studio, select the "Microsoft Azure App Service" target.  You will be prompted to select a subscription and the target application:



This will import the necessary settings to deploy the application to the cloud:



The other way to do this is to download the "Publish Profile" from the portal.  Of course, what you are downloading from the portal isn't a profile proper, instead it's a .publishSettings file that can be used to import the publish profiles into the project.  So really the button is arguably mislabeled... quibbles:



Once you have the .publishSettings file, right click the role, "Publish", "Import" and the rest is pretty much standard Publish Profile set up:




Publishing from Source Control


Azure Web Sites also has to ability to integrate with source control and automatically redeploy when changes are committed.  This can be done either by pushing to the repo build into the web app, or by connecting the application to another repo hosting service (including Visual Studio Team Services).  If you are set up with separate deployment slots, each slot can be configured independently to use different deployment options (for example, staging may be set to "Local Git" and productions to "Visual Studio Team Services"...).

Using the "Local Git" option entails a couple of steps.  As with ftp, you must create a deployment credential.  Also like ftp, you need to go to the "Properties" page to get the git url.  Set this as the upstream remote, and whenever you push a change it will trigger a build and deploy:



Visual Studio Team Services requires you to create a "link" through the Azure portal before you'll be able to set it up for deployments.  This is explained fully in this article: Setting up a VSTS account so it can deploy to a Web App.  There is a similar article for connecting to GitHub and BitBucket.  GitHub and BitBucket will both require OAuth permissions before Azure will be able to connect with them, but once that is done all three are very similar:



Integrating with these external repositories still gives you essentially the same capability as the local Git repo.  Any time changes are pushed to the remote, Azure gets a notification, pulls the changes, and builds and deploys the application.  

No comments:

Post a Comment