3

I am new to Visual Studio Team Services Release Management. My goal is to automate a deployment of an ASP.NET MVC application to the Azure App Service.

Trying different approaches, I created a Service Endpoint that is certificate based and one that uses a service principal (SPN). My build definition already builds a web deploy package, and the release definition is linked against that and can use this artifact.

Success 1: A deployment of the app using the Azure Web App Deployment Task already succeeded - almost.
Shortcoming 1: I do not understand how I can specify the correct Resource Group using this task. This uses the certificate based endpoint, and for this task I cannot use the other (SPN) endpoint.

Success 2: Using the Azure Resource Group Deployment task, I was able to use a JSON ARM template to create a new resource group with a web app in it. This way I can specify the resource group, addressing Shortcoming 1
Shortcoming 2: But now I don't understand how I can actually deploy the binaries of the build definition that has been linked against my release definition. The web application that gets created by the resource group deployment is empty, and a subsequent Web App Deployment Task seemingly cannot target this newly created web app, since it is probably not ARM based.

I get the feeling that I am missing something obvious here - any help is appreciated.

Update 1

Thanks to @bmoore-msft, I got a deployment working using the child resource extension example he linked to. Essentially, the corresponding snippet of my ARM template now looks like this:

"resources": [
{
    "apiVersion": "2015-08-01",
    "type": "Microsoft.Web/sites",
    "name": "[variables('fullEnvName')]",
    "location": "[parameters('siteLocation')]",
    "properties": {
        "name": "[variables('fullEnvName')]"
    },
    "resources": [
        {
            "apiVersion": "2014-06-01",
            "name": "MSDeploy",
            "type": "Extensions",
            "dependsOn": [
                "[concat('Microsoft.Web/Sites/', variables('fullEnvName'))]"
            ],
            "properties": {
                "packageUri": "https://dl.dropboxusercontent.com/u/<myId>/<WebDeploymentPackage>.zip",
                "dbType": "None",
                "connectionString": "",
                "mode": "Complete"
            }
        }
    ]
  }
]

But the problem is that this places a static link into my template - as you can see, I used Dropbox as temporary solution. But of course I don't want to upload my web deployment package to Dropbox, neither manually nor automatically. I want to link to the artifact created by my build definition, which unfortunately is dynamic and I can't find any information on how to construct this link. For example, build 1 is located at the following path
https://<tenant>.visualstudio.com/DefaultCollection/_apis/resources/Containers/800850?itemPath=<PathToWebDeploymentPackage>.zip
while build 2 is available here
https://<tenant>.visualstudio.com/DefaultCollection/_apis/resources/Containers/801968?itemPath=<PathToWebDeploymentPackage>.zip

So there is a number changing inside the link which means the link I refer to in my template must be dynamic which means I need to understand where to get that number from, which I don't.

Maybe there is another way of referencing artifact uploads?

Masterfu
  • 1,191
  • 3
  • 14
  • 26

1 Answers1

2

Take a look at this sample:

https://github.com/Azure/azure-quickstart-templates/blob/75d0588fbd2702288bd35ed24cb00e43dcf980c2/wordpress-mysql-replication/website.json

The website in that template resource has a child resource extension named "MSDeploy". This will deploy a package to the web site during deployment. So in your task that does the deployment you can create the web app, and deploy the package all in the one deployment task in RM.

You will need to use user or SPN authn for anything using ARM (no certs).

Update: Staging the Package

Ok, usually what I do here is "stage" my artifacts in Azure Storage (secured with a sasToken). The uri you provide in the template must be accessible to AzureRM. You VSTS build output is likely secured, so even though you could access it interactively, AzureRM cannot.

Essentially what you need is a task in RM (or build) that will 1) copy the artifacts to Azure (securely) and then 2) tell the next task where those artifacts are... Here's one option:

https://azure.microsoft.com/en-us/documentation/articles/vs-azure-tools-resource-groups-ci-in-vsts/

This doc is using VSTS build, but RM works the same way. The other part that's different is the doc is using a PS script used by Visual Studio in the Azure Resource Group projects. There's nothing special about that script (it will work anywhere just like any other PS script) but that's the example. It doesn't use the Azure Resource Group Deployment Task because that task cannot do the staging of the artifacts.

