JupyterLab環境構築から始めるTerraform

2021.07.21

はじめに

データアナリティクス事業本部の鈴木です。

最近はデータ分析をメインにしつつ、AWSやGCPなどのパブリッククラウド活用にも関心がある方が増えてきたように思っています。

クラウドサービスを勉強していると、次はInfrastructure as Code(IaC)に関心が出てきます。とはいえ、いきなりクラウド上のリソースを作るのはハードルが高く、なかなか手が出ない方も多いのではないでしょうか。

IaCツールの一つであるTerraformは、クラウド上のリソース以外にも、ローカルのDocker環境の管理が可能です。本記事では、データ分析をしているとよく利用するJupyterLab環境を、TerraformとDockerで作成することで、Terraformに入門していきます。

Terraformでやりたいこと

Jupyterが公開しているJupyterNotebook Data Science Stackイメージを起動します。

例えば、Docker Composeを使って起動する場合、以下のようにdocker-compose.ymlを作成してdocker-compose upで起動すると、ローカルとのデータ共有もできてとても便利です。

今回は同様の設定で、Docker Composeの代わりに、Terraformで起動してみましょう。

docker-compose.yml

version: "3"
services:
    datascience-notebook:
        image: jupyter/datascience-notebook:514883dc662a
        volumes: 
            - "マウントしたいディレクトリのパス"/:/home/jovyan/work
        ports:
            - 8888:8888
        container_name: datascience-notebook-container
        environment:
            - JUPYTER_ENABLE_LAB=yes

なお、docker-compose.ymlの記載内容の詳細については、Docker Composeのドキュメントをご確認ください。

Overview of Docker Compose | Docker Documentation

環境

私の実施した環境の情報を記載します。

  • Terraform v1.0.2
  • Docker Desktop Version 3.4.0 (3.4.0.5223)
  • macOS Catalina バージョン10.15.7

TerraformとDockerはインストールされていることを前提とします。

やってみる

作業用ディレクトリを作成する

まず、作業用ディレクトリを作成し、移動します。

# 作業用ディレクトリ作成
mkdir learn-terraform-docker-container

# 移動
cd learn-terraform-docker-container

main.tfを作成する

続いて、Terraformの構成を記載するmain.tfを作成します。

main.tf

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 2.13.0"
    }
  }
}

provider "docker" {}

resource "docker_image" "jupyter_science" {
  name         = "jupyter/datascience-notebook:514883dc662a"
  keep_locally = true
}

resource "docker_container" "jupyter" {
  image = docker_image.jupyter_science.latest
  name  = "datascience-notebook-cntainer"
  env = ["JUPYTER_ENABLE_LAB=yes"]
  ports {
    internal = 8888
    external = 8888
  }
  volumes {
    host_path = "マウントしたいディレクトリの絶対パス"
    container_path = "/home/jovyan/work"
  }
}

terraformブロックで、リソースを作成・管理に使用するプロバイダなど、Terraformの設定を記載します。今回は"docker"プロバイダを、Terraform Registryのkreuzwerker/dockerをソースとして定義します。

providerブロックではterraformブロックで定義した"docker"プロバイダの設定をします。なお、今回は特に指定はしませんでした。

また、Dockerイメージとコンテナの指定のため、resourceブロックでdocker_imageリソースとdocker_containerリソースの設定を記載します。記載内容は冒頭で紹介したdocker-compose.ymlと同様になるよう設定しました。

resourceブロックの設定の補足

resourceブロックにはDockerイメージとコンテナの設定を記載しました。

  • docker_imageリソースのkeep_locallyは、terraform destroy操作時にDockerイメージを削除するかどうかを制御します。今回は繰り返し起動することを見込んでtrueとしました。

  • keep_locallyをtrueにしておくと、2回目以降terraform applyするときはすぐにコンテナが起動しました。最初にterraform applyする際はローカルにjupyter/datascience-notebook:514883dc662aイメージがなかったので、コマンド実行から起動までに90秒かかりました。

  • volumesはDockerのvolumeオプションと同様です。host_pathにコンテナにマウントしたいローカルのパス、container_pathにマウント先のパスを記載します。

上記を含め、各リソースとオプションはDocker Providerのドキュメントに詳細が記載されているので、ぜひご確認ください。

Docs overview | kreuzwerker/docker | Terraform Registry

コンテナを起動する

main.tfが書けたので、早速コンテナを起動してみましょう。

Docker Desktopが起動していることを確認して、下記コマンドを実行します。

※このとき、4GB弱の大きさのイメージをダウンロードするので、ご注意ください。

# 初回はワークスペースを初期化する
terraform init

# リソースを作成する
terraform apply

terraform applyを実行すると、本当に環境を作成するか聞かれるので、問題なければ yes と入力します。

Apply complete! と表示されれば、JupyterLabが起動できているはずです。

http://localhost:8888/にアクセスすると、以下の画面が表示されます。 jupyterlabログイン画面

JupyterLabにログインする

初回はコンテナに直接ログインしてトークンを確認します。

docker exec -it datascience-notebook-cntainer /bin/bash

ログインできたら下記コマンドでtokenを取得します。

jupyter server list

先ほどの画面のSetup a PasswordのセクションのTokenに取得したトークンを、New Passwordに設定したいパスワードを入力します。

パスワード設定

入力できたらLog in and set new paswordを押すとログインできます。

ログイン後の画面

ちなみに、上記操作を行うと、コンテナの/home/jovyan/.jupyter/configjupyter_server_config.jsonが作成されます。このファイル内にハッシュ化された認証情報が記録されています。

main.tfのdocker_containerリソースに、下記でハイライトした部分を追加し、ホスト側のディレクトリに認証情報が残ります。以降の手順でterraform destroyしても、同じパスワードでログインすることが可能です。

resource "docker_container" "jupyter" {
  image = docker_image.jupyter_science.latest
  name  = "datascience-notebook-cntainer"
  env = ["JUPYTER_ENABLE_LAB=yes"]
  ports {
    internal = 8888
    external = 8888
  }
  volumes {
    host_path = "マウントしたいディレクトリの絶対パス"
    container_path = "/home/jovyan/work"
  }
  volumes {
    host_path = "認証情報を保存したいディレクトリの絶対パス"
    container_path = "/home/jovyan/.jupyter"
  }
}

コンテナを停止する

コンテナを使い終わったらterraform destroyで停止します。起動時と同様に、本当に環境を削除するか聞かれるので、問題なければ yes と入力します。

# リソースを削除する
terraform destroy

感想

TerraformとDockerでJupyterLab環境を構築することができました。

また、今回はDockerプロバイダに限った例ではあったものの、main.tfを作成し、terraformコマンドで環境を起動することで、Terraformを使ってリソースを作成する雰囲気が掴めました。

普段のデータ分析環境の起動にTerraformを使うことで、Terraformが身近になれば幸いです。

参考