DigitalOcean Droplets are Linux-based virtual machines (VMs) that run on top of virtualized hardware. Each Droplet you create is a new server you can use, either standalone or as part of a larger, cloud-based infrastructure.
Cloud-init is an industry standard tool that allows you to automate the initialization of your Linux instances. This means that you can use cloud-init to inject a file into your Droplets at deployment that automatically sets up things like new users, firewall rules, app installations, and SSH keys. DigitalOcean’s User Data feature leverages cloud-init so you can deploy and automate the set up of several Droplets simultaneously. Learning to use cloud-init can save you a lot of set up time when deploying new Droplets.
This tutorial uses cloud-init to deploy two Droplets that automatically:
root
user access.nginx
on each Droplet.By the end of the tutorial, you be can log in to each Droplet using the new user name and SSH key, and view a static website hosted on each Droplet.
This use case opens up the possibility of being able to set up user accounts on Droplets for entire teams without even having to log in to the Droplet first.
To complete this tutorial, you need:
doctl
, DigitalOcean’s official CLI tool. This tutorial uses doctl
to add an SSH key to your account and deploy the Droplets with the cloud-init file.doctl
.To complete this tutorial, you need an SSH key to set up the new user account on the Droplet. After creating the key, you upload the public portion of the key to both your DigitalOcean and GitHub accounts.
To create an SSH key, open a terminal on your local machine and run the ssh-keygen
command. ssh-keygen
is an OpenSSH tool that guides you through how to generate SSH key pairs and is native to most operating systems.
ssh-keygen
ssh-keygen
then prompts you to enter a directory and name for the key pair. Enter git-user
and save it to the .ssh
directory on your local machine like this:
/Users/example-user/.ssh/git-user
ssh-keygen
then prompts you to enter a password for the SSH key. Entering a password for the key would require you to enter the password each time you used the key to authenticate. For the purposes of this tutorial, leave the prompt blank and press Enter. This skips adding a password to the key pair.
A successful creation returns output that looks like this:
Your identification has been saved in /Users/example-user/.ssh/git-user.
Your public key has been saved in /Users/example-user/.ssh/git-user.pub.
The key fingerprint is:
SHA256:msISS7fgSE8oo9W02r14HgMzfixLWxVlQIcRGINFOG0 dbrian@DO-Loaner-ZHV2L
The key's randomart image is:
+---[RSA 3072]----+
| *=+==+ |
| + E..+ |
| .o . |
| .o . . |
|oo=.B S |
|+*oX B + |
|o =.O X |
| o O.+ |
| +oo |
+----[SHA256]-----+
ssh-keygen
generated two files, a private key (git-user
) and a public key (git-user.pub
). You can confirm this by listing the files in the .ssh
directory:
ls /Users/example-user/.ssh
Deploying the Droplets with their automated configuration requires that the public SSH key be accessible to the Droplets at creation. During Droplet creation, we require users to provide either a public SSH key or a user-defined password to set up the Droplet’s root
user account. For this purpose, you use the git-user
public key and upload it to your DigitalOcean account even though the cloud-init configuration in this tutorial disables root
access immediately after the Droplet’s deployment.
To create the second user account on the Droplet, you upload the same public key to your GitHub account. Cloud-init imports this key and associates it with the second user account upon set up.
To upload the public key to your DigitalOcean account, run the doctl
SSH key import command with the --public-key-file
flag to specify the location of the git-user.pub
file:
doctl compute ssh-key import git-user --public-key-file /Users/example-user/.ssh/git-user.pub
The import command takes two required arguments: a unique name for the key and the path to the public key file on your local machine. A successful import returns output that looks like this:
ID Name FingerPrint
35868935 git-user 42:5b:9b:40:0d:fe:c5:f5:ae:c1:cd:8f:15:c9:20:d0
To verify a successful import, you can list the available public keys in your DigitalOcean account by running:
doctl compute ssh-key list
If you have not installed doctl
or received an authentication error, review our documentation on how to install and authenticate doctl
.
After you have imported the key into your DigitalOcean account, use cat
to return the contents of the git-user.pub
key:
cat /Users/example-user/.ssh/git-user.pub
Highlight the key’s contents in the terminal and then copy it to your local machine’s clipboard, then log in to your GitHub account to import the public key. Follow GitHub’s official documentation on adding a new SSH key for more details.
After uploading the public SSH key to your DigitalOcean and GitHub accounts, you can begin configuring the cloud-init.yaml
file that the Droplet uses to configure itself.
Droplets have cloud-init installed by default. The Droplet User Data feature allows you to inject a YAML file into the Droplet upon creation that cloud-init consumes. The YAML file acts as a user-defined specification of how the Droplet should be configured. cloud-init provides a vast amount of access to various properties of the Droplet that can be configured via this YAML specification, including setting the hostname, installing packages, running CHEF recipes, and running other scripts.
#cloud-config
users:
- name: example-user
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
ssh_import_id:
- gh:<your-GitHub-username>
disable_root: true
packages:
- nginx
runcmd:
- 'export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)'
- 'echo Droplet: $(hostname), IP Address: $PUBLIC_IPV4 > /var/www/html/index.html'
The YAML file for this tutorial defines:
example-user
) account on the Droplet with root-level permissions and the user’s preferred shell (bash
). It also specifies the SSH key to import from GitHub and associates with the new user account.example-user
user can access the Droplet.nginx
.nginx
server.To configure this file to retrieve the public key you uploaded to your GitHub account, copy the file above into your preferred text editor and then update the gh:<your-GitHub-username>
field with your GitHub username. Once you have updated the file, save the file to your local machine as cloud-config.yaml
and then close it.
Once you have configured the cloud-config.yaml
file, you can now deploy the Droplets to your DigitalOcean account.
Back in your terminal, run the following doctl
command to create the Droplets, replacing the placeholder value for the --user-data-file
with the path to your cloud-config.yaml
file:
doctl compute droplet create --image ubuntu-22-04-x64 --size s-1vcpu-1gb --region nyc1 --ssh-keys git-user --user-data-file <path-to-your-cloud-init-file> --wait first-droplet second-droplet
This command creates two Droplets named first-droplet
and second-droplet
in the NYC1 datacenter region. Here is what each part of the command represents:
doctl compute droplet create
: The command doctl
requires to create Droplets.--image ubuntu-22-04-x64
: The OS image used to create the Droplet. In this case the Droplets uses the Ubuntu 22.04 operating system.--size s-1vcpu-1gb
: The number of processors and the amount of RAM each Droplet has. In this case, each Droplet has one processor and 1 GB of RAM.--region nyc1
: The region to create the Droplets in. In this example, doctl
deploys the Droplets into the NYC1 datacenter region.--ssh-keys
: The SSH keys to import into the Droplet from your DigitalOcean account. You can retrieve a list of available keys by running doctl compute ssh-key list
--user-data-file <path-to-your-cloud-init-file>
: Specifies the path to your cloud-config.yaml
file. For example, /Users/example-user/cloud-config.yaml
.--wait
: Tells doctl
to wait for the Droplets to finish deployment before accepting new commands.first-droplet second-droplet
: The names of the Droplets being deployed. You can deploy as many Droplets as you like by providing a name for each Droplet at the end of the command.Once you enter the command, the terminal prompt remains blank until the Droplets have finished deploying. This may take a few minutes. A successful deploy returns output that looks like this:
ID Name Public IPv4 Private IPv4 Public IPv6 Memory VCPUs Disk Region Image VPC UUID Status Tags Features Volumes
311143987 second-droplet 203.0.113.199 203.0.113.4 1024 1 25 nyc1 Ubuntu 22.04 x64 cfcbcc95-365a-4705-a18d-54abde1fc7b4 active droplet_agent,private_networking
311912986 first-droplet 203.0.113.146 203.0.113.3 1024 1 25 nyc1 Ubuntu 22.04 x64 cfcbcc95-365a-4705-a18d-54abde1fc7b4 active droplet_agent,private_networking
It may take cloud-init a few minutes to complete its configurations before you can log in to the Droplets.
Once you have successfully deployed the Droplets you can verify that the cloud-init configuration was successful by logging in to one of the Droplets using the username defined in cloud-config.yaml
file. To log in, use the following OpenSSH command, replacing the placeholder value with the public IPv4 address of the Droplet:
ssh example-user@<your-droplet-ip-address>
A successful log in changes the prompt in the terminal to look like this:
example-user@first-droplet:~$
You can now use the user account to navigate around the Droplet.
To confirm that the nginx
configuration succeeded, paste one of the Droplets’ public IP address into your browser and then press Enter. The browser navigates to the Droplet’s nginx
homepage where it displays the Droplet’s name and its IP address.
In this tutorial, you:
nginx
website.You can now use these Droplets as you normally would or delete them as needed.
Once you have completed this tutorial, you can explore cloud-init’s reference documentation and examples to see what other properties of your Droplet you can automatically configure upon deployment.