Edited at

Ansible2.xのexpectを使ってAnacondaをインストールする

More than 1 year has passed since last update.


背景

Anacondaの本家で提供されているLinux向けのインストーラーはBashで実行し対話式でインストール先を指定したり、パスの設定をしたりという動きになっています。

このAnacondaをAnsibleを使って複数サーバにインストールする時に、対話式であることがネックになります。以前はexpectを使って自力でなんとかしていたのですが、2.x系ではexpectのmoduleが追加されたそうなので、その動作確認も兼ねてAnsible2.x系を使ってAnacondaのインストールをしてみることにしました。


やりたいこと


  • SSHで接続できる対象サーバにAnacondaをインストールする

  • 全部Ansibleで完結させる


動作確認環境


  • ansibleを実行するサーバ


    • hostname:ansible-server

    • OS:Ubuntu14.04



  • 対象サーバ


    • hostname:test-server

    • OS:Ubuntu14.04



この2つのサーバをVagrantで用意して動作確認しました。


大雑把な流れ


  1. Ansibleの実行環境構築

  2. AnacondaのInstall時の挙動を確認

  3. 2の内容を踏まえてansible-playbookを作成

  4. ansible実行後の動作確認


1. Ansibleの実行環境構築

Ansibleはapt-getでインストールできますが、OSやバージョンによって2.x系をインストールする手順が少し異なります。

Ubuntu14.04の場合は以下のコマンドでインストールできます。


Ansibleインストールコマンド

$ sudo apt-get install software-properties-common

$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible

Ubuntu意外のOSでの導入方法はAnsibleのInstallationページを参照してください。

インストールが完了したら、以下のコマンドでバージョンを確認します。バージョンが返ってきたらインストール成功です。


Ansibleバージョン確認コマンド

$ ansible --version

ansible 2.1.1.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides


2. AnacondaのInstall時の挙動を確認

Anacondaのインストーラーを実際に実行して、どのようにそれぞれの質問に対応すべきか確認します。今回の動作確認では「Anaconda3-4.1.1-Linux-x86_64.sh」を利用しています。


Anacondaインストールコマンド

bash Anaconda3-4.1.1-Linux-x86_64.sh


実行すると、以下の部分で入力を求められます。


Anacondaインストール時の標準出力1


Welcome to Anaconda3 4.1.1 (by Continuum Analytics, Inc.)

In order to continue the installation process, please review the license
agreement.
Please, press ENTER to continue
>>>


expectのmoduleで挙動を定義するために、途中で入力を求められる部分が重要になります。

1つめの「>>>」は単にENTERすれば良いのでそれを覚えておきます。

処理をすすめるにENTERします。次に以下のところで入力を求められます。


Anacondaインストール時の標準出力2

(略)

Anaconda contains open source software packages from third parties. These
--More--

この部分はスペースでページ送りすれば良い部分です。

ただ、この部分もちゃんとexpectのmoduleに書いてあげる必要があります。

標準出力には「--More--」と表示されていますが、実はこれは「:」を置き換えられている(※)ので

「:」ときはスペースとして覚えておきます。

※:Macで試すと「:」が表示されるんです。Ubuntuだと気を利かせて置き換えてくれてる?

更にすすめると、以下のように同意するか求められます。


Anacondaインストール時の標準出力3

(略)

Do you approve the license terms? [yes|no]
>>>

ここではもちろん「yes」なので、 2つめの「>>>」はyesとおぼえておきます。

次にインストールパスの確認が来ます。


Anacondaインストール時の標準出力4

(略)

Anaconda3 will now be installed into this location:
/home/vagrant/anaconda3

- Press ENTER to confirm the location
- Press CTRL-C to abort the installation
- Or specify a different location below

[/home/vagrant/anaconda3] >>>


デフォルトでよければENTERで良いので 3つめの「>>>」はENTERと覚えておきます。

ENTERするとパッケージのインストールがスタートします。

パッケージのインストールが終わると、最後にパスを.bashrcに追加するか確認されます。


Anacondaインストール時の標準出力5

(略)

installation finished.
Do you wish the installer to prepend the Anaconda3 install location
to PATH in your /home/vagrant/.bashrc ? [yes|no]
[no] >>>

個人的には.bashrcに追加してほしいので 4つめの「>>>」はyesと覚えておきます。

これでインストールまでの挙動の確認は完了です。


3. 2の内容を踏まえてansible-playbookを作成

2で確認した挙動をもとにAnsibleのexpectのmoduleを記述します。

ansible-playbook全体はgithubにアップしているので、他の部分も確認したい場合はそちらを参照してください。

先程挙動を確認した結果をresponsesの下に書きます。


roles/anaconda/tasks/main.ymlの抜粋

- name: install anaconda3

expect:
chdir: "/home/{{ target_user }}"
command: "bash {{ anaconda_script }}"
timeout: 360
responses:
'>>>': '\n'
':': ' '
'>>>': 'yes'
'>>>': '\n'
'>>>': 'yes'
become: true
become_method: su
become_user: "{{ target_user }}"


Anacondaはgroup_vars/allで指定したtarget_userの権限でインストールしたいので以下のように記述しています。


roles/anaconda/tasks/main.ymlの抜粋

  become: true

become_method: su
become_user: "{{ target_user }}"

expectのmoduleを使うためにpexpectをpipでインストールしないといけないので

expectのmoduleよりも前に以下のような記述も必要です。


roles/anaconda/tasks/main.ymlの抜粋

- name: install pexpect by anaconda pip

pip: name=pexpect


4. ansible実行後の動作確認

無事すべてのansible-playbookが流れると以下のように出力されます。


Ansibleの実行結果

(略)

PLAY RECAP *********************************************************************
test-server : ok=5 changed=4 unreachable=0 failed=0

最後に動作確認として、test-serverにログインしてAnacondaがインストールされたかを確認します。


pythonコマンドの実行結果

vagrant@test-server:~$ python

Python 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 2 2016, 17:53:06)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

パスがしっかり通っていれば対象のユーザでpythonコマンドを打つと↑のような形になり、先程インストールしたAnaconda4.1.1のPythonが利用されていることが確認できます。


まとめ

今回はAnacondaのインストールのやり方をベースに説明しましたが、他にもAnacondaと同じようにBashで対話式にインストールするタイプのものは、同様の方法で対応することが可能だと思います。

もし、そういうものをAnsibleで入れる必要が出てきたら参考にしてみてください。

質問やコメントがあれば気軽にお願いします。