Deploying Single Page app from appveyor to azure - azure

I'm trying to figure out how to continuously deploy a single page application from appveyor to an azure website. I'm in a bit of a bind because I don't have access to the azure directly, so I'm trying to figure out as many details before contacting the admin, but the appveyor/azure documentation is leaving me with some questions.
My Goals:
Deploy a static site after it's built or trigger azure to do a deployment after a successful build. The app is written in typescript with angular and a bunch of other dependencies that get compiled and bundled into a static site.
I do not want the end user to ever know a deployment is taking place, so any incremental copying to a live environment is out.
I do not want to check in derived files or builds into the repo.
I currently have a build system that bundles the static site it in a zip archive. So my questions are:
Will using the WebDeploy provider meet my goals? Will there be any downtime during deployments if I deploy the zip archive as an artifact?
Is there another approach that would work better?
Is there a way to do this with azure automated deployments? For example, trigger azure to deploy after a successful build. If so, can kudu handle cloning a private submodule as part of the deployment process. I saw that they have submodule support, but I couldn't figure out from the docs if there would be any authentication issues with private submodules.
FYI, the build system is 100% NodeJS driven and independent of the windows ecosystem.

AppVeyor will will automatically deploy to an Azure website. Use the website below to setup your deployment.
http://www.appveyor.com/docs/deployment/web-deploy

Users are going to notice the change if the static files are not cached in their browsers or if they do a hard reload. Regardless of the implementation method, It is advisable to use a CDN (content delivery network). Connect the CDN endpoints to your app service and have the DNS point to the CDN instead of app service. The CDN will serve the static files to the end user instead of the app service itself. The CDN caches the last deployed files and continues serving them to end user until you purge them. Hence, you can keep deploying to your app service and the end user doesn't get affected by your deployments at all since they are accessing your site via CDN instead of app service. Once you have a stable deployment, you can purge your CDN and the latest code will be cached to the CDN again from your app service.
To answer your question about deploying the code, Regardless of the CI/CD system you use, FTP deployment from azure CLI can be one of the methods. Click here for details. However, WebDeploy is the most standard methods of all when you deploy to an app service.

Related

Azure App Service Restart required after uploading new contents to FTP

I have some app services and I update the web sites content by uploading the data via FTPS.
Occasionally, after I upload new content, the sites don't display it at all or partially until the app service is restarted.
Is this normal behavior?
What can be done to avoid restarting or monitoring the site and automatically restarting the app service if the site does not appear properly after updating the content?
Thanks
Just to highlight, based on your application framework - Unlike Git-based deployments and Zip deployment, FTP deployment doesn't support build automation, such as: dependency restores (such as NuGet, NPM, PIP, and Composer automations), compilation of .NET binaries, generation of web.config (here is a Node.js example).
You may generate these necessary files manually on your local machine, and then deploy them together with your app.
Additionally, App Service deploys files to the wwwroot folder. It never directly restarts your app.
You may verify if the deployment files are in root folder. A deployment issue is an issue that causes the wrong set of files to get deployed to your site folder (typically d:\home\site\wwwroot). Deployment-vs-runtime-issues

Should I stop an Azure App Service during an update?

