Automate Droplet Setup with cloud-init

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.

In this tutorial, you will learn how to use cloud-init to deploy two Droplets that automatically:

  • Set up a new user on the Droplet.
  • Associate a public SSH key (from GitHub) with the new user.
  • Remove root user access.
  • Configure and launch nginx on each Droplet.

By the end of the tutorial, you will be able to log into 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.

Prerequisites

To complete this tutorial, you need:

  • A GitHub account to store your new user’s SSH key.
  • To install doctl, DigitalOcean’s official CLI tool. You will use doctl to add an SSH key to your account and deploy the Droplets with the cloud-init file.
  • An API token to authenticate your commands from doctl.

Step 1: Create Your SSH Keys

To complete this tutorial, you will need an SSH key to set up the new user account on the Droplet. After creating the key, you will 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 [email protected]ner-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

Step 2: Upload Public Keys

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 will 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 will upload the same public key to your GitHub account. Cloud-init will import this key and associate 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.

Once logged in to your GitHub account, click your profile icon in the upper-righthand corner of the screen and then click Settings from the drop-down menu. From the Access section of the left-navigation menu, select SSH and GPG keys. From the SSH Keys page, click New SSH Key.

GitHub SSH and GPG keys page

In the Title field, enter the name git-user and then paste the contents of the git-user.pub file into the Key field, then click Add SSH Key. GitHub adds the public SSH key to the account.

GitHub SSH and GPG keys page

GitHub adds the public key to your account.

For more information about how to add SSH keys to your GitHub account, see GitHub’s documentation.

Step 3: Configure the cloud-init File

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:
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:

  • A new user (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.
  • An option to disable root user access so that only the example-user user can access the Droplet.
  • Which packages to install upon deployment, in this case nginx.
  • Two commands that create an environment variable and configure the 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.

Step 4: Deploy the Droplets

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.

Step 5: Verify the Setup

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 [email protected]<your-droplet-ip-address>

A successful log in changes the prompt in the terminal to look like this:

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.

Droplet nginx site

Summary:

In this tutorial, you:

  • Created an SSH keypair and uploaded the public key to your DigitalOcean and GitHub accounts.
  • Configured a cloud-init YAML file.
  • Deployed two Droplets that used a cloud-init file to automatically configure a new user and an nginx website.

You can now use these Droplets as you normally would or delete them as needed.

What’s Next?

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.