3
votes

I'm deploying an ARM template with VSTS which contains a lock (in my case lock on a Storage Account for a Function App)

{
    "parameters": {
        "name": {
            "type": "string"
        },
        "storageName": {
            "type": "string"
        },
        "location": {
            "type": "string"
        }
    },
    "resources": [
        {
            "apiVersion": "2015-05-01-preview",
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[parameters('storageName')]",
            "location": "[parameters('location')]",
            "properties": {
                "accountType": "Standard_LRS"
            },
            "resources": [
                {
                    "type": "Microsoft.Storage/storageAccounts/providers/locks",
                    "name": "[concat(parameters('storageName'), '/Microsoft.Authorization/', parameters('storageName'))]",
                    "apiVersion": "2015-01-01",
                    "dependsOn": [
                        "[concat('Microsoft.Storage/storageAccounts/', parameters('storageName'))]"
                    ],
                    "properties": {
                        "level": "CannotDelete",
                        "notes": "One or more function apps were linked to this storage account. You can see all the function apps linked to the account under 'files' or 'shares'."
                    }
                }
            ]
        },...

That just works fine when deploying from VS or from command line with my credentials. However when deploying from a VSTS release definition, the deployment fails with:

Resource Microsoft.Resources/deployments 'myFunctionApp' failed with message '{
  "error": {
    "code": "InvalidTemplateDeployment",
    "message": "The template deployment failed with error: 'Authorization failed for template resource 'myFunctionAppStorage/Microsoft.Authorization/myFunctionAppStorage' of type 'Microsoft.Storage/storageAccounts/providers/locks'. The client '***VSTS service principal Id***' with object id '***VSTS service principal Id***' does not have permission to perform action 'Microsoft.Authorization/locks/write' at scope '/subscriptions/*** subscription ***/resourceGroups/*** resource group ***/providers/Microsoft.Storage/storageAccounts/myFunctionAppStorage/providers/Microsoft.Authorization/locks/myFunctionAppStorage'.'."
  }
}

When I remove the Microsoft.Storage/storageAccounts/providers/locks section from the template, the VSTS deployment works. But then the storage account would bear no lock preventing a deletion.

1
You'd probably see the same error without involving a function app at all, by simply creating a storage account with a lock. I so, I'd suggest rephrasing the question to make it clearer that you're dealing with a pure ARM/Storage issue and not a Functions issue. And as for the other question, isolate away from VSTS if possible. The more isolated the question is, the easier it is to reason about it :)David Ebbo
Thanks @DavidEbbo for helping me sorting out the issue.Kai Walter
I was successfully able to manually deploy including the lock with a manually created Service Principal which I needed to add to role Owner - it did not work with the role Contributor, which VSTS by default assigns to the Service Principal. Hence I removed the role Contributor from the VSTS SP and assigned role Owner. With that the deployment even worked in VSTS. Based on that the answer for me would be to do exactly that with the VSTS SP because setting the lock obviously requires Owner rights.Kai Walter
Today it's better to just add User Access Administrator role.Piotr Perak

1 Answers

7
votes

Contributor role - which is assigned when VSTS creates the Service Principal in the AAD connected to the Resource Groups Subscription - is not sufficient for placing the lock. Assign Owner and the lock can be placed with the VSTS deployment process.