Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can package Windows Azure cloud project from command line, but not deploy to Windows Azure itself

We have a solution featuring a web application project destined as a web role in a Windows Azure cloud service. It also bears a cloud service project that targets the cloud service only (production slot)

SlnRoot\WebApp1\WebApp1.csproj SlnRoot\CloudDeployment\CloudServiceName\CloudServiceName.ccproj

Publishing (deploying) from Visual Studio is very easy; simply select the Publish... option from the cloud project's context menu and hit Publish with all the pre-configured cloud service settings.

Now we are going a further step of trying to automate this process so I'm trying it out from command-line and raw MSBuild without the aid of Visual Studio.

.nuget\nuget.exe restore
msbuild .\CloudDeployment\CloudServiceName\CloudServiceName.ccproj /t:Publish /p:PublishDir=..\..\pubout\ /fl1 /v:d

But it appears the Publish target is in reality the Package option in Visual Studio, only generating the cspkg file which has to be manually uploaded to Windows Azure portal. This will not do, of course. Is there a separate target to specify to carry out the additional step (Deploy is not it; no such target) that Visual Studio carries out so easily?

like image 703
icelava Avatar asked Sep 25 '14 03:09

icelava


People also ask

Why can't I use application packages with Azure Storage?

You can't use application packages with Azure Storage accounts configured with firewall rules, or with Hierarchical namespace set to Enabled. The Batch service uses Azure Storage to store your application packages as block blobs.

Is it possible to run commands from Azure CLI?

Privacy policy. Thank you. The Azure Command-Line Interface (CLI) is a cross-platform command-line tool that can be installed locally on Windows computers. You can use the Azure CLI for Windows to connect to Azure and execute administrative commands on Azure resources.

How to run Azure App service from a remote package?

You can also run from a remote package. The easiest way to run a package in your App Service is with the Azure CLI az webapp deployment source config-zip command. For example: Because the WEBSITE_RUN_FROM_PACKAGE app setting is set, this command doesn't extract the package content to the D:\home\site\wwwroot directory of your app.

Is there a command line interface for Azure?

Thank you. The Azure Command-Line Interface (CLI) is a cross-platform command-line tool that can be installed locally on Windows computers. You can use the Azure CLI for Windows to connect to Azure and execute administrative commands on Azure resources.


3 Answers

Thanks for your advice. The true answer to the gap in my knowledge however - how do MSBuild and PowerShell gel together in the first place - came from my colleague who crafted a custom MSBuild proj file to get it all working together. A basic sample follows with comments

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0"
         DefaultTargets="Build"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<!-- Declare configuration properties for this deployment -->
<!-- This custom.proj file is in a sub-directory in solution root -->

  <PropertyGroup>
    <SolutionDir Condition=" '$(SolutionDir)'=='' ">$(MSBuildThisFileDirectory)..\</SolutionDir>
    <SolutionPath Condition=" '$(SolutionPath)'=='' ">$(MSBuildThisFileDirectory)..\CloudService.sln</SolutionPath>
    <OutDir Condition=" '$(OutDir)'=='' ">$(MSBuildThisFileDirectory)\Output\Binaries\</OutDir>
    <PackageOutDir>$(MSBuildThisFileDirectory)Output\Packages\</PackageOutDir>
    <TargetCloudService>targetcloudservice</TargetCloudService>
    <DeployConfig>BuildConfig</DeployConfig>
    <PubSettingsPath>$(MSBuildThisFileDirectory)subscription.publishsettings</PubSettingsPath>
    <SubscriptionName>subscription name</SubscriptionName>
    <StorageAccount>targetstorageaccount</StorageAccount>
  </PropertyGroup>


<!-- Target to restore all Nuget packages on a clean repo pull. -->

  <Target Name="RestorePackages">
    <Message Text="Restoring nuget..."/>
    <Exec Command="&quot;$(SolutionDir).nuget\NuGet.exe&quot; restore &quot;$(SolutionPath)&quot;" />
  </Target>

<!--
Target to package the indicated cloud project,
which will build the referenced web role project first with desired build config.
-->

  <Target Name="PackageCloud" DependsOnTargets="RestorePackages">
    <Message Text="Creating package for cloud deployment ..."/>
    <MSBuild
      Projects="$(MSBuildThisFileDirectory)..\CloudDeployment\$(TargetCloudService)\$(TargetCloudService).ccproj"
      Properties="OutputPath=$(PackageOutDir)$(TargetCloudService)\;Configuration=$(DeployConfig);"
      Targets="Publish"/>
  </Target>


