Is it possible to deploy on a single machine through API?

Submitted on: https://github.com/OctopusDeploy/OctopusDeploy-Api/issues/9

"On Octopus Deploy UI, we can deploy to a single machine on a specified environment. The use case is the following: when we create a new machine in an environment (for scaling out the web application), we do not want to do a full deploy on the environment, only just on this single machine (initial deploy for this machine).

Is it possible with the current API?"

you can do this with the octo.exe utility…

.\octo.exe deploy-release --project=“Shared” --forcepackagedownload --waitfordeployment --deploymenttimeout=300 --guidedfailure=False --deployto=$env --apiKey=$apiKey --server=$octopusServer --specificmachines=$machine --version=Latest

Short answer:

Yes it is possible. The following script will help you deploy to specific machines filtering by Name or URI patterns. Make sure to fill in the variables:

APIKey
OctopusURL
ProjectName
EnvironmentName
Filter

Long answer:

When you start a deployment, you are sending a POST request to /api/deployments with a JSON that looks pretty much like this

{
  "Id": "deployments-387",
  "ReleaseId": "releases-386",
  "EnvironmentId": "Environments-1",
  "ForcePackageDownload": false,
  "ForcePackageRedeployment": false,
  "SkipActions": [],
  "SpecificMachineIds": [],
  "TaskId": "ServerTasks-1508",
  "ProjectId": "projects-1",
  "UseGuidedFailure": false,
  "Comments": null,
  "FormValues": {},
  "QueueTime": null,
  "Name": "Deploy to Development",
  "Created": "2015-03-05T15:43:09.486+00:00",
  "LastModifiedOn": "2015-03-05T15:43:09.558+00:00",
  "LastModifiedBy": "dalmiro",
  "Links": {
    "Self": "/api/deployments/deployments-387",
    "Release": "/api/releases/releases-386",
    "Environment": "/api/environments/Environments-1",
    "Project": "/api/projects/projects-1",
    "Task": "/api/tasks/ServerTasks-1508",
    "Web": "/app#/deployments/deployments-387",
    "Artifacts": "/api/artifacts?regarding=deployments-387",
    "Interruptions": "/api/interruptions?regarding=deployments-387"
  }
}

As you may have noticed already, by default Octopus deploys to all the machines on the environment. On the JSON above you can see "SpecificMachineIds": []. When this value is set to an empty array, that means it’ll deploy to all the machines on the environment. If you want to cherry pick the machines you’ll be deploying to, you’re gonna have to add MachineIDs to SpecificMachineIds before you do the POST.

To get the machine IDs you could:

A) On the Web UI click on the tentacle from the environments page and then check the URL, it should be something like /app#/machines/machines-1. The machine ID is machines-1

B) Using the API, GET the environment (i.e /api/environments/Environments-1). The response will return a JSON that will contain links to many resources. One of them will be Machines. Do a GET to the machines link (i.e /api/environments/Environments-1/machines) and it’ll return a collection of machines, which will have the machine ID

Once you have the machine IDs, add them to SpecificMachineIDs and POST the message to /api/deployments. The SpecificMachineIDs on the message should look like this for a deployment to only 1 machine

"SpecificMachineIds": [
    "machines-1"
  ]

The gist at the beginning of the post makes pretty much all the same API calls a regular deployment invoked from the Web UI or Octo.exe would do. The comments on it should help understanding what is going on behind scenes.

Thanks!

Dalmiro

1 Like

Thank you very much for the detailed answer! That is exactly what I am looking for.