Over my Christmas break I found many cloud providers were offering free trials or free $100 towards the first two months of usage. I always wanted to get into trying a setup in the cloud so this post will be about my dive into cloud for the first time at home. I take no responsibility for costs associated with testing this out.

Project Description

The goal is to have a way to setup an environment to teach python online. We need a way to create the infrastructure and then install/configure jupyterhub with user accounts to connect with.

Infrastructure

Our infrastructure will be written in terraform. We need to start with the networking side of things.

Networking

We are going to create a VPC for the project and make a floating IP so we always have the same IP to connect to. This code can be found here.

terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option 
variable "do_token" {
  type = string
  description = "api token for digital ocean"
}

# Configure the DigitalOcean Provider
provider "digitalocean" {
  token = var.do_token
}

# create floating ip for the dev env
resource "digitalocean_floating_ip" "devip" {
  region     = "nyc3"
}

# create vpc for the jupyterhub dev env
resource "digitalocean_vpc" "devvpc" {
  name     = "jupyterhub-dev-network"
  region   = "nyc3"
  ip_range = "10.10.10.0/24"
}

output "devip" {
  value = digitalocean_floating_ip.devip.ip_address
}

output "devvpc" {
    value = digitalocean_vpc.devvpc.id
}

Notice the outputs at the bottom. We will need those for the other terraform after we apply this networking terraform.

Droplet Setup

Now we create our droplet with the networking we had setup previously. We will assign the floating IP to our droplet and put the droplet in the VPC. This code can be found here.

terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option
variable "do_token" {
  type = string
  description = "api token for digital ocean"
}

# Configure the DigitalOcean Provider
provider "digitalocean" {
  token = var.do_token
}

# get remote state for networking info
data "terraform_remote_state" "network" {  
  backend = "local"
  config = {    
    path = "./network/terraform.tfstate"  
  }
}

# Create the jupyter server
resource "digitalocean_droplet" "jupyterhubdev" {
    image  = "ubuntu-20-04-x64"
    name   = "jupyterhub-01"
    region = "nyc3"
    size   = "s-2vcpu-4gb"
    ssh_keys = [32690924]
    vpc_uuid = data.terraform_remote_state.network.outputs.devvpc
}

# assign the floating IP
resource "digitalocean_floating_ip_assignment" "dev_ip_assignment" {
  ip_address = data.terraform_remote_state.network.outputs.devip
  droplet_id = digitalocean_droplet.jupyterhubdev.id
}

# output ipv4 address
output "dev_instance_ip_addr" {
  value = digitalocean_droplet.jupyterhubdev.ipv4_address
}

After running this terraform our infrastructure is complete. All of it is located in NYC3. For this terraform you will need to find your ssh key id from your account for the ssh_keys parameter. It will fail if that doesn’t get updated.

Jupyterhub Installation

The rest of our setup can be handled by ansible code. The ansible code is in the same repo as the previous codePlease see the playbook named jupyterhub.yml. To run that playbook you will need to update the IP address in the development inventory. You will also need to create a new encrypted password for the devtest user in the group vars directory. To create a new password run the following:

echo -n "newpass" | ansible-vault encrypt_string

The value that gets outputted copy into the group vars file for jupyterhubdev.

Now run the playbook to install jupyterhub from the ansible directory.

ansible-playbook -i development playbooks/jupyterhub.yml --ask-vault-pass -u root

You will need to input the password you used to encrypt the password in the last step. After that script finishes jupyterhub is installed.

Lab Files

In order to push out class files to the students in the class I wrote a second playbook named lab.yml. To run that run the following:

ansible-playbook -i development playbooks/lab.yml -e '{"lab": "lab00", "target": "jupyterhubdev"}' -u root --ask-vault-pass

This will copy lab00 to all users defined for our class.

Conclusion

For me this was a great intro to setting up cloud infrastructure and some playbooks to accomplish tasks quickly. I think I could use this setup for teaching and enjoyed figuring this out. Everything is online in my python-teaching-environment repo.