Question

Invoke a script or command using after creating a droplet

When using the DigitalOcean API to create a new droplet, is there a way to have the droplet run a command or script once it spins (using the API)?

Thanks.

Show comments

Submit an answer

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Happy to provide a bit more clarification:

User-data can be either YAML or a script format supported by the droplet’s OS by default (ex. Bash). When using a non-YAML script whitespace is only as much of a concern as it would be for any other script in the language you use.

You can paste a user-data script into the create page in the control panel. Check the user-data checkbox in the optional settings and the text box will appear to allow pasting the script.

You can also send user-data via the API populating the user-data field in your request to the create endpoint.

On first boot after it fetches it’s network configuration and other basic settings cloud-init will automatically run your script. Make sure that it is non-interactive as any prompt for user input will cause it to stall since there is no user to enter the needed information. You can log into your droplet and view the output of your script (if you’re installing a lot of things you can use tail to watch it actually run in real-time if you’re quick enough) in the file /var/log/cloud-init-output.log

Hello there,

This can be achieved. For example, in a simple bash script, you can deploy a droplet using the API and then connect to the droplet using the ssh-key that was added and execute the code bit that you need.

Regards

@alimakki @dreawelabs even though this is an older question, I ran into the same issue and I figured I’d share how I resolved this, just in case you’re still wondering how to fully automate it or in case anyone else stumbles upon this.

Since you’re using the API, I’d suggest creating an image. This is a snapshot of a droplet with pre-existing files and configurations you can then use to create a Droplet. To do that, use Packer: https://www.packer.io/

  1. install packer on your machine: https://www.packer.io/downloads

  2. create a packer hcl file for your image:

touch config.pkr.hcl
  1. add the DigitalOcean the following builder to your config.pkr.hcl file: https://www.packer.io/plugins/builders/digitalocean
packer {
  required_plugins {
    digitalocean = {
      version = ">= 1.0.0"
      source  = "github.com/hashicorp/digitalocean"
    }
  }
}
  1. init your packer file
packer init config.pkr.hcl
  1. add a source image to your config.pkr.hcl file. for instance: https://www.packer.io/plugins/builders/digitalocean#basic-example
source "digitalocean" "ubuntu" {
  image = "ubuntu-16-04-x64"
  region = "nyc3"
  size = "512mb"
  ssh_username = "root"
  snapshot_name = "myimage"
  api_token = "YOUR_API_KEY"
}

build {
  sources = ["source.digitalocean.ubuntu"]
}
  • this step will require your DigitalOcean api token (replace YOUR_API_KEY)
  • this step will also require image, region, and size slugs found here: https://slugs.do-api.dev/
  1. add a shell provisioner to your config.pkr.hcl that runs scripts upon the creation of your droplet: https://www.packer.io/docs/provisioners/shell

the idea is that packer will build an image which DigitalOcean will then use to create a droplet off of. so the scripts than run on your shell provisioner will modify you linux/ubuntu system (in this example) to add a script that runs when it boots.

build {
  name = "myimage"
  source = [
    "source.digitalocean.ubuntu"
  ]

  provisioner "shell" {
    inline = [
      "echo 'hello myimage as a droplet'"
    ]
  }
}
  1. you can test this by running the following command in the same directory as your config.pkr.hcl file:
packer build .

the following should happen:

  • packer will create a droplet locally (which should be reflected on your DigitalOcean dashboard)
  • in the output, you should see “hello myimage as a droplet” since it was echoed above
  • packer turning your local droplet to a snapshot (image) which will be uploaded to DigitalOcean
  • the droplet created above will be deleted
  • the image create should appear under the “Images” tab
  1. you can safely delete this test image

  2. in order to create a script that runs when your droplet boots, now you need to add a systemd service. in your inline scripts (inside your shell provisioner), add the following command:

touch /etc/systemd/system/mystartup.service

and

chmod +x /etc/systemd/system/mystartup.service

it should look something like:

build = {
  ...
  provisioner "shell" {
    inline = [
      "echo 'hello myimage as a droplet'",
      "touch /etc/systemd/system/mystartup.servce",
      "chmod +x /etc/systemd/system/mystartup.service"
    ]
  }
}

this will create a system daemon service that will get called on boot.

  1. define the service. make sure to dump the following into that new mystartup.service file:
[Unit]
Description=mystartup service
Documentation=https://github.com/mygithub/myrepo/blob/main/README.md

[Service]
Restart=no
Type=oneshot

ExecStart=sudo /root/mystartup.sh

[Install]
WantedBy=multi-user.target
  • replace ExecStart value with the command to run the script you want to run on boot
  • be sure to use an absolute path to your script
  • if you need to wait one some other service to run, use the After property under [Unit]
  • add your own documentation url
  • here’s the systemd documentation: https://www.freedesktop.org/software/systemd/man/systemd.service.html
  • as an option, you can dump the contents of the file line by line with the following approach under your shell provisioner inline scripts:
"echo '[Unit]' >> /etc/systemd/system/mystartup.service",
"echo 'Description=mystartup service' >> /etc/systemd/system/mystartup.service",
...
  1. clone the code you actually want to run, also, under your shell provisioner inline scripts:
"git clone https://github.com/mygithub/myrepo"
  • you can reference this project in your mystartup.service’s ExecStart command, IE:
ExecStart=sudo /root/myrepo/main.sh
After=pm2-root.service
  1. finally, enable the mystartup.service daemon service by also adding the following lines to your shell provisioner inline scripts:
"systemctl daemon-reload",
"systemctl cat mystartup.service",
"systemctl enable mystartup.service",
"systemctl status mystartup.service"
  1. build and publish image with new instructions:
packer build .
  1. to test, you can go to DigitalOcean, open your Images on the nav menu. your new image should be there.
  • click the “More” dropdown menu, and select “Create Droplet”.
  • specify matching droplet size and region, and create droplet.
  • your droplet should be created based on that image, which should run your shell script once it boots.
  • if you use pm2 to run it in the background, ssh to your new droplet and run the following to verify that it’s running:
pm2 status
pm2 logs
  1. you can safely delete the test droplet

  2. now that you know it’s working, get the image id by requesting it from the snapshots list endpoint: https://docs.digitalocean.com/reference/api/api-reference/#operation/get_images_list

  3. now that you know your image id, in your DigitalOcean API POST droplet request body, your add the image id to the request. for instance:

{
  "name": "mydroplet",
  "region": "nyc3",
  "size": "s-1vcpu-1gb",
  "image": "MY_IMAGE_ID"
}

for reference: https://docs.digitalocean.com/reference/api/api-reference/#operation/create_droplet

  1. happy coding! hope this helps!