Jupyter+Ansibleを使ったインフラ運用のはじめかた

去年書いた [Jupyter+Ansibleを使ったインフラ運用の考え方2017](https://qiita.com/yacchin1205/items/8bd1b79942418e0d0888) では、Jupyter+Ansibleを使ったインフラ運用の考え方(Literate Computing for Reproducible Infrastructure: LC4RI)について説明しました。
今回は、LC4RIを使ったインフラ運用をどのように始めたらよいか？という観点でまとめてみたいと思います。

# 何が問題なのか？

「JupyterとAnsibleを使って賢くインフラ運用できる」として、

* どこに/どうやってそのJupyter環境を構築すべきか？
* どうやってJupyterから(Ansibleを介して)操作対象マシンを操作できるようにすべきか？

といった、**LC4RIを実施可能な(Jupyter+Ansible環境を含んだ)インフラ構成のパターンとその構成手順**をまだまだ明らかにできていないなという問題意識があります。

個人的には、これらをまとめることが難しい最大の理由は、**すでに動いてしまっているインフラ**があり、**セキュリティポリシーなどを含む運用にまつわるルールが存在**する点にあると思っています。
LC4RI環境の導入自体にも、導入対象が持っているこれまでの経緯を踏まえて検討をおこなう必要があるなあということです。しかしながら、これらの前提条件をパターン化して、カタログ化するまではまだ(個人的には)至っていない・・・という現状認識もあります。(たぶんこれは、広くこのやり方を試してもらう中で明らかになるのだとも。)

そこで、今回は、アプローチとして**自分自身が試みたLC4RI実施可能なインフラ構成例**をパターンとしていくつか挙げながら、それらの**構成に必要な設定手順を整理する**という形式で、カタログ化への一歩としてみたいと思います。
LC4RIを使ったインフラ運用をどのように始めたらいいかを考えておられる方がいたとして、前提条件が合致するようなパターンがあればその構成を試してみてもらえればと考えています。

# インフラ構成例

LC4RIを実施するためには、運用者は、Ansibleが利用可能なJupyter Notebookサーバを用意し、自身が管理するインフラと連動させる必要があります。この構成例をいくつか列挙してみます。
現段階ではこれらに網羅性はありませんが、読んでいる方がどう環境を構成するか、考える材料にはなるのではないかなと。

* ローカルJupyter+既存マシン
* インフラ内Jupyter+既存マシン
* ローカルJupyter+パブリッククラウド

それぞれのインフラ構成例には、「はじめかた」という項目を用意しています。この項目では手順を詳細に説明することはしませんが、[設定手順](#設定手順)のセクションの説明である程度理解できるようにしているつもりです。

## パターン1: ローカルJupyter+既存マシン

すでに運用しているマシン(既存マシン)を操作対象のマシンとして、運用者の作業用マシンにLC4RI実施可能なJupyter Notebook環境を導入する方法です。

### 構成

<img width="679" alt="pattern-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/28770/a93c587d-8bb9-cbab-65a4-b6f0ac1c4530.png">

### 適用可能な環境

* 運用者の作業用マシンがJupyter Notebook(この説明ではDocker Engineを利用しその上にコンテナの形で起動)の動作要件を満たしている
* 操作対象のマシンに対して運用者の作業用マシンからSSHすることが許されている

自身のマシンからSSHしながらマシンを運用しているような場合は、最も単純にSSHをJupyter+Ansibleに置き換えることができるパターン。
しかしながら、運用者が複数いる場合は、Jupyter環境が複数異なる場所で起動することになり、バージョン等のコントロールが困難という問題がある。この問題は、**パターン2: 組織インフラ内Jupyter+既存マシン** で解消することができる。(しかしながら、インフラ内のJupyterマシンを運用するという仕事が追加される・・・)

### はじめかた

1. 運用者の作業用マシン(ローカル環境)にDocker Engineをインストール
2. ローカル環境 Docker EngineでLC4RI全部入りJupyterコンテナを起動
3. ローカル環境Jupyter Notebook環境のAnsibleから操作対象マシンを操作できるよう設定

## パターン2: インフラ内Jupyter+既存マシン

LC4RI実施可能なJupyter Notebook環境を、運用者のマシンではなく、操作対象のインフラ内に構築したマシンに用意する方法です。

### 構成

<img width="663" alt="pattern-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/28770/5ccfd371-001e-9f67-7bc6-e7771d5f7cc8.png">


### 適用可能な環境

* 操作対象マシンがいるネットワーク内に、Docker Engineが動作し、かつ操作対象のマシンにSSH可能なマシンを用意することができる
* 自身のマシンもしくは管理端末等からJupyter用マシンの8888番ポートに対してブラウザ経由でアクセス可能な経路を用意することができる

管理ネットワークがDMZを構成している場合など、操作対象のマシンが運用者のネットワークから分離されている場合にLC4RIを実践するためのパターン。
なお、複数人が操作を行う場合は、複数のJupyterサービスを起動し、Notebookだけ共有して環境を分割することで、操作対象マシンに接続する際のアカウントの共有を避けることができる。


### はじめかた

1. 操作対象インフラ内のJupyter Notebook用マシンにDocker Engineをインストール
2. インフラ内Jupyter NotebookマシンでLC4RI全部入りJupyterコンテナを起動
3. インフラ内Jupyter Notebook環境のAnsibleから操作対象マシンを操作できるよう設定

## パターン3: ローカルJupyter+パブリッククラウド

パターン1, パターン2は操作対象マシンは既にあることを前提としていましたが、このパターンではLC4RI環境からパブリッククラウドのコンソールを操作できるようにすることで、マシンの増減やネットワーク制御もJupyter Notebook上で記録を残しながら操作できるようにする方法です。

### 構成

![image.png](https://qiita-image-store.s3.amazonaws.com/0/28770/31ea804c-7c9b-d90f-13c5-6f81fdf22610.png)

### 適用可能な環境

* AWS等のコンソールへのアクセス権限を持っている
* コンソールアクセスに利用するネットワークとAWS等に作成した仮想マシンへのSSHに利用するネットワークが同一である(DirectConnect等、異なるネットワークへの切り替えを必要としない)

このネットワークを利用すべきといった制約はない(セキュリティポリシーなどの関係で、パブリッククラウドを使うな、など)場合に、パブリッククラウドを活用することで、複数のマシンを必要とするクラスタの構成などが手早くできる可能性がある。

### はじめかた

1. 運用者の作業用マシン(ローカル環境)にDocker Engineをインストール
2. ローカル環境 Docker EngineでLC4RI全部入りJupyterコンテナを起動
3. ローカル環境Jupyter Notebook環境にパブリッククラウド操作用ツール(この例ではAWS CLI)をインストール・設定


# 設定手順

各パターンの「はじめかた」の手順に関する説明です。

## Docker Engineのインストール

Docker社の公式ドキュメントの[Install Docker](https://docs.docker.com/engine/installation/)から、適切なパッケージを選んで、手順を実施してください。

## LC4RI全部入りJupyterコンテナの起動

この記事で紹介するNotebookが利用するツールを盛り込んだ「LC4RI用ツール全部入り」DockerイメージをDocker Hubから入手することができます。
あらかじめNotebookファイルを保存するためのディレクトリを準備しておき、以下のように`docker run`コマンドを実行してください。

```
$ docker run -d --name lcnotebook -v (Notebookを保存するためのディレクトリへのパス):/notebooks -p 8888:8888 niicloudoperation/notebook:latest
```

上記のコマンドを実行すると、Jupyter Notebookコンテナが起動されます。
以下のように`docker logs lcnotebook` を実行すると、tokenを含むURLが表示されますので、これをブラウザで開くことでLC4RI用ツール全部入りJupyter環境を利用することができます。(ホスト名は、Docker Engineが動作しているホストに合わせて読み替えてください。)

```
$ docker logs lcnotebook
[C 22:57:50.715 NotebookApp] 

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=24ce34ee9360160c1ecd7216a18f5b710d92bc5bxxxxxxxx
```

コンテナを停止・削除するときは、以下のコマンドを実行してください。

```
$ docker stop lcnotebook
$ docker rm lcnotebook
```

## Ansibleから操作対象マシンを操作できるよう設定

Jupyter Notebook環境のAnsibleから操作対象マシンを操作できるようにするには、SSHログインに関する設定情報をまとめて、Ansibleの設定ファイルとして記述する必要があります。

この手順自体を、LC4RIの手法を用いてNotebookにまとめてみました。以下のリンクを参照してみてください。

* [nbviewer: 既存マシンをAnsibleで操作可能にする](http://nbviewer.jupyter.org/github/yacchin1205/LC-sample-notebooks/blob/master/%E6%97%A2%E5%AD%98%E3%83%9E%E3%82%B7%E3%83%B3%E3%82%92Ansible%E3%81%A7%E6%93%8D%E4%BD%9C%E5%8F%AF%E8%83%BD%E3%81%AB%E3%81%99%E3%82%8B.ipynb)

> 上記リンクでは画像ファイルがリンク切れになってしまいます(nbviewer.jupyter.orgの制約？)ので、ご興味ある方は以下の手順で参照・実行してみてください。
>
> 1. 上記リンク先の右上のDownloadボタンでダウンロード
> 2. LC4RI用ツール全部入りJupyter環境にダウンロードした `既存マシンをAnsibleで操作可能にする.ipynb` をドラッグ＆ドロップしてインポート
> 3. LC4RI用ツール全部入りJupyter環境にインポートされた `既存マシンをAnsibleで操作可能にする` を開く

## Jupyter Notebook環境にAWS CLIをインストール・設定

Jupyter Notebook環境からパブリッククラウドを操作可能にする例として、AWS CLIのインストール例がNIIクラウドチームのリポジトリを挙げておきます。

* [nbviewer: AWS操作用ツールのインストール](http://nbviewer.jupyter.org/github/NII-cloud-operation/Jupyter-LC_docker/blob/master/sample-notebooks/02_AWS%E6%93%8D%E4%BD%9C%E7%94%A8%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB.ipynb)


# まとめ

LC4RIの構成方法とはじめかたを整理する試みをしてみましたが、まとめる中でやはり前提条件はまだまだ色々ありそうだと感じています。今回挙げたようなパターンが蓄積されてきて、網羅的に整理されてくると面白いなあ、という感じがしています。