Maintain password for TFS Release Management - powershell

I'm developing Release pipeline for our internal LOB applications using TFS 2015 Update2 Release Management. There are various tasks like "Windows Machine File Copy" and "Run PowerShell on Target machines" which needs admin credentials to be passed as input parameters. These admin credentials have Administrative access on target nodes. I'm using Windows service accounts for these. We have an organizational security policy to rotate passwords every year.
With that in mind, it is cumbersome to update hundreds of TFS release definitions for new password every year.
Do you have a better idea to handle this?
Thanks for your help and suggestions.

You can update release definitions programmatically via the REST API, which is well-documented and fairly straightforward.
Ex (note that this is for Update 3 and later, per the documentation, the API in TFS 2015.2 may differ slightly):
PUT https://fabfiber.vsrm.visualstudio.com/DefaultCollection/ff213d65-d61d-447c-b39d-d16f21b18364/_apis/release/definitions/28?api-version=3.0-preview.1
Content-Type: application/json
{
"id": 28,
"name": "Fabrikam.CD",
"createdOn": "2016-04-11T11:04:05.197Z",
"createdBy": {
"id": "52a5bc8d-4730-400a-95c7-7276d4ae5953",
"displayName": "Chuck Reinhart",
"uniqueName": "chuckreinhart#outlook.com",
"url": "https://fabfiber.vssps.visualstudio.com/_apis/Identities/52a5bc8d-4730-400a-95c7-7276d4ae5953",
"imageUrl": "https://fabfiber.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=52a5bc8d-4730-400a-95c7-7276d4ae5953"
},
"environments": [
{
"name": "Dev",
"rank": 1,
"deployStep": {
"tasks": []
},
"owner": {
"id": "52a5bc8d-4730-400a-95c7-7276d4ae5953",
"displayName": "Chuck Reinhart",
"uniqueName": "chuckreinhart#outlook.com",
"url": "https://fabfiber.vssps.visualstudio.com/_apis/Identities/52a5bc8d-4730-400a-95c7-7276d4ae5953",
"imageUrl": "https://fabfiber.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=52a5bc8d-4730-400a-95c7-7276d4ae5953"
},
"queueId": 2,
"demands": [],
"conditions": [],
"variables": {},
"runOptions": {},
"environmentOptions": {
"emailNotificationType": "Always",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0
},
"executionPolicy": {
"concurrencyCount": 0,
"queueDepthCount": 0
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": null
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false
}
],
"approvalOptions": null
}
}
],
"artifacts": [
{
"alias": "FabrikamCI",
"type": "Build",
"definitionReference": {
"project": {
"name": "Fabrikam",
"id": "ff213d65-d61d-447c-b39d-d16f21b18364"
},
"definition": {
"name": "Fabrikam.CI",
"id": "1"
}
},
"isPrimary": false
}
],
"variables": {},
"triggers": [],
"revision": 1,
"releaseNameFormat": "",
"retentionPolicy": {
"daysToKeep": 60
}
}

Related

azure function 404 not found when deployed from ARM, works fine when deployed from visual studio

