Start an Auto Swap in azure using TFS - azure

I'm using VSO to continuously deploy to azure.
I have three slots :
Staging ( for automated tests )
AutoSwap ( if the version passes the automated tests in staging, it's deployed to AutoSwap )
Production ( When AutoSwap is deployed, it will auto swaps with Production ).
The problem is that my deployments are done using FTP ( I can't do it otherwise because it's an Asp.net Core 1.0 app ), so when I deploy to AutoSwap, it's not detected as an actual deployment so no auto swap is done with production.
My question : Is there any powershell command that I can call from the TFS task to start that auto swapping ? ( A command to tell for example that a deployment has been done which I can call when the FTP uploading ends ) ?
EDIT
I have found and tried this but it does simply nothing ( it doesn't fail ) :
Switch-AzureWebsiteSlot -Name "MyApp" -Slot1 "production" -Slot2 "AutoSwap" -Force

Try to use the Move-AzureDeployment, which swaps the deployments in production and staging.
Parameter Set: Default
Move-AzureDeployment [-ServiceName] <String> [ <CommonParameters>]
More details you can refer the link from MSDN: Move-AzureDeployment
Note: This applies only to cloud services, not web apps. The difference between Web APP and cloud service: Web App vs Cloud Service
Update
This may caused by the azure powershell script loads from VSO online does not support swap-slot. Try to remove the Azure powershell module, and import a different one.
See the answer from Ryan P in this MSDN link: https://social.msdn.microsoft.com/Forums/windows/en-US/0f30b76b-7954-4558-a10d-6a2b6635765a/switchazurewebsiteslot-does-not-work-in-vso-online

The problem was that I'm using this utility to upload the files via FTP :
https://marketplace.visualstudio.com/items?itemName=januskamphansen.ftpupload-task
In its code there is this line which should be commented to not to block azure commands in the tasks following it :
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$CurrentSession.ignoreCert}
Now everything works great, It took me one week to find it, I hope that this answer will save time to someone.

Related

How can I prevent deploying code to the wrong function app?

I have developed a number of JavaScript functions that all get deployed to an Azure Function App. I have two different code sets intended for two different Azure FAs. Unfortunately, when the FAs were created they were not given a meaningful name, and instead are just a random string of letters and numbers.
I primarily deploy my code to Azure from within VSCode, and that seems to work fine. However, I have a strong concern that one day I will deploy one set of functions to the wrong FA, which would of course cause big problems.
Is there anywhere that I can define a list of "allowed" function apps, so that if I were to attempt deploying the code to another FA it would fail? Or is there another method to achieve a similar result?
As of right now, I can deploy any codebase to any FA.
To prevent deploying code to the wrong function:
There are few methods for restricting deployment to only particular Function Apps and preventing deployment to undesired Function Apps.
Use Deployment slots:
As detailed in MSDoc, You can choose a deployment slot for a function app which has a different URL than function app.
Instead of executing immediately in a production environment, you can test any fixes or incorrect deployments in a different deployment slot before it goes live by deploying it into a secondary deployment slot.
Because it is your production environment slot, your users will be accessing your original Function App.
How to work with Deployment Slots:
Goto Function App and you will find Deployment slots under deployment and then Add a slot as described in the below image:
You can also create a deployment slot using Az CLI command az functionapp deployment slot.
Use below format:
az functionapp deployment slot create --name <Functionapp> --resource-group <ResourceGroup> --slot "slot1"
Use Deployment Scripts:
When you deploy your code, you can specify a deployment script, which can be a CLI or PowerShell script.
You can create a deployment script that verifies the target Function App's name and fails if it does not match one of the given Function Apps.
Goto Azure Portal and search for Deployment Scripts to work with this.

How to automatically deploy a web job to Azure portal using Power shell

I have been checking for ways to deploy a web job to azure automatically using PowerShell. I saw some blogs that depict the steps and the following summarizes what I have tried
I build my application (ASP.NET Console Application) in release mode and Zipped the contents of bin/Release to a folder.
In PowerShell, I logged in with az login
Then I tried the following commmand
Invoke-WebRequest -Uri https://$applicationName.scm.azurewebsites.net/site/wwwroot/app_data/jobs/triggered/$webJobName ` -InFile $ZipFile -ContentType "application/zip" -Method Put
$ZipFile has the path to the folder I created on step 1.
The output I get is the following
Invoke-WebRequest : The page was not displayed because the request entity is too large
Please let me know if you know what the issue is or If you have any reference that would help.
Thanks in advance!
Thanks for pitching in everyone! Your input was helpful, however I would like to update the answer with the solution I found that was so easy and saved me so much time. I will like to update you on how I could successfully deploy the app service and web job in a single go. Its very easy and since it deploys web app and corresponding web jobs in a single go, this was the perfect solution for my scenario. Thanks to my colleague who helped me with this solution.
The following depicts the steps I had to go through.
Lets suppose that my app service in Azure is "appService1" and I want to create a triggered web job under appService1 that goes by the name "webJob1".
I followed zip-deployment with azure cli.
Publish your web application (For the app service) solution in release mode to get the files you will have to deploy. Let this folder be WebAppBuild.
Build your application (a console application in my case) that would serve as the web job for the app service in release mode.
Inside the published folder for the web application (for app service ie WebAppBuild in our example), add a folder with the following path
app_data\jobs\triggered\webJob1
(If you need more than one web jobs deployed, you can create more than one folders like webJob2, webJob3 etc)
Add the files you have in step 2 to this folder. This is basically the files needed for your web job
Zip the contents in a single folder that acts as your deployment folder for web app and web job
Go to powershell and run az login (works if you have installed azure cli, otherwise you will have to install it as well)
Log into your respective account with the prompt window
Run the following commands that sets run from package property to true for your web app and the second command is the actual deployment command
az webapp config appsettings set --resource-group <<resourceGroupName>> --name <<appServiceName>> --settings WEBSITE_RUN_FROM_PACKAGE="1" ;
az webapp deployment source config-zip --resource-group <<resourceGroupName>> --name <<appServiceName>> --src <<zipFilePath>>
Now login to your azure portal and navigate to your web app. Check under web jobs option and you will see that the web job has been created with the files you deployed.
For more help on starting, stopping, deleting the web job with azure cli, go through the following document.
Check here

Version 4 of Azure App Service Deploy - ERROR_USER_NOT_AUTHORIZED_FOR_CREATEAPP

This is a follow-up question to this question. The answer in the original question helped me, but I am stuck somewhere else. As a reminder, I want to deploy my application using a publish profile. My web app in Azure has two subfolders inside wwwroot and one of them is called backend. I want to deploy my application to that folder. I am not sure why msdeploy wants to create anything, since the web app is already there - I just need to get the artifacts inside the backend folder.
Here is the relevant part of the log (with some names changed to xyz):
2018-06-14T09:19:25.0295238Z Start executing msdeploy.exe
2018-06-14T09:19:25.0323018Z "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe" -source:package='D:\a\r1\a\artifacts\drop\xyz.zip' -dest:auto,computerName="https://xyz.scm.azurewebsites.net:443/msdeploy.axd?site=xyz/backend",userName="$xyz",password="***",authtype="basic",includeAcls="False" -verb:sync -disableLink:AppPoolExtension -disableLink:ContentExtension -disableLink:CertificateExtension -setParamFile:"D:\a\r1\a\artifacts\drop\xyz.SetParameters.xml"
-enableRule:DoNotDeleteRule -retryAttempts:6 -retryInterval:10000
2018-06-14T09:19:25.6154385Z Info: Using ID '89f1210b-39ba-4758-b7ee-76a06407a503' for connections to the remote server.
2018-06-14T09:19:28.0800802Z Info: Creating application (Default Web Site)
2018-06-14T09:19:28.2012951Z ##[debug]rc:1
2018-06-14T09:19:28.2013216Z ##[debug]rc:1
2018-06-14T09:19:28.2013360Z ##[debug]success:false
2018-06-14T09:19:28.2013523Z ##[debug]success:false
2018-06-14T09:19:28.2073234Z ##[error]Failed to deploy web package to App Service.
2018-06-14T09:19:28.2081930Z ##[debug]Processed: ##vso[task.issue type=error;]Failed to deploy web package to App Service.
2018-06-14T09:19:28.2082198Z ##[debug]{}
2018-06-14T09:19:28.2082470Z ##[debug]System.DefaultWorkingDirectory=D:\a\r1\a
2018-06-14T09:19:28.2083178Z ##[error]Error Code: ERROR_USER_NOT_AUTHORIZED_FOR_CREATEAPP More Information: Could not
complete an operation with the specified provider ("createApp") when
connecting using the Web Management Service. This can occur if the
server administrator has not authorized the user for this operation.
createApp http://go.microsoft.com/fwlink/?LinkId=178034 Learn more
at: http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_USER_NOT_AUTHORIZED_FOR_CREATEAPP.
Error count: 1.
I managed to resolve the issue. According to this answer by #starian chen-MSFT, I needed to set the correct parameter in SetParameters.xml. I did this by adding the following to my Visual Studio Build task:
/p:DeployIisAppPath="xyz"
where xyz is the value of DeployIisAppPath element in the publish profile.
The reason is that Azure expecting that site name will be presented twice in scm.azurewebsites.net:443/msdeploy.axd?site=%SiteNameHere%" and the same value as a parameter, by default value from file SetParameters.xml is used for second.
So, you need to modify the value of IIS Web Application Name parameter in xxx.SetParameters.xml programming (e.g. PowerShell or other tasks), after that it should works fine.
Azure staging web deploy fails with ERROR_USER_NOT_AUTHORIZED_FOR_CREATEAPP but not for production

Azure app service deployment with Powershell (No FTP)

I have an ASP.NET app service running in Azure as Paas,
what i wanted is simple powershell script that just deploys my ASP.NET build produced by jenkins, so just xcopy may work (No FTP).
Too many resources and options around the internet, specific input would be appreciated.
I'd look into msdeploy. It's a pretty powerful way to do deploys to Azure App Services.
Thanks for the input Mike, your input ended up looking something like this with powershell script.
#param([string]$packageFolderPath,[string]$publishProfilePath)
[string]$packageFolderPath = "C:\Site"
[string]$publishProfilePath = "C:\Publish\app-local1.PublishSettings"
#Get publish-settings from file
[xml]$xml=Get-Content($publishProfilePath)
[string]$azureSite=$xml.publishData.publishProfile.msDeploySite.get(0)
[string]$azureUrl=$xml.publishData.publishProfile.publishUrl.get(0)
[string]$azureUsername=$xml.publishData.publishProfile.userName.get(0)
[string]$azurePassword=$xml.publishData.publishProfile.userPWD.get(0)
[string]$computerName ="`"https://$azureUrl/msdeploy.axd?site=$azureSite`""
msdeploy.exe -verb:sync -source:contentPath=$packageFolderPath -dest:contentPath=$azureSite,ComputerName=$computerName,UserName=$azureUsername,Password=$azurePassword,AuthType='Basic'
Write-Output "Done !"

Azure ExpiredAuthenticationToken during New-AzureRmResourceGroupDeployment when deploying resources via Visual Studio

I'm trying to deploy an HDInsight cluster using an ARM template via Visual Studio. I've created an Azure Resource Group project in Visual Studio 2015, and added my resource definitions to the template JSON files.
However when I've gone to deploy it (by right-clicking the project, choosing Deploy -> New Deployment, entering my parameters), the output of Visual Studio shows (I've snipped out some boring stuff):
17:19:23 - Build started.
17:19:23 - Project "LaunchHdInsightCluster.deployproj" (StageArtifacts target(s)):
[snip]
17:20:27 - [VERBOSE] 17:20:27 - Resource Microsoft.HDInsight/clusters 'groupbhdinsight' provisioning status is running
17:31:06 - [ERROR] New-AzureRmResourceGroupDeployment : ExpiredAuthenticationToken: The access token expiry UTC time '3/14/2016 5:31:06 PM' is earlier than current UTC time '3/14/2016 5:31:07 PM'.
Note that the deploy only ran for 12 minutes before the access token expired - obviously for deploying an HDInsight cluster this is a problem (takes on average 20 minutes).
I'm just trying to understand what's going on under the hood here, as I can't find documentation for this. i.e:
What creates the access token and how? How long does it last for? I wasn't asked for any Azure creds when deploying - I'm assuming it must be the fact that I'm signed into Visual Studio using the same account I use in Azure, and it 'borrows' the authentication session, but this is just a guess
What determines the expiry time of the access token so I can prevent this happening again?
How do I refresh my authentication token?
What's happening here is that the Azure Resource Group deployment in VS uses the PowerShell Script in the project to do deployment (even though the output is hosted in VS, we use that PS script to do the work). The PowerShell script is authenticated by using the token from your VS sign in. That token is only good for an hour and then VS will refresh it. Once it's handed off to PowerShell though, PowerShell doesn't automatically refresh it. So if you have the token for 59 minutes, it's going to expire soon after you start the deployment. The token could last for an hour, or anything less than that. We're working on a fix for this (i.e. have PowerShell automatically refresh the token) but that's a month or so out yet. See: https://github.com/Azure/azure-powershell/issues/1068
Workarounds: Unfortunately there's no good work around from VS. But...
As observed the deployment will continue just fine in Azure, it's just that VS/PS can no longer poll for status. You can monitor the deployment via the portal or PowerShell.
If you drop to PowerShell and run the script, PowerShell will automatically refresh the token when you login with credentials - you can get the exact command that VS runs by sifting through the output window - this doc also gives an overview of running the script manually: https://azure.microsoft.com/en-us/documentation/articles/vs-azure-tools-resource-groups-how-script-works/
Hope that helps...
I bet it was a transient issue. I retried deployment (needed to modify my ARM template) and now it succeeded.
Please check your Azure Resource Group in the portal. You will likely have your resources up and running.
#Cleverguy25 provided an explanation of how I believe the deployment process work.
I am not sure, but I believe that the New-AzureRmResourceGroupDeployment uploads your template file and sets up a deployment to happen in the cloud. Then it queries the deployment to see if it is done and outputs the resources as they are created. Obviously those queries error when the token expires. But the deployment should continue.
You could ignore this error and query the deployment or resource group yourself, to see when it is done.
I follow this post, and simply execute 'Clear-AzureRmContext' this command, then reconnect to Azure, using 'connect-AzAccount', the issue resolved.
https://github.com/Azure/azure-powershell/issues/6585
Open a new powershell and get the current metadata used to authenticate Azure Resource Manager requests using Clear-AzureRmContext.
This worked the magic for me.

Resources