0
votes

Please help me to start certain virtual machine from the build pipeline.

There are https://dev.azure.com/organization and https://portal.azure.com/#home that I can access using my domain account.

I'd like to write build pipeline that will connect to the portal and start the VM

So I've created service connection and wrote the build pipeline code like:

variables:
  resourceGroup: group-AZDCWBLA03-017732
  system.Debug: true
pool: server
steps:

    - task: InvokeRESTAPI@1
      displayName: 'Invoke REST API: POST'
      inputs:
        serviceConnection: 'devTest VM start'
        headers: |
         {
         "Content-Type":"application/json", 
         "Authorization": "Bearer $env:TOKEN"
         }
        urlSuffix: '/resourceGroups/$(resourceGroup)/providers/Microsoft.Compute/virtualMachines/AZDCWBLA03/start?api-version=2018-06-01'
      env:
        TOKEN: $(system.accesstoken)

Machine name is AZDCWBLA03. Build result is

============================================================================== 
Task         : Invoke REST API: POST
Description  : Invoke a REST API as a part of your pipeline.
Version      : 1.0.6
Author       : Microsoft Corporation
Help         : [More information](https://go.microsoft.com/fwlink/?linkid=870236)
============================================================================== 



POST https://management.azure.com/subscriptions/ orgid /resourceGroups/group-AZDCWBLA03-017732/providers/Microsoft.Compute/virtualMachines/AZDCWBLA03/start?api-version=2018-06-01
                Response Code: 0
                Response: An error was encountered while processing request. Exception: {"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}
Exception Message: The remote server returned an error: (401) Unauthorized. (type WebException)

The problem is that I do not know how build token could be connected with azure VM portal. I suppose that $(system.accesstoken) could be not the same what I need. I'd like not to use my user credentials (besides of testing purposes only) and use current build token if it is possible to execute the Azure REST API

I can see from the log that POST uses correct URI with proper orgid and resourcegroup names.

Can you please give me some hint?

2

2 Answers

2
votes

I'm fairly certain that $(system.accesstoken) is only valid for calls to Azure Devops itself. So you'd need to pass in the token somehow (get it in one of the previous steps).

But honesly, its a lot simpler to just use Azure Powershell step:

- task: AzurePowerShell@3
  inputs:
    azureSubscription: Subscription Name
    ScriptType: InlineScript
    Inline: |
        Start-AzVm -Name AZDCWBLA03 -ResourceGroupName group-AZDCWBLA03-017732
    azurePowerShellVersion: LatestVersion

It will take care of the auth for you, but you'd need to create a service connection and give it appropriate rights (say VM Contributor)

2
votes

I'm little late to the party, but anyway here is what worked for me:

parameters:
- name: action
  default: ''
  values:
  - start
  - deallocate

steps:
  - task: InvokeRESTAPI@1
    inputs:
      connectionType: 'connectedServiceNameARM'
      azureServiceConnection: '$(AzureService)'
      method: 'POST'
      headers: |
        {
          "Content-Type":"application/json",
          "AuthToken": "$(system.AccessToken)"
        }
      urlSuffix: 'subscriptions/$(AzureSubscriptionId)/resourceGroups/$(AzureResourceGroupName)/providers/Microsoft.Compute/virtualMachines/$(AzureVmName)/${{ parameters.action }}?api-version=$(AzureApiVersion)'

First added new parameter connectionType and serviceConnection is replaced with azureServiceConnection.
Now $(system.AccessToken) actually belongs to established azureServiceConnection and need to be sent as AuthToken param in header. Additionally, I expanded urlSuffix with Azure SubscriptionId.

With this start and deallocate work as expected.