I have an azure function that works when manually deployed via visual studio.
I then exported the ARM template from Azure portal and used this in a DevOps release pipeline.
The release pipeline succeeds after creating storage a hosting plan the function app and deploying the code to the function app.
When trying to access the function app however it throws a 404 not found error.
I've tried in postman and in the "code + test" section of the azure portal, but I get the same 404 error.
I assume the ARM template exported from azure portal is incorrect somehow but I cannot see how, as it deploys successfully.
Has anyone experienced this issue?
In case it is useful, below is the ARM template, almost as it was exported from the portal. I have changed function name and urls just to prevent any potential attacks.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"sites_myFuncName_name": {
"defaultValue": "myFuncName",
"type": "String"
},
"serverfarms_FuncsPlan_externalid": {
"defaultValue": "/subscriptions/2sdr7sec-8sd7-78sd-a628-78asfd89sfed/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/hostingPlanName",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Web/sites",
"apiVersion": "2022-03-01",
"name": "[parameters('sites_myFuncName_name')]",
"location": "North Europe",
"kind": "functionapp",
"properties": {
"enabled": true,
"hostNameSslStates": [
{
"name": "myFuncName.azurewebsites.net",
"sslState": "Disabled",
"hostType": "Standard"
},
{
"name": "myFuncName.scm.azurewebsites.net",
"sslState": "Disabled",
"hostType": "Repository"
}
],
"serverFarmId": "[parameters('serverfarms_FuncsPlan_externalid')]",
"reserved": false,
"isXenon": false,
"hyperV": false,
"vnetRouteAllEnabled": false,
"vnetImagePullEnabled": false,
"vnetContentShareEnabled": false,
"siteConfig": {
"numberOfWorkers": 1,
"acrUseManagedIdentityCreds": false,
"alwaysOn": false,
"http20Enabled": false,
"functionAppScaleLimit": 200,
"minimumElasticInstanceCount": 0
},
"scmSiteAlsoStopped": false,
"clientAffinityEnabled": false,
"clientCertEnabled": false,
"clientCertMode": "Required",
"hostNamesDisabled": false,
"customDomainVerificationId": "XXXXX",
"containerSize": 1536,
"dailyMemoryTimeQuota": 0,
"httpsOnly": true,
"redundancyMode": "None",
"storageAccountRequired": false,
"keyVaultReferenceIdentity": "SystemAssigned"
}
},
{
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('sites_myFuncName_name'), '/ftp')]",
"location": "North Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_myFuncName_name'))]"
],
"properties": {
"allow": true
}
},
{
"type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('sites_myFuncName_name'), '/scm')]",
"location": "North Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_myFuncName_name'))]"
],
"properties": {
"allow": true
}
},
{
"type": "Microsoft.Web/sites/config",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('sites_myFuncName_name'), '/web')]",
"location": "North Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_myFuncName_name'))]"
],
"properties": {
"numberOfWorkers": 1,
"defaultDocuments": [
"Default.htm",
"Default.html",
"Default.asp",
"index.htm",
"index.html",
"iisstart.htm",
"default.aspx",
"index.php"
],
"netFrameworkVersion": "v6.0",
"requestTracingEnabled": false,
"remoteDebuggingEnabled": false,
"remoteDebuggingVersion": "VS2019",
"httpLoggingEnabled": false,
"acrUseManagedIdentityCreds": false,
"logsDirectorySizeLimit": 35,
"detailedErrorLoggingEnabled": false,
"publishingUsername": "$myFuncName",
"scmType": "VSTSRM",
"use32BitWorkerProcess": true,
"webSocketsEnabled": false,
"alwaysOn": false,
"managedPipelineMode": "Integrated",
"virtualApplications": [
{
"virtualPath": "/",
"physicalPath": "site\\wwwroot",
"preloadEnabled": false
}
],
"loadBalancing": "LeastRequests",
"experiments": {
"rampUpRules": []
},
"autoHealEnabled": false,
"vnetRouteAllEnabled": false,
"vnetPrivatePortsCount": 0,
"localMySqlEnabled": false,
"ipSecurityRestrictions": [
{
"ipAddress": "Any",
"action": "Allow",
"priority": 2147483647,
"name": "Allow all",
"description": "Allow all access"
}
],
"scmIpSecurityRestrictions": [
{
"ipAddress": "Any",
"action": "Allow",
"priority": 2147483647,
"name": "Allow all",
"description": "Allow all access"
}
],
"scmIpSecurityRestrictionsUseMain": false,
"http20Enabled": false,
"minTlsVersion": "1.2",
"scmMinTlsVersion": "1.2",
"ftpsState": "FtpsOnly",
"preWarmedInstanceCount": 0,
"functionAppScaleLimit": 200,
"functionsRuntimeScaleMonitoringEnabled": false,
"minimumElasticInstanceCount": 0,
"azureStorageAccounts": {}
}
},
{
"type": "Microsoft.Web/sites/functions",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('sites_myFuncName_name'), '/FuncName')]",
"location": "North Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_myFuncName_name'))]"
],
"properties": {
"script_root_path_href": "https://myFuncName.scm.azurewebsites.net/api/vfs/site/wwwroot/FuncName/",
"script_href": "https://myFuncName.scm.azurewebsites.net/api/vfs/site/wwwroot/bin/MyFuncName.dll",
"config_href": "https://myFuncName.scm.azurewebsites.net/api/vfs/site/wwwroot/FuncName/function.json",
"test_data_href": "https://myFuncName.scm.azurewebsites.net/api/vfs/data/Functions/sampledata/FuncName.dat",
"href": "https://myFuncName.scm.azurewebsites.net/api/functions/FuncName",
"config": {},
"invoke_url_template": "https://myFuncName.azurewebsites.net/api/FuncName",
"language": "DotNetAssembly",
"isDisabled": false
}
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2022-03-01",
"name": "[concat(parameters('sites_myFuncName_name'), '/', parameters('sites_myFuncName_name'), '.azurewebsites.net')]",
"location": "North Europe",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('sites_myFuncName_name'))]"
],
"properties": {
"siteName": "myFuncName",
"hostNameType": "Verified"
}
}
]
}