I am updating my Azure App Service from Azure DevOps. Currently, my release is like this:
Stop the App Service,
Update the App Service, and
Start the App Service.
My question is whether it reasonable to stop the App Service during the update? When I select a release template from Azure DevOps for Azure App Service, there are't any stop/start steps, only the update step. So I am wondering if the stop/start is even needed?
What we have done mostly is:
Stop staging slot
Deploy to slot
Start slot
Swap staging to production
Stop staging slot
Martin's suggestion on Take app offline is also a good one!
We prefer to deploy to slots and then swap so we incur minimal impact to production and can also rollback easily.
Stopping/taking app offline can prevent file locking issues.
It probably depends on your app. If you don't have any issues when you just update your app (such as the a file is in use issue) you can consider to use the Take App Offline flag which will place an app_offline.htm file in the root directory of the App Service during the update (then it will be removed). This way user will recognize that something is happening with the app.
However, I often ended up doing the same like you: Stop, Update, Start 😉
There are (5) options for safe-deployment (atomic updates) to Azure Web Apps. Here is my preferred order ranked by priority and feature richness:
Run-from-Package + ZipDeploy (makes site read-only)
ZipDeploy (using kudu REST api - automatically takes site offline)
Azure CLI (az webapp)
msdeploy (-enableRule:AppOffline, or stop/start site to enforce atomicity)
FTP (using publish profile, make sure to upload appoffline.htm)
There are numerous other deployment options like cloud sync, github continuous, local git, etc - but they are all built upon Kudu APIs (as is Azure CLI).
Note: If you're using Azure DevOps - it's supports nearly all these options - leverage the Azure App Service Deploy task
Agree with both Martin and juunas. If you want to deploy without impacting users then you need to use the slot swap approach. juunas brings up the great point of easily rolling back too. Our approach includes another slot we call "hotfix". This adds a few benefits:
Having an environment with production configs so that you can optionally do additional testing before actually doing the swap.
Roll back in prod even when devs have already deployed into a staging environment.
Allows you to test bugs in the current and previous versions of the code. Helpful when someone says "well it worked before this deployment"...
This is what it looks like.

How to update a folder in an Azure AppService upon Checkin into a VSO TFS repository

I have a website hosted as an azure web app. It's an asp.net website that's in a vs solution. On folder of that website is my products documentation, all of it as static resources (html and images). These static resources are located in a folder in another vs solution (this is the actual products solution). Both solutions are TFS based in VSO.
As of now, i have a webjob running in the context of the website that is basically doing a "tfs get" on the documentation folder and placing it's contents into the documentation folder on the website. This is working, however, the vms the website is running on do change quite frequently and the mechanism to create a workspace is bound to the machine, not to the disk drive. Thus, i cannot get only the changes but i must always get all the content which right now takes about 20 minutes and creates unnecessary load on the website. (This is why i'm only running this webjob once a week.)
Now i'm looking for a better way to do this. I would like to only get the files that have changed, making this a lot faster and let cpu/drive costly.
I did not find a way to create a workspace on the webserver that isn't vanishing each time the webservers vm changes. (if it was possible to somehow attach the workspace to the drive instead of to the machine name, that would solve the problem.)
i was also looking at my continues build definition that i have running for the products solution. as part of that, i think it's possibly to create a deployment where the documentation folder is copied to the app services's documentation folder. This way i could get rid of the "special" webjob, but i'd still copy all the docs files each time. (also, the build agent for that is running on premises, so i'd also have to copy those files from premises up to the cloud when they're actually already there inside vso.). So basically, i don't think this option is a lot of use for my case.
Obviously if i moved the static docs resources from the products solution to the websites solution, i could simply use the automatic deployment that is available for website projects from vso to azure web app. Unfortunately, for various other reasons (one of which being, the static resources are partially created automatically from the .cs sources in the products solution) i simply cannot move the docs folder from the products solution to the websites solution.
So does anybody have a suggestion for a method where i could update the documentation folder in the web app based on changes in the corresponding VSO folder?
You can upload the updated files to Azure app service by using Kudu API.
Simple steps:
Create a Continuous Integration build
Check Allow Scripts to Access OAuth Token option in Options tab
Add PowerShell step/task to check the changes with REST API. (Refer to Calling VSTS APIs with PowerShell)
Add Azure PowerShell step/task to upload files to app service by using kudu api. (Refer to Remove files and folders on Azure before a new deploy from VSTS)
Here is what i ended up doing:
Created a ServiceHook in VSO that is wired to "Web Hooks". The hook is called upon each Check-In and filtered based on the directory i want. (All of this can be done using the existing functionality in VSO.)
The hook calls an Azure "functionapp" (which is easy to do, because functionapps have a "HttpTrigger" mechanism which fits in nicely here.)
The hook passes the id of the checkins ChangeSet to the function app.
The FunctionApp puts that id into an Azure (Storage) Queue.
This triggers an azure webjob which listens on that queue. That webjob uses the ChangeSet-Id to get the changes from VSO and acts on the changetype for each change. (e.g.: Downloads or deletes a file.)

