projectkudu / ARMClient

A simple command line tool to invoke the Azure Resource Manager API
http://blog.davidebbo.com/2015/01/azure-resource-manager-client.html
Other
315 stars 96 forks source link

Run inside VSTS task #34

Closed leidegre closed 6 years ago

leidegre commented 6 years ago

Is there any way you can run inside a VSTS task?

You can have PowerShell and Azure CLI running with an account that is provided by the VSTS environment can the same be made possible with ARMClient?

I really really don't want to have to setup service principals...

davidebbo commented 6 years ago

That sounds more like a VSTS question than ARMClient. If you can bring ARMClient to the VSTS build machine, then I suspect it would run fine from there.

leidegre commented 6 years ago

Yes, naturally, but it depends entirely on how it manages credentials. Trying to figure out that right now.

leidegre commented 6 years ago

From VSTS release process

[command]C:\Windows\system32\cmd.exe /D /S /C ""C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.cmd" login --service-principal -u ******** -p ******** --tenant ********"
2017-09-22T08:12:21.8913292Z [
2017-09-22T08:12:21.8923289Z   {
2017-09-22T08:12:21.8923289Z     "cloudName": "AzureCloud",
2017-09-22T08:12:21.8923289Z     "id": "...",
2017-09-22T08:12:21.8923289Z     "isDefault": true,
2017-09-22T08:12:21.8923289Z     "name": "Pay-As-You-Go",
2017-09-22T08:12:21.8923289Z     "state": "Enabled",
2017-09-22T08:12:21.8923289Z     "tenantId": "********",
2017-09-22T08:12:21.8923289Z     "user": {
2017-09-22T08:12:21.8923289Z       "name": "********",
2017-09-22T08:12:21.8923289Z       "type": "servicePrincipal"
2017-09-22T08:12:21.8923289Z     }
2017-09-22T08:12:21.8923289Z   }
2017-09-22T08:12:21.8923289Z ]

It signs you in using a service principal, is there anyway ARMClient can pick up that?

edit: there seem to be a connected service task here. will I have to roll my own VSTS task?

davidebbo commented 6 years ago

I see, so you mean make it work so if you're already logged in via 'az' tool, armclient would automatically pick that up? It doesn't do that, but if you already have the service principal info, that you use for az, why not pass the same thing to armclient? https://github.com/projectkudu/ARMClient/wiki/Using-Service-Principal-(spn)

leidegre commented 6 years ago

It's injected very secretively by the VSTS environment, maybe there's a task that let me customize this but I haven't found it.

Thanks, I'll keep digging.

edit: I really really really don't want to start having to manage service principals if I don't absolutly have to...

leidegre commented 6 years ago

@davidebbo btw, this tool is exactly what I've been looking for all along.

snobu commented 6 years ago

P.S. az can now call raw into ARM API as well:

e.g.

az resource show --id /subscriptions/axxxxxxxx/resourceGroups/amisecure/providers/Microsoft.Web/sites/amisecure/config/web --api-version 2016-08-01

az resource update --id /subscriptions/axxxxxxxxxx/resourceGroups/amisecure/providers/Microsoft.Web/sites/amisecure/config/web --api-version 2016-08-01 --set properties.key=value

Use https://resources.azure.com/ to build the request (there's an Azure CLI 2.0 tab in there).

leidegre commented 6 years ago

@snobu 👍 nice! though, you should know, I still like this tool better but I can't afford to waste more time trying to find a way to make credentials work within VSTS, so this will have to do. Thanks!

davidebbo commented 6 years ago

Yes, I pushed hard on them to support that :). Not quite as powerful yet. e.g. you wouldn't be able to call an action, like to restart a site. Though that's coming. See https://github.com/Azure/azure-cli/pull/4509

leidegre commented 6 years ago

@davidebbo what I wanted all along was something that allowed me to consume the ARM APIs without dragging in a gazillion of DLLs, so this ARMClient is small and nimble enough that I can easily integrate it with my own tooling. Right now, I'm using shell execute to interop with Azure CLI because it's the only thing that I can reliably get to work everywhere...

edit: that pull request is like 2 hours old... when is release? :)

leidegre commented 6 years ago

@snobu actually that's not enough. I need to be able to just do the freaking PUT operation of the raw JSON structure directly. I noticed that the Azure CLI is subject to race conditions, I'm just trying to push a bunch of appsettings but all the strings are too long to perform as a single op so I run them in parallel but I think they overwrite each other because only half of them get written.

snobu commented 6 years ago

I don't believe the ARM API supports parallel PUTs on the same set of App Settings. @davidebbo can confirm. Remember that all you really need is to get your hands on a Bearer token, then you can just HttpClient your way around ARM, without extra dependencies (well, except for ADAL or MSAL).

   var credential = new UserCredential(username, password);
   var result = context.AcquireTokenAsync(resource, clientId, credential);
   // result.AccessToken will have the Bearer
leidegre commented 6 years ago

From my testing, I would say it does not which of course makes sense because I'm assuming it's doing PUT over the same resource. Right now all my settings are 1600 characters, which is OK but I don't want to be hitting the 8000 character limit of the command line and have settings truncated without warning. I've been trying to use the CLI to just push some settings from a file but apparently, you cannot pass input as a file or through stdin. And the whole reason for doing it in parallel is because I don't want to wait longer than necessary...

snobu commented 6 years ago

You have an Azure PowerShell task for that in VSTS: image Define the App Settings as environment variables and pick them up in the .ps1 script.

$PropertiesObject = @{
    SqlConnStr=$env:SuperSecretSqlConnStr;
}

New-AzureRmResource -PropertyObject $PropertiesObject -ResourceGroupName amisecure `
    -ResourceType Microsoft.Web/sites/config -ResourceName "amisecure/appsettings" `
    -ApiVersion 2016-08-01 -Force

I think we've reached the offtopic limits for an ARMClient issue :)

leidegre commented 6 years ago

OK but the PowerShell RM module isn't very fun to work with because it doesn't remember your login between sessions like CLI does. And now I have two sets of shells to manage as well, which only do the REST part which I would like to do my self actually but I cannot see how I do that because I need to create a service principal for that yet, somehow this is not necessary with the VSTS, PowerShell RM or CLI.

Specifically, VSTS appears to have a "connected service" that is our Azure subscription and it is using a service principal to access our subscription but I cannot pass those credentials onto a tool of my choosing. I have to invoke stuff through shells like CLI or PowerShell which again, only because I cannot get easy API access to my own subscription.

I tried creating a service principal once, ran into an access denied issue and sort of gave up on that. It shouldn't be this difficult.

Again, the ARMClient is precisely the tool I want the question now is only how to get the service principal from VSTS into the ARMClient. I guess I write my own VSTS task for that but I would like to avoid that as well, if possible.

I write tools to make the things we do at our shop easier to manage. These tools have very simple GUIs tailored to our use case, it then generates commands that gets executed. Thus far, this has proven to be the best solution for us.

snobu commented 6 years ago

You should see the VSTS Service Principal in your subscription in the Azure Portal, under your Web App, however i'm not sure if you can see its password.

image

Just create a service principal, allocate a quiet 10 minutes, it's really not difficult, and seems to be the answer to your troubles.

leidegre commented 6 years ago

I can drop our production database but I cannot create an app in our AD, sigh. Yet I am an administrator of our subscription. At some future point maybe I will resolve this as well but I shouldn't have to jump through this many hops.