今まで食わず嫌いをしてしまっていたAnsibleに、今更ながら1入門しました。

使う前に抱いていた印象と実際に使ってみた感想を並べてみて、最後に書いてみたPlaybookを載せます。 使う前はあまりいいイメージではなかったのですが、使ってみるとなかなか便利では……という使用感でした。

使う前に抱いていた印象

箇条書きで。

  • 小規模利用にはオーバースペックなのでは?
  • リモートに処理を流し込むだけなら、シェルスクリプトを標準入力経由でsshに流せばいいだけでは……
  • Playbookがシェルスクリプトを難しくしただけのラッパーに見えた
    • 「実際のコマンドは~だから、Playbookにはこう書いて~」みたいなことを考えるくらいなら直接シェルスクリプトを書いた方がシンプルでわかりやすいのでは。

実際に使ってみた感想

今回は「新規作成したVPSに初期セットアップをする」という用途でPlaybookを作成し、実行しました。 基本的に、シェルスクリプトで同じことをする場合との比較だと思ってください。

使用感を箇条書きで。

  • 小規模向きかと言うと微妙だけど普通に使える
    • 対象のホスト名を書いたファイルを用意しなくてはいけないのは若干面倒
      • とはいえ1ファイル作るだけ
    • localhost向けに実行することもできる
  • 再実行しやすい
    • 同じ設定を上書きしない作りになっていたり、回避する手段がちゃんと用意されていたりする2
      • 例えば lineinfile という、ファイルに行を追加する命令(?)を再実行した場合、内容が既に追加されていれば追記は行われない
      • "ifだらけ"現象になりにくいため、見通しがよくなる
  • aptgitなどよく使う命令(?)が用意されており、書き方を自然に統一できる
    • shellcommandは極力使わないほうがよさそう
      • ほぼ使わずにできるようになっているし、必要になったら自分の設計が怪しいかもというサインになりそう

実際に書いたPlaybook

VPS(Conoha)に作成したUbuntuへ、毎度やっている初期セットアップ作業をするPlaybookを書きました。

※ユーザー名とsshd_portは適当に変えてます

※セットアップ直後なのでrootで実行します

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
- hosts: all
  vars:
    - username: user
    - sshd_port: 12345
  vars_prompt:
    - name: password
      prompt: "Input user password"
      encrypt: sha512_crypt
      private: yes
      confirm: yes

  tasks:
    - name: Add user
      user:
        name: "{{ username }}"
        password: "{{ password }}"
        groups: sudo
        shell: /bin/bash

    - name: Add authorized_keys
      authorized_key:
        user: "{{ username }}"
        key: "{{ lookup('file', '.ssh/authorized_keys') }}"

    - name: SSHD settings
      lineinfile:
        dest: /etc/ssh/sshd_config
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
      with_items:
        - regexp: "^PasswordAuthentication"
          line: "PasswordAuthentication no"
        - regexp: "^ChallengeResponseAuthentication"
          line: "ChallengeResponseAuthentication no"
        - regexp: "^Port"
          line: "Port {{ sshd_port }}"

    - name: Restart sshd
      service:
        name: sshd
        state: restarted

    - name: Configure ufw default rules
      ufw:
        direction: "{{ item.direction }}"
        policy: "{{ item.policy }}"
      with_items:
        - direction: "incoming"
          policy: deny
        - direction: "outgoing"
          policy: allow

    - name: Configure ufw rules
      ufw:
        rule: "{{ item.rule }}"
        port: "{{ item.port }}"
        proto: tcp
      with_items:
        - rule: "limit"
          port: "{{ sshd_port }}"

    - name: Enable ufw logging
      ufw:
        logging: on

    - name: Enable ufw
      ufw:
        state: enabled

    - name: Restart ufw
      service:
        name: ufw
        state: restarted

作ってから5回くらい使ってますが便利ですね。

まとめ的な

以前「メンテナンスのことを考えるとシェルスクリプトよりAnsibleの方がいい」という言説を見かけたんですが、確かにその通りだなと感じました。

サーバの初期セットアップをする用途で考えると、 型のあるシェルスクリプト と言えるかもしれません。 >なんだか「型のあるシェルスクリプト」って感じはします。(イメージ— くんすと (@kunst1080) 2018年5月2日


食わず嫌いはいけませんね!


  1. Ansibleがリリースされたのは2012年、今年は2018年。
  2. “ちゃんと用意されている”というのは、”自分でやり方を考えたり、工夫したりしなくてもいい”というニュアンスです。