目標
Ansibleを使ってUbuntuの環境を最低限構築します. 構築する環境はだいたい下のような感じ.
- Git
- fish
- Docker
Ubuntu20.04はインストール済みということにします. Ubuntu20.04では最初からPython3.8がインストール済みなので新たにインストールする必要はありません.
Ansibleとは
Python製の構成管理自動化ツールです.
今回はローカルで個人利用のPCの初期設定に用いましたが,本来は多数のサーバを一括でセットアップしたりするのが目的のツールです. セットアップしたいPCにPythonさえ入れておけば管理サーバからセットアップすることができます. (Linuxはだいたい最初からPythonが入っている.)
また,複数回実行しても結果が同じになるという冪等性が担保されるように作られているそうです.
冪等性についてはこちらが分かりやすいです.
Ansibleの冪等性について深く考えたことはありますか? - ぽよメモ
インストール
# Ubuntu $ sudo apt update $ sudo apt install ansible # Mac $ brew install ansible
バージョン確認.
$ ansible --version ansible 2.9.6 config file = /etc/ansible/ansible.cfg configured module search path = ['/home/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3/dist-packages/ansible executable location = /usr/bin/ansible python version = 3.8.2 (default, Apr 27 2020, 15:53:34) [GCC 9.3.0]
ここからは失敗談なので興味がない人は飛ばしてください.
Ansibleのインストール— Ansibleのドキュメントの通り下の方法でインストールすると途中でエラーが出ました.
$ sudo apt update $ sudo apt install software-properties-common $ sudo apt-add-repository --yes --update ppa:ansible/ansible $ sudo apt install ansible
エラー箇所
$ sudo apt-add-repository --yes --update ppa:ansible/ansible # エラー文 Err:12 http://ppa.launchpad.net/ansible/ansible/ubuntu focal Release 404 Not Found [IP: 2001:67c:1560:8008::15 80] Reading package lists... Done E: The repository 'http://ppa.launchpad.net/ansible/ansible/ubuntu focal Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.
なので,追加したPPAを削除して,普通にapt installしたらインストールできました.
$ sudo rm /etc/apt/sources.list.d/ansible-ubuntu-ansible-focal.list
$ sudo apt install ansible
Ubnutu20.04ではデフォルトでAnsibleのリポジトリを含むPPAを持っているため,必要ないという感じでしょうか.
Ansibleの構成
今回はシンプルに以下のような構成にしました.
$ tree . ├── ansible.cfg ├── hosts ├── roles │ ├── apt_packages │ │ └── tasks │ │ └── main.yml │ └── fish │ └── tasks │ └── main.yml └── ubuntu-provisioning.yml
Ansible用のディレクトリを作成しそこで作業しました.
$ mkdir ansible $ cd ansible
設定ファイル(ansible.cfg)の作成
ansible.cfgというファイルに書き込みます.ansible.cfgには優先順位があるので,優先順位が高いカレントディレクトリに作成しました.
GitHubに上がっている公式の設定例を落としてきて置きました.
wget https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg
必要に応じてコメントアウトを外せばいいと思います(僕は設定については変更していないのでデフォルトのままですが...…).
インベントリ(hosts)の作成
インベントリにはAnsible実行する対象を記述します. 今回は自身に対するので127.0.0.1を指定しています.
[localhost] 127.0.0.1
プレイブック(ubuntu-provisioning.yml)の作成
プレイブックはどこに何を実行するか記述します.
--- - hosts: localhost connection: local gather_facts: no roles: - apt_packages - fish
hostsのlocalhostはインベントリで設定したもの,ローカルのセットアップなのでconnectionはlocalです. gather_factsはyesにするとシステム変数がとってこれるそうです. またrolesには次に記述するtaskを持つディレクトリ名を記述します.
Roleの作成
roles以下の部分を作成します. まずはこのようにディレクトリを作成します.
$ tree . ├── ansible.cfg ├── hosts ├── roles │ ├── apt_packages │ │ └── tasks │ │ └── main.yml │ └── fish │ └── tasks │ └── main.yml └── ubuntu-provisioning.yml
必要なパッケージのインストール
./roles/apt_packages/tasks/main.yamlに記述します.
--- - name: Upgrade all package apt: update_cache: yes upgrade: yes - name: Install apt packages apt: name: - vim - curl - git - docker-compose - fonts-powerline - tree - tmux state: latest
nameは自由につけることができます. aptなどはモジュールと呼ばれるもので,公式のモジュールを利用することで冪等性が担保されるそうです. モジュールはかなり種類が多いらしいので必要なモジュールを調べるのが大変そうだなと思いました.
fishの設定
./roles/fish/tasks/main.yamlに記述します.
--- - name: Upgrade all package apt: update_cache: yes - name: Install packages apt: name: - fish state: latest - name: Exec fish after bash lineinfile: dest: /home/username/.bashrc line: exec fish - name: Make function directory file: path: /home/username/.config/fish/functions state: directory - name: Install fisher get_url: url: https://git.io/fisher dest: /home/username/.config/fish/functions/fisher.fish - name: Install fisher theme shell: fish -lc "fisher add {{ item }}" args: creates: /home/username/.config/fisher/github.com/{{ item }} with_items: - oh-my-fish/theme-bobthefish
実行
この記事のために再実行した結果なので,初回の実行とは表示が異なりますが下のような出力が出ました.
$ sudo ansible-playbook -i hosts ubuntu-provisioning.yml --ask-become-pass BECOME password: PLAY [localhost] ***************************************************************************** TASK [apt_packages : Upgrade all package] **************************************************** [WARNING]: The value True (type bool) in a string field was converted to 'True' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change. ok: [127.0.0.1] TASK [apt_packages : Install apt packages] *************************************************** ok: [127.0.0.1] TASK [fish : Upgrade all package] ************************************************************ changed: [127.0.0.1] TASK [fish : Install packages] *************************************************************** ok: [127.0.0.1] TASK [fish : Exec fish after bash] *********************************************************** ok: [127.0.0.1] TASK [fish : Make function directory] ******************************************************** ok: [127.0.0.1] TASK [fish : Install fisher] ***************************************************************** ok: [127.0.0.1] TASK [fish : Install fisher theme] *********************************************************** ok: [127.0.0.1] => (item=oh-my-fish/theme-bobthefish) PLAY RECAP *********************************************************************************** 127.0.0.1 : ok=8 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
最後に
本当はサーバをセットアップする感じでMacからansibleを実行したかったんですが,接続がうまく行きませんでした. SlackとかVSCodeもsnapでインストールしたかったのですが,相変わらず日本語に対応していなさそうなので諦めました. 今回はAnsibleのことを色々調べていて疲れてしまったので,シンプルなことだけしましたが分かったような気になれたので良かったです.
今後何かでUbuntuを入れ直したりしたときに,ちゃんと使えればいいなぁという感じです. 正直Ansibleに詳しい方からするとツッコミどころ満載な気がしますが最後まで読んでいただきありがとうざいます.