Can't see my custom extension on Azure Devops Marketplace

My issue
I created an Azure Devops extension task. Deploy it on a publisher, shared it. But I can't find it on the MarkePlace.
What I did
This is my project:
This is my task.json:
{
"id": "0f6ee401-2a8e-4110-b51d-c8d05086c1d0",
"name": "deployRG",
"category": "Utility",
"visibility": [
"Build",
"Release"
],
"demands": [],
"version": {
"Major": "0",
"Minor": "1",
"Patch": "0"
},
"instanceNameFormat": "DeployRG $(name)",
"groups": [],
"inputs": [
{
"name": "Name",
"type": "string",
"label": "RG name",
"defaultValue": "",
"required": true,
}
],
"execution": {
"PowerShell3": {
"target": "CreateRG.ps1"
}
}
}
My manifest vss-extension.json:
{
"manifestVersion": 1,
"id": "deployRG",
"version": "0.1.0",
"name": "Deploy RG",
"publisher": "Amethyste-MyTasks",
"public": false,
"categories": [
"Azure Pipelines"
],
"tags": [
"amethyste"
],
"contributions": [
{
"id": "DeployRG",
"type": "ms.vss-distributed-task.task",
"targets": [
"ms.vss-distributed-task.tasks"
],
"properties": {
"name": "DeployRG"
}
}
],
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"files": [
{
"path": "DeployRG",
"packagePath": "DeployRG"
},
{
"path": "VstsTaskSdk"
}
]
}
What I checked
I am owner of the organization and belong to Project Collection Administrators group.
On the portal:
On the publisher portal:
What I need
I checked some tutorial on Internet and can't see what I do wrong.
Has anybody an idea?
Thank you
Aargh, I have just found and its easy.
After sharing, one should install the extension as indicated here:
https://learn.microsoft.com/en-us/azure/devops/extend/publish/overview?view=azure-devops
Don't know why so many tutorials skip this step

deploy web apps /create Stages by api to run new deployments

It’ possible to create a deploment stage by Azure DevOps API? We want to create a new stage and want to deploy a web app on the webserver. What is the best approach to release a new web app including the configuration of iis by azure devops API?
Kind Regards,
Dominik
If you mean creating release definition with stages and specific tasks, then you can call the Definitions - Create REST API.
For example to add a stage with the IIS Web App Deploy task:
POST : https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0
Request Body: (Of course, you need to replace the parameters accordingly. You can also capture the Request Body(Payload) by pressing F12 when creating a release definition from the UI)
{
"id": 0,
"name": "RESTAPI-WEB",
"source": 2,
"comment": "",
"createdOn": "2022-04-20T08:36:03.598Z",
"createdBy": null,
"modifiedBy": null,
"modifiedOn": "2022-04-20T08:36:03.598Z",
"environments": [
{
"id": -3,
"name": "Stage 1",
"rank": 1,
"variables": {},
"variableGroups": [],
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
],
"approvalOptions": {
"executionOrder": 1
}
},
"deployStep": {
"tasks": [],
"id": 0
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
],
"approvalOptions": {
"executionOrder": 2
}
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": 0
},
"agentSpecification": null,
"skipArtifactsDownload": false,
"artifactsDownloadInput": {},
"queueId": 158,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {},
"dependencies": []
},
"rank": 1,
"phaseType": 1,
"name": "Agent job",
"refName": null,
"workflowTasks": [
{
"name": "Deploy IIS Website/App: ",
"refName": null,
"enabled": true,
"timeoutInMinutes": 0,
"inputs": {
"WebSiteName": "TestSite",
"VirtualApplication": "",
"Package": "$(System.DefaultWorkingDirectory)\\**\\*.zip",
"SetParametersFile": "",
"RemoveAdditionalFilesFlag": "true",
"ExcludeFilesFromAppDataFlag": "true",
"TakeAppOfflineFlag": "false",
"AdditionalArguments": "",
"XmlTransformation": "false",
"XmlVariableSubstitution": "false",
"JSONFiles": ""
},
"taskId": "1b467810-6725-4b6d-accd-886174c09bba",
"version": "0.*",
"definitionType": "task",
"alwaysRun": false,
"continueOnError": false,
"overrideInputs": {},
"condition": "succeeded()",
"environment": {},
"retryCountOnTaskFailure": 0
}
],
"phaseInputs": {}
}
],
"runOptions": {},
"environmentOptions": {
"emailNotificationType": "OnlyOnFailure",
"emailRecipients": "release.environment.owner;release.creator",
"skipArtifactsDownload": false,
"timeoutInMinutes": 0,
"enableAccessToken": false,
"publishDeploymentStatus": true,
"badgeEnabled": false,
"autoLinkWorkItems": false,
"pullRequestDeploymentEnabled": false
},
"demands": [],
"conditions": [
{
"conditionType": 1,
"name": "ReleaseStarted",
"value": ""
}
],
"executionPolicy": {
"concurrencyCount": 1,
"queueDepthCount": 0
},
"schedules": [],
"properties": {
"LinkBoardsWorkItems": false,
"BoardsEnvironmentType": "unmapped"
},
"preDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"postDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"processParameters": {}
}
],
"artifacts": [
{
"type": "Build",
"definitionReference": {
"IsMultiDefinitionType": {
"name": "False",
"id": "False"
},
"project": {
"name": "AzureFunction",
"id": "4da2f07a-ac7b-43a0-b764-459af8a4d9df"
},
"repository": {
"name": "",
"id": ""
},
"definitions": {
"name": "",
"id": ""
},
"definition": {
"name": "AzureFunctions_CI",
"id": "172"
},
"defaultVersionType": {
"name": "Latest",
"id": "latestType"
},
"defaultVersionBranch": {
"name": "",
"id": ""
},
"defaultVersionTags": {
"name": "",
"id": ""
},
"defaultVersionSpecific": {
"name": "",
"id": ""
}
},
"alias": "_AzureFunctions_CI",
"isPrimary": true,
"sourceId": "",
"isRetained": false
}
],
"variables": {},
"variableGroups": [],
"triggers": [],
"lastRelease": null,
"tags": [],
"path": "\\",
"properties": {
"DefinitionCreationSource": "ReleaseNew",
"IntegrateJiraWorkItems": "false",
"IntegrateBoardsWorkItems": false
},
"releaseNameFormat": "Release-$(rev:r)",
"description": ""
}
To deploy the webapp, please refer to Deploy your Web Deploy package to IIS servers using WinRM and Deploy an Azure Web App for details.

