0
votes

I am trying to create a service endpoint (aka service connection) in Azure DevOps. I first attempted to use the DevOps CLI but this method hangs. Using az devops as shown below.

az devops service-endpoint azurerm create --name “Azure subscription 1 endpoint” --azure-rm-service-principal-id $serviceprincipleid --azure-rm-subscription-id $subscriptionid --azure-rm-tenant-id $tenantid --azure-rm-subscription-name $serviceprinciplename --organization $organization --project $project

Hangs till i restart PowerShell

I suspect the logged in account doesn't have access?? IDK. And there's no way to specify a personal access token which is what I need anyway.

I then turned my attention towards calling the DevOps REST method using a Personal Access Token (PAT) to authenticate. I'm using the documentation from this sample

Here is the basic code in PowerShell

$body = '{
  "data": {
    "subscriptionId": "1272a66f-e2e8-4e88-ab43-487409186c3f",
    "subscriptionName": "subscriptionName",
    "environment": "AzureCloud",
    "scopeLevel": "Subscription",
    "creationMode": "Manual"
  },
  "name": "MyNewARMServiceEndpoint",
  "type": "AzureRM",
  "url": "https://management.azure.com/",
  "authorization": {
    "parameters": {
      "tenantid": "1272a66f-e2e8-4e88-ab43-487409186c3f",
      "serviceprincipalid": "1272a66f-e2e8-4e88-ab43-487409186c3f",
      "authenticationType": "spnKey",
      "serviceprincipalkey": "SomePassword"
    },
    "scheme": "ServicePrincipal"
  },
  "isShared": false,
  "isReady": true,
  "serviceEndpointProjectReferences": [
    {
      "projectReference": {
        "id": "c7e5f0b3-71fa-4429-9fb3-3321963a7c06",
        "name": "TestProject"
      },
      "name": "MyNewARMServiceEndpoint"
    }
  ]
}' | convertto-json | convertfrom-json

$bo = $body | convertfrom-json
$bo.data.subscriptionId = $subscriptionid
$bo.data.subscriptionName = "subscription name"
$bo.name = $serviceprinciplename
$bo.authorization.parameters.tenantid = $tenantid
$bo.authorization.parameters.serviceprincipalid = $serviceprincipalid
$bo.authorization.parameters.serviceprincipalkey = $serviceprincipalkey
$bo.serviceEndpointProjectReferences = @{}

$readybody = $bo | convertto-json -Depth 100

#POST https://dev.azure.com/{organization}/_apis/serviceendpoint/endpoints?api-version=6.0-preview.4
function createazurermserviceendpoint($body, $pat, $org, $project)
{
    #POST https://dev.azure.com/{organization}/_apis/serviceendpoint/endpoints?api-version=6.0-preview.4
    $requestpath = "/_apis/serviceendpoint/endpoints?api-version=6.0-preview.4"
    $token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$pat"))
    $uribase = "https://dev.azure.com/" + $org
    $uri = $uribase+$requestpath
    $authheader = "Authorization=Basic " + $token

    $result = az rest --method post --uri $uri --headers "Content-Type=application/json" $authheader --body $body | convertfrom-json
    return $result
}

$result = createazurermserviceendpoint $readybody $pat $org $project 

The method throws a Bad Request exception as shown below

az : Bad Request({"$id":"1","innerException":null,"message":"TF400898: An Internal Error Occurred. Activity Id: 
10a098a9-b4b5-4def-8356-307a5cad0579.","typeName":"Newtonsoft.Json.JsonReaderException, 
Newtonsoft.Json","typeKey":"JsonReaderException","errorCode":0,"eventId":0})

So, i went into the UI with fiddler and captured both an automated and manual create service endpoint believing the contract would be the same. I'm not certain it is. The resulting json body from the API is shown below. When I attempt to pass this through the script I get the exact same error as above for both of them. None of the json is like the other; I started with the sample json structure in the article mentioned above. Now I'm not certain what the issue is at all.

   #hack a version from fiddler to try it
    
    #fiddler body capture from automated service connection

    $readybody = '{"authorization":{"parameters":{"tenantid":"xxxxxxxx-34e9-4306-ac1a-5f28c1d08fb1","serviceprincipalid":"","serviceprincipalkey":"","authenticationType":"spnKey"},"scheme":"ServicePrincipal"},"createdBy":{},"data":{"environment":"AzureCloud","scopeLevel":"Subscription","subscriptionId":"yyyyyyyy-75c4-4dfd-bdd5-c8c42d1a5dd0","subscriptionName":"Azure subscription 1.1","creationMode":"Automatic","appObjectId":"","azureSpnPermissions":"","azureSpnRoleAssignmentId":"","spnObjectId":""},"isShared":false,"name":"Azure sub 1.1 test","owner":"library","type":"azurerm","url":"https://management.azure.com/","administratorsGroup":null,"description":"","groupScopeId":null,"operationStatus":null,"readersGroup":null,"serviceEndpointProjectReferences":[{"description":"","name":"Azure sub 1 test","projectReference":{"id":"zzzzzzzz-fad9-427f-ad6c-21f4ae2d311f","name":"Connected2someone"}}]}'

$result = createazurermserviceendpoint $readybody $pat $org $project 

Fails the same way

    #fiddler body capture from manual service connection

    $readybody = '{"dataSourceDetails":{"dataSourceName":"TestConnection","dataSourceUrl":"","headers":null,"resourceUrl":"","requestContent":null,"requestVerb":null,"parameters":null,"resultSelector":"","initialContextTemplate":""},"resultTransformationDetails":{"callbackContextTemplate":"","callbackRequiredTemplate":"","resultTemplate":""},"serviceEndpointDetails":{"administratorsGroup":null,"authorization":{"scheme":"ServicePrincipal","parameters":{"serviceprincipalid":"xxxxxxxx-65b2-470d-adc7-c811fc993014","authenticationType":"spnKey","serviceprincipalkey":"{a key}","tenantid":"yyyyyyy-34e9-4306-ac1a-5f28c1d08fb1"}},"createdBy":null,"data":{"environment":"AzureCloud","scopeLevel":"Subscription","subscriptionId":"zzzzzzzz-75c4-4dfd-bdd5-c8c42d1a5dd3","subscriptionName":"azure test 2 ","creationMode":"Manual"},"description":"","groupScopeId":null,"name":"azure test 2 connection","operationStatus":null,"readersGroup":null,"serviceEndpointProjectReferences":null,"type":"azurerm","url":"https://management.azure.com/","isShared":false,"owner":"library"}}'

$result = createazurermserviceendpoint $readybody $pat $org $project 

Fails the same way.

Can someone confirm the REST API works? what version of the API is specified and does the body json look like what I posted?

1

1 Answers

1
votes

I did a test with your PowerShell script and got the same error you did.

enter image description here

Then I switched to another PowerShell script with the same body, and it worked.

Here is my script:

$pat = "{PAT}"
$pat = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$url="https://dev.azure.com/{organization}/_apis/serviceendpoint/endpoints?api-version=6.0-preview.4"
$body = @'
{
    body
}
'@

$head = @{ Authorization =" Basic $pat" }
Invoke-RestMethod -Uri $url -Method Post -Headers $head -Body $body -ContentType application/json

So the cause of the error may be your PowerShell script (probably az rest) and not the REST API request body. You can try out the PowerShell script I've provided.

By the way:

You can sign in Azure DevOps CLI with a PAT. Please click this document for detailed information.