Ubuntu 20.04にErlang 24.0.1とElixir 1.12.0-otp-24をインストールする

# はじめに
- [Elixir](https://elixir-lang.org/) 楽しんでいますか:bangbang::bangbang::bangbang:
- 「[Graphing support via VegaLite has arrived to Livebook! をイゴかしてみる(Elixir)](https://qiita.com/torifukukaiou/items/d9813aad1d3f5790b9ae)」という記事を書くにあたり、[Time4VPS](https://www.time4vps.com/)というVPS（Virtual Private Server）に`Elixir 1.12.0-otp-24`をインストールしたくなりました
- いっつもこういうときひとつひとつコマンドを手打ちでやっていました
- メモのようなものは残しているのですが試行錯誤した結果を記録するのを忘れるといったことがよくありました
- これをいい加減どうにかしたいとおもいました
- [Docker](https://www.docker.com/)も選択肢にあがりますが、今回は[ansible](https://docs.ansible.com/ansible/latest/index.html)でやってみようとおもいます[^1]

## 環境
- Time4VPS [Container VPS](https://www.time4vps.com/container-vps/)
    - C2 Plan
        - 2.99 EUR/mo
    - RAM 2GB
    - Storage 20GB
- Ubuntu 20.04.1 LTS (GNU/Linux 4.4.0 x86_64)

```
$ uname -a
Linux 3clr.c.time4vps.cloud 4.4.0 #1 SMP Tue Aug 25 11:59:26 MSK 2020 x86_64 x86_64 x86_64 GNU/Linux
```

## 参考にした記事
- [IoT開発フレームワーク『Nerves』のハンズオン環境をAnsibleで構築してみた](https://dev.classmethod.jp/articles/setup-nerves-handson-env-by-ansible/)
    - とても参考にしました
    - ありがとうございます :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5:
- [Elixir](https://elixir-lang.org/)のバージョン切り替えに定評のある[asdf](https://asdf-vm.com/#/)を使います

# playbook.yml 

```yml:playbook.yml 
---
- hosts: all
  remote_user: "{{ user }}"
  tasks:
    - name: install packages
      become: true
      apt:
        name:
        - build-essential
        - autoconf
        - m4
        - libncurses5-dev
        - libwxgtk-webview3.0-gtk3-dev
        - libgl1-mesa-dev
        - libglu1-mesa-dev
        - libpng-dev
        - libssh-dev
        - unixodbc-dev
        - xsltproc
        - fop
        - libxml2-utils
        - libncurses-dev
        - openjdk-11-jdk
        - curl
        - git
        update_cache: yes
    - name: git clone asdf
      git:
        repo: https://github.com/asdf-vm/asdf.git
        dest:  /home/{{ user }}/.asdf
        depth: 1
        version: "{{ asdf }}"
    - name: set env vars
      lineinfile:
        dest: /home/{{ user }}/.bashrc
        state: present
        line: "{{ item.line }}"
      with_items:
      - line: . $HOME/.asdf/completions/asdf.bash
        regexp: '^ \. \$HOME/\.asdf/completions/asdf\.bash'
      - line: . $HOME/.asdf/asdf.sh
        regexp: '^ \. \$HOME/\.asdf/asdf\.sh'
    - name: source ~/.bashrc
      ansible.builtin.shell:
      args:
        cmd: 'source /home/{{ user }}/.bashrc'
        chdir: '/home/{{ user }}'
        executable: /bin/bash
    - name: asdf plugin add erlang
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf plugin add erlang'
        chdir: '/home/{{ user }}/'
      ignore_errors: yes
      register: result
    - name: show result
      debug:
        var: result
    - name: asdf plugin add elixir
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf plugin add elixir'
        chdir: '/home/{{ user }}/'
      ignore_errors: yes
      register: result
    - name: show result
      debug:
        var: result
    - name: asdf install erlang
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf install erlang {{ erlang }}'
        chdir: '/home/{{ user }}/'
      ignore_errors: yes
      register: result
    - name: show result
      debug:
        var: result
    - name: asdf install elixir
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf install elixir {{ elixir }}'
        chdir: '/home/{{ user }}/'
      ignore_errors: yes
      register: result
    - name: show result
      debug:
        var: result
    - name: asdf global erlang
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf global erlang {{ erlang }}'
        chdir: '/home/{{ user }}/'
    - name: asdf global elixir
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf global elixir {{ elixir }}'
        chdir: '/home/{{ user }}/'
    - name: asdf reshim erlang
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf reshim erlang {{ erlang }}'
        chdir: '/home/{{ user }}/'
    - name: asdf reshim elixir
      ansible.builtin.shell:
      args:
        cmd: '/home/{{ user }}/.asdf/bin/asdf reshim elixir {{ elixir }}'
        chdir: '/home/{{ user }}/'
```

- `ignore_errors`って入れているところは、[ansible](https://docs.ansible.com/ansible/latest/index.html)で整理しなおしてみるにあたってやっぱり試行錯誤した部分がありまして、`asdf`関係のコマンドですでに実行済みのものがあった場合に`Already installed`的なメッセージで`playbook.yml`の実行をそこでやめてしまうことがあったのでまあ無視でいいやということにしました
    - もっといいやり方がありましたらぜひ教えてくださいませ :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5: 
- `apt`でインストールしているものは以下を参考にしました
    - https://github.com/asdf-vm/asdf-erlang/blob/f850959c5f5deeac84544eee0d9e420728144211/README.md
    - @MzRyuKa さんの[asdfでErlangをインストールする場合の留意点](https://qiita.com/MzRyuKa/items/8762ea006ca446e6e422)
- 最終確認としてOS再インストールしてまっさらな状態から後述の実行コマンドが最後まで通って、`IEx`を起動できましたのできっとだいじょうvでしょう

# vars.yml 例
```yml:vars.yml
---
user: deploy
asdf: v0.8.1
erlang: 24.0.1
elixir: 1.12.0-otp-24
```

- [asdf](https://asdf-vm.com/#/)のバージョン(tag)は、https://asdf-vm.com/#/core-manage-asdf?id=asdf をみてきめました
- [Erlang](https://www.erlang.org/)や[Elixir](https://elixir-lang.org/)のバージョンは、[elixir.jp](https://join.slack.com/t/elixirjp/shared_invite/zt-ae8m5bad-WW69GH1w4iuafm1tKNgd~w) SlackやTwitterかなにかでみた情報できめました
- 2021/05/23現在はこれが最新です
- 実施されるときには公式ページなどでバージョンをご確認ください


# inventory_file 例
```:inventory_file
[webservers]
176.223.134.64

[webservers:vars]
ansible_port=22
ansible_user=deploy
ansible_ssh_private_key_file=~/.ssh/id_rsa
```

- IPアドレスやsshの設定はご自身の環境にあわせてください

# 実行
```
$ ansible-playbook -i inventory_file playbook.yml --ask-become-pass -e @vars.yml
```

- `sudo`するときにパスワードが必要な構成になっているので、`--ask-become-pass`でパスワードを渡しています
- `TASK [asdf install erlang]`([Erlang](https://www.erlang.org/)のインストール)がなかなかおわりませんが気長に :coffee: でも飲んで待ちましょう(気持ち1h以上かかったかな)

```
ok: [176.223.134.64] => {
    "result": {
        "changed": true,
        "cmd": "/home/sammy/.asdf/bin/asdf install erlang 24.0.1",
        "delta": "1:06:23.888921",
        "end": "2021-05-23 11:10:28.723041",
        "failed": false,
        "rc": 0,
        "start": "2021-05-23 10:04:04.834120",
        "stderr": "Downloading kerl...\n  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100   122  100   122    0     0    417      0 --:--:-- --:--:-- --:--:--   416\n\r100  491k    0  491k    0     0   398k      0 --:--:--  0:00:01 --:--:--  398k\r100 1093k    0 1093k    0     0   496k      0 --:--:--  0:00:02 --:--:--  620k\r100 2001k    0 2001k    0     0   625k      0 --:--:--  0:00:03 --:--:--  767k\r100 3080k    0 3080k    0     0   733k      0 --:--:--  0:00:04 --:--:--  872k\r100 3947k    0 3947k    0     0   757k      0 --:--:--  0:00:05 --:--:--  868k\r100 4686k    0 4686k    0     0   754k      0 --:--:--  0:00:06 --:--:--  843k\r100 5435k    0 5435k    0     0   754k      0 --:--:--  0:00:07 --:--:--  868k\r100 6220k    0 6220k    0     0   758k      0 --:--:--  0:00:08 --:--:--  843k\r100 7356k    0 7356k    0     0   799k      0 --:--:--  0:00:09 --:--:--  854k\r100 8506k    0 8506k    0     0   832k      0 --:--:--  0:00:10 --:--:--  910k\r100 9401k    0 9401k    0     0   839k      0 --:--:--  0:00:11 --:--:--  944k\r100 10.0M    0 10.0M    0     0   842k      0 --:--:--  0:00:12 --:--:--  970k\r100 11.3M    0 11.3M    0     0   881k      0 --:--:--  0:00:13 --:--:-- 1082k\r100 12.3M    0 12.3M    0     0   892k      0 --:--:--  0:00:14 --:--:-- 1063k\r100 13.5M    0 13.5M    0     0   912k      0 --:--:--  0:00:15 --:--:-- 1076k\r100 14.4M    0 14.4M    0     0   914k      0 --:--:--  0:00:16 --:--:-- 1082k\r100 15.3M    0 15.3M    0     0   914k      0 --:--:--  0:00:17 --:--:-- 1090k\r100 16.4M    0 16.4M    0     0   922k      0 --:--:--  0:00:18 --:--:-- 1032k\r100 17.5M    0 17.5M    0     0   936k      0 --:--:--  0:00:19 --:--:-- 1062k\r100 18.8M    0 18.8M    0     0   954k      0 --:--:--  0:00:20 --:--:-- 1081k\r100 19.9M    0 19.9M    0     0   962k      0 --:--:--  0:00:21 --:--:-- 1118k\r100 21.4M    0 21.4M    0     0   989k      0 --:--:--  0:00:22 --:--:-- 1246k\r100 22.8M    0 22.8M    0     0  1010k      0 --:--:--  0:00:23 --:--:-- 1327k\r100 24.4M    0 24.4M    0     0  1035k      0 --:--:--  0:00:24 --:--:-- 1413k\r100 26.2M    0 26.2M    0     0  1066k      0 --:--:--  0:00:25 --:--:-- 1516k\r100 28.3M    0 28.3M    0     0  1108k      0 --:--:--  0:00:26 --:--:-- 1726k\r100 30.7M    0 30.7M    0     0  1156k      0 --:--:--  0:00:27 --:--:-- 1898k\r100 33.1M    0 33.1M    0     0  1204k      0 --:--:--  0:00:28 --:--:-- 2105k\r100 36.2M    0 36.2M    0     0  1271k      0 --:--:--  0:00:29 --:--:-- 2407k\r100 38.9M    0 38.9M    0     0  1320k      0 --:--:--  0:00:30 --:--:-- 2601k\r100 41.7M    0 41.7M    0     0  1370k      0 --:--:--  0:00:31 --:--:-- 2744k\r100 44.5M    0 44.5M    0     0  1416k      0 --:--:--  0:00:32 --:--:-- 2828k\r100 47.8M    0 47.8M    0     0  1477k      0 --:--:--  0:00:33 --:--:-- 3016k\r100 50.7M    0 50.7M    0     0  1518k      0 --:--:--  0:00:34 --:--:-- 2967k\r100 52.7M    0 52.7M    0     0  1535k      0 --:--:--  0:00:35 --:--:-- 2841k\r100 55.1M    0 55.1M    0     0  1559k      0 --:--:--  0:00:36 --:--:-- 2739k\r100 56.1M    0 56.1M    0     0  1571k      0 --:--:--  0:00:36 --:--:-- 2715k\nln: failed to create symbolic link './erl_call': File exists\n/home/sammy/.asdf/lib/commands/command-install.bash: line 200: asdf: command not found",
        "stderr_lines": [
            "Downloading kerl...",
            "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current",
            "                                 Dload  Upload   Total   Spent    Left  Speed",
            "",
            "  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0",
            "  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0",
            "100   122  100   122    0     0    417      0 --:--:-- --:--:-- --:--:--   416",
            "",
            "100  491k    0  491k    0     0   398k      0 --:--:--  0:00:01 --:--:--  398k",
            "100 1093k    0 1093k    0     0   496k      0 --:--:--  0:00:02 --:--:--  620k",
            "100 2001k    0 2001k    0     0   625k      0 --:--:--  0:00:03 --:--:--  767k",
            "100 3080k    0 3080k    0     0   733k      0 --:--:--  0:00:04 --:--:--  872k",
            "100 3947k    0 3947k    0     0   757k      0 --:--:--  0:00:05 --:--:--  868k",
            "100 4686k    0 4686k    0     0   754k      0 --:--:--  0:00:06 --:--:--  843k",
            "100 5435k    0 5435k    0     0   754k      0 --:--:--  0:00:07 --:--:--  868k",
            "100 6220k    0 6220k    0     0   758k      0 --:--:--  0:00:08 --:--:--  843k",
            "100 7356k    0 7356k    0     0   799k      0 --:--:--  0:00:09 --:--:--  854k",
            "100 8506k    0 8506k    0     0   832k      0 --:--:--  0:00:10 --:--:--  910k",
            "100 9401k    0 9401k    0     0   839k      0 --:--:--  0:00:11 --:--:--  944k",
            "100 10.0M    0 10.0M    0     0   842k      0 --:--:--  0:00:12 --:--:--  970k",
            "100 11.3M    0 11.3M    0     0   881k      0 --:--:--  0:00:13 --:--:-- 1082k",
            "100 12.3M    0 12.3M    0     0   892k      0 --:--:--  0:00:14 --:--:-- 1063k",
            "100 13.5M    0 13.5M    0     0   912k      0 --:--:--  0:00:15 --:--:-- 1076k",
            "100 14.4M    0 14.4M    0     0   914k      0 --:--:--  0:00:16 --:--:-- 1082k",
            "100 15.3M    0 15.3M    0     0   914k      0 --:--:--  0:00:17 --:--:-- 1090k",
            "100 16.4M    0 16.4M    0     0   922k      0 --:--:--  0:00:18 --:--:-- 1032k",
            "100 17.5M    0 17.5M    0     0   936k      0 --:--:--  0:00:19 --:--:-- 1062k",
            "100 18.8M    0 18.8M    0     0   954k      0 --:--:--  0:00:20 --:--:-- 1081k",
            "100 19.9M    0 19.9M    0     0   962k      0 --:--:--  0:00:21 --:--:-- 1118k",
            "100 21.4M    0 21.4M    0     0   989k      0 --:--:--  0:00:22 --:--:-- 1246k",
            "100 22.8M    0 22.8M    0     0  1010k      0 --:--:--  0:00:23 --:--:-- 1327k",
            "100 24.4M    0 24.4M    0     0  1035k      0 --:--:--  0:00:24 --:--:-- 1413k",
            "100 26.2M    0 26.2M    0     0  1066k      0 --:--:--  0:00:25 --:--:-- 1516k",
            "100 28.3M    0 28.3M    0     0  1108k      0 --:--:--  0:00:26 --:--:-- 1726k",
            "100 30.7M    0 30.7M    0     0  1156k      0 --:--:--  0:00:27 --:--:-- 1898k",
            "100 33.1M    0 33.1M    0     0  1204k      0 --:--:--  0:00:28 --:--:-- 2105k",
            "100 36.2M    0 36.2M    0     0  1271k      0 --:--:--  0:00:29 --:--:-- 2407k",
            "100 38.9M    0 38.9M    0     0  1320k      0 --:--:--  0:00:30 --:--:-- 2601k",
            "100 41.7M    0 41.7M    0     0  1370k      0 --:--:--  0:00:31 --:--:-- 2744k",
            "100 44.5M    0 44.5M    0     0  1416k      0 --:--:--  0:00:32 --:--:-- 2828k",
            "100 47.8M    0 47.8M    0     0  1477k      0 --:--:--  0:00:33 --:--:-- 3016k",
            "100 50.7M    0 50.7M    0     0  1518k      0 --:--:--  0:00:34 --:--:-- 2967k",
            "100 52.7M    0 52.7M    0     0  1535k      0 --:--:--  0:00:35 --:--:-- 2841k",
            "100 55.1M    0 55.1M    0     0  1559k      0 --:--:--  0:00:36 --:--:-- 2739k",
            "100 56.1M    0 56.1M    0     0  1571k      0 --:--:--  0:00:36 --:--:-- 2715k",
            "ln: failed to create symbolic link './erl_call': File exists",
            "/home/sammy/.asdf/lib/commands/command-install.bash: line 200: asdf: command not found"
        ],
        "stdout": "asdf_24.0.1 is not a kerl-managed Erlang/OTP installation\nNo build named asdf_24.0.1\nDownloading OTP-24.0.1.tar.gz to /home/sammy/.asdf/plugins/erlang/kerl-home/archives...\nExtracting source code\nBuilding Erlang/OTP 24.0.1 (asdf_24.0.1), please wait...\nErlang/OTP 24.0.1 (asdf_24.0.1) has been successfully built\nInstalling Erlang/OTP 24.0.1 (asdf_24.0.1) in /home/sammy/.asdf/installs/erlang/24.0.1...\nYou can activate this installation running the following command:\n. /home/sammy/.asdf/installs/erlang/24.0.1/activate\nLater on, you can leave the installation typing:\nkerl_deactivate\nCleaning up compilation products for \nCleaned up compilation products for  under /home/sammy/.asdf/plugins/erlang/kerl-home/builds\n\nErlang 24.0.1 has been installed. Activate globally with:\n\n    asdf global erlang 24.0.1\n\nActivate locally in the current folder with:\n\n    asdf local erlang 24.0.1",
        "stdout_lines": [
            "asdf_24.0.1 is not a kerl-managed Erlang/OTP installation",
            "No build named asdf_24.0.1",
            "Downloading OTP-24.0.1.tar.gz to /home/sammy/.asdf/plugins/erlang/kerl-home/archives...",
            "Extracting source code",
            "Building Erlang/OTP 24.0.1 (asdf_24.0.1), please wait...",
            "Erlang/OTP 24.0.1 (asdf_24.0.1) has been successfully built",
            "Installing Erlang/OTP 24.0.1 (asdf_24.0.1) in /home/sammy/.asdf/installs/erlang/24.0.1...",
            "You can activate this installation running the following command:",
            ". /home/sammy/.asdf/installs/erlang/24.0.1/activate",
            "Later on, you can leave the installation typing:",
            "kerl_deactivate",
            "Cleaning up compilation products for ",
            "Cleaned up compilation products for  under /home/sammy/.asdf/plugins/erlang/kerl-home/builds",
            "",
            "Erlang 24.0.1 has been installed. Activate globally with:",
            "",
            "    asdf global erlang 24.0.1",
            "",
            "Activate locally in the current folder with:",
            "",
            "    asdf local erlang 24.0.1"
        ]
    }
}
```
- 必要なパッケージのインストールのところは適当にやってしまっているので**過**はあるかもしれませんが、ログを見る限り、Ubuntu 20.04 x Erlang 24.0.1に対して**不足**はないようです

# Wrapping Up :lgtm::lgtm::lgtm::lgtm:
- Enjoy [Elixir](https://elixir-lang.org/) :bangbang::bangbang::bangbang:
- 「[Graphing support via VegaLite has arrived to Livebook! をイゴかしてみる(Elixir)](https://qiita.com/torifukukaiou/items/d9813aad1d3f5790b9ae)」という記事を書くにあたり、デモ環境を公開しようと[ansible](https://docs.ansible.com/ansible/latest/index.html)に手を出してしまい、結果[ansible](https://docs.ansible.com/ansible/latest/index.html)と格闘することとなりましたがいい経験だとおもっています
- 放っておけば出来上がるというのはとっても素敵です!!!



[^1]: [ansible](https://docs.ansible.com/ansible/latest/index.html)にした理由はですね、Time4VPSのお値段がお得なContainer VPSだと[Docker](https://www.docker.com/)が動かないんですよ、ゴニョゴニョともっともらしい理由を挙げようとおもいました。で、公式の見解を改めて確認してみると、[We support Docker on our Linux VPS and Container VPS (ordered after 2020-01-10). Tutorial about how to set it up can be found on our Community Forum.](https://www.time4vps.com/knowledgebase/can-i-run-docker-on-my-server/)なんと、私がもっていた情報は古く、`2020-01-10`以降は[Container VPS](https://www.time4vps.com/container-vps/)でも[Docker](https://www.docker.com/)が使えるようになっていたようです。これに気づいたのはいままさにこの記事を書いている最中でして、もういまさら後戻りはいたしません。