patching website on azure webroles

Sometimes in our website which is deployed on Azure web roles, issue comes related to small bugs in javascript and HTML. We go to all instances of webroles and fix these JS and HTML file on machines.
But I was looking into some automated way of doing this, downloading the files to patch from some central location and replace the files in all azure web roles. I am using ASP .net MVC for website.
It is possible to redeploy the website with the patch in the package but we don't want to wait for long deployment time. Please let me know if it is possible via some internal WEB API which replaces the content on all azure web roles.
There are 2 ways to deploy a new webrole:
redeploy
inplace update
The first one is the slowest, meaning new VM's are booted.
With inplace upgrade (https://azure.microsoft.com/en-us/documentation/articles/cloud-services-update-azure-service/)
The new application package is mounted on a new drive (usually F: instead of E:) and the IIS website is swapped to the new drive.
You can try this by going to the old portal and upload a new application package. In just a few seconds/minutes the update is done.
After digging many things on stackoverflow, I crafted my own solution which is creating a topic and subscribing to the topic in code when website starts. When I want to patch the web app then I send a message to Topic to start patching then each machine in the web roles will get notification from topic and start patching themselves. Patching itself is very easy, which is going to a web storage and downloading files from there and replacing files in approot.
When azure maintenance happens this patching may go away, so for this situation I made patching work started at start up of website too.
Cloud service deployment packages tend to be slow since they are basically a recipe on how to build and configure your deployment. The deployment not only puts the recipe out in Azure (so it can be used again if it needs to move your machine), but also follows the recipe to build out a VM for your Cloud Service (WebRoles/WorkerRoles are platform as a service so you don't have to worry about the OS and infrastructure level like you would if you were using the Virtual Machine Azure product but they do still run in VMs on physical hardware).
What you are looking to do is something that will update the recipe (your cloud service package) and your deployment after it is out and running already ... there is no simple way to do that in Cloud Services.
However, yes you could create a startup script that could pull the site files from blob storage or some other centralized location - this would compare to how applications (fiddler for example) look for updates then know how to update and replace themselves. For that sort of feature you will likely need to run code as an elevated user - one nice thing about startup scripts are they can run as an elevated user - so they can do about anything you need done on a machine (but will require you to restart the instance for them to run). Basically you would need to write some code that will allow your site to update itself. This link may help: https://azure.microsoft.com/en-us/documentation/articles/cloud-services-startup-tasks/
If you have the ability to migrate to WebApps and WebJobs, I would recommend looking into that since that compute product solves your problem really well.
Here is a useful answer of the differences between WebApps and Cloud Services: What is the difference between an Azure Web Site and an Azure Web Role

How To Update a Web Application In Azure and Keep The App Up the whole time

I've a MVC Web Application (.NET) and from time to time I need to upgrade the deployment version on Azure, the problem is that I have customers that are using the Web-App and I cant take it down and make it unavailable.
There is a way to deploy a new version of my Web-App and still be up and running the all time? (during the deployment process)
One way that I could think of it to do it is by deploy the the Web-App to somewhere other than my current deployment and "play" with the DNS record on my external domain.
Use deployment slots.
Azure Web Apps let you create staging slots for your site. They're effectively independent sites that you can deploy your test/staging bits to.
Then when you have the staging site ready you can push a button and make it your public production site.
See here for more details: https://azure.microsoft.com/en-us/documentation/articles/web-sites-staged-publishing/

Resources