Azure DevOps REST API to create a release definition

I'm trying to create a release definition by using Azure DevOps REST API. I've created a json file which has configuration details for the request. I'm getting the below error, while creating the release definition.
{
"$id": "1",
"innerException": null,
"message": "Workflow of deploy job 'Run on the agent' in release pipeline stage 'development' is invalid. Add valid tasks and try again.",
"typeName": "Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data",
"typeKey": "InvalidRequestException",
"errorCode": 0,
"eventId": 3000
}
I'm using the below request body to create a new release definition in Azure cloud.
{
"name": "myreleasedefn1",
"artifacts": [{
"type": "DockerHub",
"alias": "_dockerusername_mydockerimage",
"definitionReference": {
"connection": {
"id": "dd986f4a-123k-45d5-b8e6-fc4fds23rce",
"name": "dockerservice"
},
"defaultVersionType": {
"id": "selectDuringReleaseCreationType",
"name": "Specify at the time of release creation"
},
"definition": {
"id": "dockerusername/mydockerimage",
"name": "dockerusername/mydockerimage"
},
"namespaces": {
"id": "dockerusername",
"name": "dockerusername"
}
},
"isPrimary": true,
"isRetained": false
}],
"releaseNameFormat": "Release-$(rev:r)",
"environments": [{
"name": "development",
"rank": 1,
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 10
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "beforeGates"
}
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 12
}
],
"approvalOptions": {
"requiredApproverCount": null,
"releaseCreatorCanBeApprover": false,
"autoTriggeredAndPreviousEnvironmentApprovedCanBeSkipped": false,
"enforceIdentityRevalidation": false,
"timeoutInMinutes": 0,
"executionOrder": "afterSuccessfulGates"
}
},
"deployPhases": [{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"agentSpecification": {
"identifier": "ubuntu-16.04"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {
"downloadInputs": []
},
"queueId": 9,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Run on the agent",
"workflowTasks": [{
"version": "4.*",
"name": "Deploy Azure App Service",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"WebAppKind": "webAppContainer",
"WebAppName": "azureappservice1",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "dockerusername",
"DockerRepository": "mydockerimage",
"DockerImageTag": "10"
}
}]
}]
}]
}
It would be very helpful if you share an example template for the same request.
Please help!!!
Azure DevOps REST API to create a release definition
According to the error message:
"Workflow of deploy job 'Run on the agent' in release pipeline stage 'development' is invalid.
We could to know the task Deploy Azure App Service in the workflowTasks is invalid, we need to provide the correct request body for that task.
As I answered your previous post How to create new build pipeline using Azure DevOps REST API, this is very difficult and error-prone, if we add a huge request body completely manually. Usually, we use REST API Definitions - Get to get the Response Body from the similar release pipeline, then we update the corresponding properties by modifying the Response Body.
As test, I add the task Deploy Azure App Service in my release pipeline, then I use the REST API:
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{definitionId}?api-version=5.0
to get the Response Body:
"workflowTasks": [
{
"environment": {},
"taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1",
"version": "4.*",
"name": "Azure App Service Deploy: xxxx",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": "task",
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"ConnectedServiceName": "xxxxx",
"PublishProfilePath": "$(System.DefaultWorkingDirectory)/**/*.pubxml",
"PublishProfilePassword": "",
"WebAppKind": "webApp",
"WebAppName": "xxxx",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "",
"DockerRepository": "",
"DockerImageTag": "",
"VirtualApplication": "",
"Package": "$(System.DefaultWorkingDirectory)/**/*.zip",
"RuntimeStack": "",
"RuntimeStackFunction": "",
"StartupCommand": "",
"ScriptType": "",
"InlineScript": ":: You can provide your deployment commands here. One command per line.",
"ScriptPath": "",
"WebConfigParameters": "",
"AppSettings": "",
"ConfigurationSettings": "",
"UseWebDeploy": "false",
"DeploymentType": "webDeploy",
"TakeAppOfflineFlag": "true",
"SetParametersFile": "",
"RemoveAdditionalFilesFlag": "false",
"ExcludeFilesFromAppDataFlag": "true",
"AdditionalArguments": "-retryAttempts:6 -retryInterval:10000",
"RenameFilesFlag": "true",
"XmlTransformation": "false",
"XmlVariableSubstitution": "false",
"JSONFiles": ""
}
}
]
You could use this response body, and overwrite those properties you want to change.
Where can I get taskId in Azure portal?
You could check the source code of the task from Github,it is generally on the first line of task.json. Or you can use REST API/F12 to get it.
Can we use 'AzureContainerRegistry' as artifact type in the request
body?
The answer should be yes (not test it by a sample). You could add following request body in the body:
"artifacts": [
{
"sourceId": "xxxxxxxxxxxxxxx",
"type": "AzureContainerRepository",
"alias": "xxx",
"definitionReference": {
"connection": {
"id": "xxxxxx",
"name": "xxxx"
},
"defaultVersionType": {
"id": "latestType",
"name": "Latest"
},
"definition": {
"id": "xx",
"name": "xx"
},
"registryurl": {
"id": "22",
"name": "22"
},
"resourcegroup": {
"id": "xx",
"name": "xx"
}
},
"isPrimary": true,
"isRetained": false
}
],
Hope this helps.
I can help here. In workflowTasks You need to include the "taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1" which is id of the AzureRmWebAppDeploymentV4.
"workflowTasks": [
{
"taskId": "497d490f-eea7-4f2b-ab94-48d9c1acdcb1",
"version": "4.*",
"name": "Deploy Azure App Service",
"refName": "",
"enabled": true,
"alwaysRun": false,
"continueOnError": false,
"timeoutInMinutes": 0,
"definitionType": null,
"overrideInputs": {},
"condition": "succeeded()",
"inputs": {
"ConnectionType": "AzureRM",
"WebAppKind": "webAppContainer",
"WebAppName": "azureappservice1",
"DeployToSlotOrASEFlag": "false",
"ResourceGroupName": "",
"SlotName": "production",
"DockerNamespace": "dockerusername",
"DockerRepository": "mydockerimage",
"DockerImageTag": "10"
}
Once I added that I was able to create the release definition with your request body.

How to expand all properties in returned release definition

Our Azure DevOps architecture uses a single release pipeline to upgrade and kick off other pipelines. Before the kicked pipelines run a release, the "kicker" pipeline updates the release definition of the "kickee" pipeline. I only have the name of the "kickee" pipeline, not the ID, so to get the pipeline to upgrade, we call the API documented at:
https://learn.microsoft.com/en-us/rest/api/azure/devops/release/Definitions/List?view=azure-devops-rest-5.0#releasedefinitionexpands
Because we need to modify several aspects of the release definition, I need to use the $expand parameter to expand a number of properties that will be updated (variables, artifacts, environments, etc). The documentation seems to indicate that multiple properties can be expanded, but it is unclear how to do this. Is this some list passed into the parameter, and if so, what separates each the list? Is it expected that the parameter is specified multiple times (which I guess is legal according to How to pass multiple parameters in a querystring)? Other options?
You separate the properties with ,.
For example:
https://vsrm.dev.azure.com/{your-account}/{your-project}/_apis/release/definitions?$expand=Environments,Artifacts&api-version=5.0-preview.3
You will get in the result the Environments and the Artifacts:
"environments": [
{
"id": 1,
"name": "Environment 1",
"rank": 1,
"owner": {
"displayName": "Shayki Abramczyk",
"url": "https://app.vssps.visualstudio.com/xxxxxxx-7cea-4070-bdad-0e1f6e0bc9e7/_apis/Identities/7a9a9b44-a2f1-6dfd-a7f6-e49cafde66b0",
"_links": {
"avatar": {
"href": "https://dev.azure.com/shaykia/_apis/GraphProfile/MemberAvatars/msa.xxxYTliNDQtYTJmMS03ZGZkLWE3ZjYtZTQ5Y2FmZGU2NmIw"
}
},
"id": "xxxxx-a2f1-6dfd-a7f6-e49cafde66b0",
"uniqueName": "xxxxx#gmail.com",
"imageUrl": "https://dev.azure.com/shaykia/_api/_common/identityImage?id=xxxxx-a2f1-6dfd-a7f6-e49cafde66b0",
"descriptor": "msa.N2E5YTliNDQtYTJmMS03ZGZkLWE3ZjYtZTQ5Y2FmZGU2NmIw"
},
"variableGroups": [],
"schedules": [],
"currentRelease": {
"id": 7,
"url": "https://vsrm.dev.azure.com/shaykia/xxxxx-b891-4fe5-b2fe-9b9a19a1d1af/_apis/Release/releases/7",
"_links": {}
},
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
},
"properties": {},
"preDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"postDeploymentGates": {
"id": 0,
"gatesOptions": null,
"gates": []
},
"environmentTriggers": [],
"badgeUrl": "https://vsrm.dev.azure.com/shaykia/_apis/public/Release/badge/xxxxx5-b891-4fe5-b2fe-9b9a19a1d1af/1/1"
}
],
"artifacts": [
{
"sourceId": "xxxxx-b891-4fe5-b2fe-9b9a19a1d1af:2",
"type": "Build",
"alias": "MyProject",
"definitionReference": {
"artifactSourceDefinitionUrl": {
"id": "https://dev.azure.com/shaykia/_permalink/_build/index?collectionId=xxxxxx-8c69-4ea0-8882-6340bf42f3b6&projectId=7fcdafd5-b891-4fe5-b2fe-9b9a19a1d1af&definitionId=2",
"name": ""
},
"defaultVersionBranch": {
"id": "",
"name": ""
},
"defaultVersionSpecific": {
"id": "",
"name": ""
},
"defaultVersionTags": {
"id": "",
"name": ""
},
"defaultVersionType": {
"id": "latestType",
"name": "Latest"
},
"definition": {
"id": "2",
"name": "MyBuild"
},
"project": {
"id": "xxxxxx-b891-4fe5-b2fe-9b9a19a1d1af",
"name": "SampleForVSTS"
}
},
"isPrimary": true,
"isRetained": false
}
],
"releaseNameFormat": "Release-$(rev:r)",
"retentionPolicy": {
"daysToKeep": 30
},
"properties": {},
"id": 1,
"name": "New Release Definition",
"path": "\\",
"projectReference": null,
"url": "https://vsrm.dev.azure.com/shaykia/xxxxxx-b891-4fe5-b2fe-9b9a19a1d1af/_apis/Release/definitions/1",
"_links": {
"self": {
"href": "https://vsrm.dev.azure.com/shaykia/xxxxxx-b891-4fe5-b2fe-9b9a19a1d1af/_apis/Release/definitions/1"
},
"web": {
"href": "https://dev.azure.com/shaykia/xxxxxx-b891-4fe5-b2fe-9b9a19a1d1af/_release?definitionId=1"
}
}
}
]
}
I worked around the problem by using the list API to get the definition ID and then called the get API to get the full contents of a particular release definition. This isn't ideal if I needed to update a large number of release definitions at once, but will work for my needs since I only need to update definitions one at a time.