Essentially what you need to do is:

  1. parameterize that URI property (see example & repo below)
  2. copy the webdeploy package to Azure (PowerShell in this case)
  3. deploy the template and pass in the uri of the package

e.g. "packageUri": "[concat(parameters('artifactsLocation'), webdeploy.zip, parameters('sasToken')]"

That doc shows you how VS does it, and you should be able to adapt that for your scenario. If you go this route, you would use the Azure PowerShell task and no longer need the Azure Resource Group Deployment Task.

Another way to do this is with the Azure File Copy task, but currently that task does not output the URI or sasToken, so you couldn't pass it in to the deployment task (there's a PR in the queue to make that work).

Another option if you don't have access to Visual Studio is this repo:

https://github.com/Azure/azure-xplat-arm-tooling/tree/master/PowerShell

It has the same PS script that VS uses, and the templates show an example of the parameterized URL (for a dsc.zip file in this example) but would work the same way for msdeploy.

You've actually hit on one of the more sophisticated scenarios and at the moment not doc'd real well, but it's pretty cool when it works. LMK if you need more help here.

bmoore-msft
  • 8,376
  • 20
  • 22
  • Thanks bmoore-msft. I got a deployment working using the child resource extension you mentioned. However, it is still not working as I would like it to work. I will update my question accordingly to explain further. – Masterfu Feb 19 '16 at 13:34
  • Thanks, I got it working by using the Azure File Copy task, and hardcoding the blob link and SAS token. Still, the current situation seems to be a contradiction to what Release Management is about. IMO, the environment should be created *during* a RM deployment, and not *before* during the build task. Otherwise, what's all the staging and approving about? – Masterfu Feb 22 '16 at 15:35
  • Completely agree with your thinking re: during vs. before. Once the PR for outputting the storage uri and token is accepted, I think that will work the way you want. If not, I'd love to hear about it since there may be another scenario we're missing. – bmoore-msft Feb 22 '16 at 21:15
  • Thanks for commenting again on this one. One thing that will probably still be open even after the PR is the problem that there needs to be a storage account to upload the binaries to *before* the release task actually sets up all the infrastructure - including the storage account. This can be circumvented by having a central, pre-existing storage account to store all the uploads, as opposed to having environment-specific storage. An argument could be made for both approaches, I guess. Definitely going to check it out should the PR come to my attention. – Masterfu Feb 23 '16 at 13:52
  • Hmmm... yes this is another interesting view on the workflow - we took the approach that you'd likely have a static place to stage artifacts but the notion of "temp" has merit too... I'd love to talk to you about this more, if you're up for it feel free to email bmoore at microsoft.com. – bmoore-msft Feb 23 '16 at 17:54
  • 1
    There ought to be a start-to-end example for this. :) – Veksi Feb 29 '16 at 21:22
  • 1
    We're working on updating this: https://azure.microsoft.com/en-us/documentation/articles/vs-azure-tools-resource-groups-ci-in-vsts/ which shows how to do it with the PowerShell script from VS. For the approach using Tasks, we need VSTS updated and then we can document that approach. – bmoore-msft Mar 01 '16 at 15:06
  • @bmoore-msft Sounds cool! Maybe a bad place to ask, but can you estimate weeks? How to shuffle work in the nearish future I'm thinking... – Veksi Mar 03 '16 at 17:57
  • Ok, well the VSTS task updates shipped this week. Not sure about the doc yet, but probably a few weeks on that. If you get impatient, ping me directly and I'll walk you through it. – bmoore-msft Mar 03 '16 at 18:54
  • @bmoore-msft Hmm, where should I ping? I don't definitely want to take your free-time, but if you have cycles to spear on people on BizSpark (to at least here the case and in which situation this would be applied), I'd be delighted about that too. – Veksi Mar 07 '16 at 11:00
  • you can send email bmoore at microsoft.com - don't worry about taking free time, your feedback will help us get the doc right :) – bmoore-msft Mar 07 '16 at 15:36
  • @bmoore-msft Much, appreciated, thanks. I sent a more in-depth e-mail with a heading "Veksi from Stackoverflow, about resource group deployment from VSTS Release Management" on what a person like a me would wish to see in such instructions. – Veksi Mar 08 '16 at 08:15