<!--
Target to deploy the package produced by the dependency target.
This is the part that launches PowerShell to execute custom ps1 script
with all the cloud service parameters (MSBuild variables above)
and cspkg package for deployment.
The custom script uses the Azure module cmdlets to make service checks and publish.
-->

  <Target Name="DeployCloud" DependsOnTargets="PackageCloud">
    <Message Text="Deploying package to cloud service ..."/>
    <Exec WorkingDirectory="$(MSBuildThisFileDirectory)"
         Command="$(windir)\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy ByPass -f $(MSBuildThisFileDirectory)PublishCloudService.ps1 -packageLocation &quot;$(PackageOutDir)$(TargetCloudService)\app.publish\$(TargetCloudService).cspkg&quot; -cloudConfigLocation &quot;$(PackageOutDir)$(TargetCloudService)\app.publish\ServiceConfiguration.Cloud.cscfg&quot; -subscriptionDataFile &quot;$(PubSettingsPath)&quot; -selectedsubscription &quot;$(SubscriptionName)&quot; -servicename $(TargetCloudService) -storageAccountName $(StorageAccount)" />
  </Target>
</Project>

So a one-shot deployment invocation would be something like

msbuild.exe custom.proj /t:DeployCloud
like image 87
icelava Avatar answered Oct 19 '22 00:10

icelava


As astaykov pointed out, MSBuild on it's own doesn't know how to deploy to Azure but you can install the Azure Powershell SDK to do the deployment.

Even using the publishsettings file, there are still some additional commands you need to perform to do the deployment beyond just the publish one:

  • Import-AzurePublishSettingsFile - to use the settings
  • Set-AzureSubscription - used to set a default storage account (where you will upload the package from msbuild)
  • Select-AzureSubscription - used to update the subscription for your powershell context
  • Get-AzureStorageContainer - get the container you're going to upload the package to
  • New-AzureStorageContainer - useful if the container doesn't already exist
  • Set-AzureStorageBlobContent - Upload the package to blob storage
  • Get-AzureStorageBlob - Read info about the blob, likes it's Uri
  • Get-AzureDeployment - Get info about a deployment in a slot of your service - useful before dpleoyment, while waiting for instances to start, etc
  • Remove-AzureDeployment - Removes a deployment - useful if you publish to staging and VIP swap into production
  • New-AzureDeployment - Create a new deployment from a given package (blob), config, etc in a service
  • Move-AzureDeployment - VIP swap staging/production slots
  • Set-AzureDeployment - Can be used to change the status of a deployment

I have a post around building a sample publication script here: Automated Deployment to Azure Hosted Services

It walks through the process in greater depth to use those scripts in building a deployment script that follows the "deploy to staging and VIP swap into production" path, but a lot of the details are still relevant for a direct upgrade deployment.

I use a similar method for several projects, but go one step further and swap out the configuration projects in between an msbuild call and packaging.

On the "publish settings" vs credentials, I think it comes down to where you are going to be running these builds (and who has access to that environment) and whether you feel more comfortable with a certificate enabling access or a set of credentials, based on portability and visibility/access in your build process. A lot of the core steps will be the same, though.

like image 3
Tarwn Avatar answered Oct 19 '22 00:10

Tarwn


After you get your CSPKG and CSCONFIG files, you need to "manually" publish your project. MSBuild does not publish the project. You can use Azure PowerShell to publish the project. The Publish-AzureService is the cmdlet you are looking for.

You can also configure one (or more) users in your Azure AD tenant (something that each Azure subscription has) and enable fully automatic deployment with PowerShell without the need of .publishsettings file and client certificates. Check my Non-interactive login with Azure PowerShell and Azure AD blog post.

UPDATE

Fairly stright forward and easy to use PowerShell Script for creating new deployment on existing Cloud Service and existing Storage Account:

Add-AzureAccount
Select-AzureSubscription "<subscription name>"
Set-AzureSubscription -SubscriptionName "<subscription name>" `
                      -CurrentStorageAccountName "<storage_account_name>"
New-AzureDeployment -ServiceName "<cloud_service_name>" `
                    -Package "D:/tmp/cloud/myservice.cspkg"  `
                    -Configuration "D:/tmp/cloud/ServiceConfiguration.Cloud.cscfg" `
                    -Slot "Staging"

And an Upgrade Script:

Add-AzureAccount
Select-AzureSubscription "<subscription name>"
Set-AzureSubscription -SubscriptionName "<subscription name>" `
                      -CurrentStorageAccountName "<storage_account_name>"
Set-AzureDeployment -Upgrade `
                    -ServiceName "<cloud_service_name>" `
                    -Package "D:/tmp/cloud/myservice.cspkg"  `
                    -Configuration "D:/tmp/cloud/ServiceConfiguration.Cloud.cscfg" `
                    -Slot "Staging"

For Slot you can either use Staging or Production. For the case you use publish settings file, just replace the Add-AzureAccount with Import-AzurePublishSettingsFile.

Note that these are verified scripts.

like image 3
astaykov Avatar answered Oct 19 '22 00:10

astaykov