How to deploy to Azure Resource Group using VSTS r

2020-07-22 16:52发布

问题:

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?

回答1:

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.