LoginSignup
14
11

More than 5 years have passed since last update.

Ansibleの基本

Last updated at Posted at 2018-02-28

前回環境ができたところで、改めて公式ドキュメントからAnsibleに関するもろもろまとめ。

前提

  • 2018/02/28時点の情報つまりAnsible v2.4
  • 以降のリンクは最新版(latest)への参照であり、また正式なレビューも受けていないため、本記事と内容が異なる場合は参照先が真
  • deprecatedなものは記載しない

コマンドリファレンス

まずはよく使う(であろう)コマンドから。

ansible

ホスト(セット)に対し、シングルタスク(playbook)を実行するコマンド。
単発で「リモートでなにか実行(doing ‘remote things’)」する。

実行例(Windowsサーバ上にフォルダを作成する)
$ ansible windows -i /etc/ansible/hosts -m win_file -a "path=C:\\\test state=directory"
実行例(pingモジュールで疎通確認する)
$ ansible windows -m ping
  • 最初の引数("windows")はインベントリのグループ名("all"を指定すると全部、公式マニュアル上は"host-pattern")
  • -iでインベントリファイル(デフォルトは"/etc/ansible/hosts")を指定
  • -mで使うモジュール(詳細後述)を指定
  • -aでモジュールへの引数(argument)を指定

補足:インベントリファイル

そのままだが、管理対象ホストのリストを記載したファイル。[groupname]でセクション化することで、ホストをグルーピング可。

inventory
[groupname]
10.1.1.1
hostname.mydomain.com

[hogeWebServers]
www1.hogehoge.com
www2.hogehoge.com
www3.hogehoge.com

ansible-playbook

こちらは"playbook"(後述)を作成して複数タスクを実行するコマンド。こいつこそがAnsibleの真骨頂(のはず)。

実行例
$ ansible-playbook playbook.yml
  • ほとんどの設定(実行サーバ等)はplaybook自体に書くので、実行時は割りとシンプル
  • -C or --checkをオプション指定すれば実際の変更操作は行わず、起こりうる変更を予測する(try to predict some of the changes that may occur)。

ansible-vault

YAMLファイルを暗号化したり複合化したりするユーティリティ。vaultは地下金庫(Harry Potterにも出てきましたね)。Ansibleのデータファイル(/etc/ansible/group_vars,host_vars下)中にパスワードなどのセンシティブな情報を書き込んだら暗号化しておきましょう。

実行例
$ ansible-vault encrypt /etc/ansible/group_vars/windows.yml
  • 暗号化したらansibleansible-playbook実行時に--ask-vault-passオプションをつけるなりしないと、当然動かない
  • 第一引数にcreateを指定するとエディタが開いて保存時に暗号化

ansible-galaxy

すごい名前。インターネット接続前提(または自分の共有リポジトリ)のようなので、今回は対象外。
とりあえずロール(リポジトリを管理する上での役割と推測)を管理するためのユーティリティらしい。

ansible-console

AnsibleのREPL(Read-eval-print loop)なコンソールユーティリティ。

$ ansible-console hogeWebServers
-m ping
-m ping

ansible-config

Ansibleの設定周りを表示するコマンド。

実行例
$ ansible-config list
$ ansible-config dump
$ ansible-config view
  • ANSIBLE_CONFIG環境変数でcfgファイルを指定(/etc/ansible/ansible.cfg overrided by ~/.ansible.cfg)
  • または-c or --configオプションでオーバーライド

ansible-doc

Ansibleプラグインのドキュメントを表示するユーティリティ。

実行例
$ ansible-doc -m ping

ansible-inventory

インベントリを表示するユーティリティ。

実行例
$ ansible-inventory --graph all
$ ansible-inventory --list all

ansible-pull

"playbook"をリポジトリからダウンロードしてきて実行するユーティリティ。

モジュール

モジュールとは

簡単に言えば、AnsibleのコントロールマシンからOSネイティブコマンドを実行せずとも、モジュールと引数によってなんらかの処理をしてくれる。タスク・プラグイン、ライブラリ・プラグインとも呼ばれる。APIのようなもの。
もちろん、自作のモジュールを開発することもできる(腕があれば)。

概要

リンク先のほぼ翻訳です。

モジュールを使った実行例
$ ansible webservers -m service -a "name=httpd state=started"
$ ansible webservers -m ping

-mでモジュールを指定し、-aでモジュールへの引数を渡す。ほとんどのモジュールは"key=value"型で引数を渡し、複数あるときはスペースで区切る。"ping"のように引数が不要なモジュールもある。
これを"playbook"にすると、

- name: start the webservers
 service:
   name: httpd
   state: started

のようになる。

モジュールを使った実行例2
$ ansible webservers -m command -a "/sbin/reboot -t now"

これを"playbook"にすると、

- name: reboot the webservers
 action: command /sbin/reboot -t now

これはplaybookの解説によれば古い書き方で、次のように短く書くのがモダンなやり方。、

- name: reboot the webservers
 command: /sbin/reboot -t now

自分でモジュールを書くようなことでもないかぎりあまり気にしなくてもいいけど、モジュールはJSONフォーマットのレスポンスを返す。
モジュールは冪等性を持つべき(should be idempotent)で、実行前に状態を確認して、既に最終形になっているなら、なにもしないほうがいい(should avoid making any changes)。
個別の詳細は実際に使うときになって調べることにしますが、どんなものがあるかくらいは目を通しておいてよさそうです。

あとはサードパーティ製のモジュールもあったりなかったりだとか。

YAML Syntax

既にちょこちょこと出てきている"playbook"はYAML形式で記載します。HTMLに対するmarkdownのようなもので、XMLやJSONに比べて人間に優しい形式だと主張していますが、実際のところどうなんでしょうね。

リストとディクショナリ

AnsibleではほぼすべてのYAMLファイルはリストで始まります。リスト内の各項目はkey/valueのペアで、一般的にハッシュとかディクショナリと呼ばれるものです。
YAMLは"---"で開始と終端を表すことができます。

リスト内のすべての項目は同じインデントレベルで、行頭を"- "(a dash + a space)にします。

---
# A list
hogeList:
   - listItem1
   - listItem2
   - listItem3
---

ディクショナリは"key: value"で表します(コロンの後ろのスペース1個は必須)。

---
# A dictionary
hogeDict:
   name: hogename
   attr: hogeattr
   value: hogevalue
---

リストもディクショナリも短縮形で書けます。

---
hogeList: ['listItem1', 'listItem2', 'listItem3']
hogeDict: {name: hogename, attr: hogeattr, value: hogevalue}
---

複数行にまたがる場合の指示子

複数行をみたまま表示させるか(HTMLでいうところのpre的な)、空行や改行を無視するかを指定する場合、それぞれ"|"と">"を使用します。

# みたままバージョン
asYouCanSee: |
   hogehoge
   the second line
   the third line

# 改行等無視バージョン
ignoreLineBreaks: >
   hogehoge
   hogehoge
   hogehoge

注意点

コロンが値にある場合は注意が必要です。

test: this is test: which is intended to be meaningless

drive: c:

このままだとシンタックスエラーになりますが、それぞれ'"'(ダブルクォート)で括ることで回避できます。

test: "this is test: which is intended to be meaningless"

drive: "c:"

ただし、クォートが不要なケースも存在します(なぜOKなのか言及されていないので詳細不明)。

windows_path: c:\windows

さらに、Ansibleでは"{{ var }}"という形式で変数を保存する一方、YAMLパーサはそれをディクショナリのワンライナー型と解釈するため、この場合もダブルクォートする必要があります。
その他、クォートするべき事項をまとめます。

hoge: "{{ var }}"
hoge2: "{{ basedir }}/hoge/geho"   # 固定文字列を含む場合は全体をクォート
hoge3: "{{ basedir }}\\hoge\\geho" # バックスラッシュも特殊文字
hoge4: "text which includes white spaces all must be quoted" # スペースを含む文字列も全体をクォート
hoge5: "yes"                       # booleanではなく文字列としての"yes"
hoge6: "1.0"                       # 浮動少数点数ではなく文字列としての"1.0"

Playbooks

最後にこれで締めます。
「モジュールが道具だとすれば、"playbooks"はマニュアル(操作手順)であり、インベントリは素材だ」とのことです(DIY好きな人にはわかりやすい例えなのかしら?)。
また、「とりあえず読んでおけ、これらがベストプラクティスだ!」とのことです。

まずは、ドキュメント中の例をそのまま記載します。

---
- hosts: webservers
 vars:
   http_port: 80
   max_clients: 200
 remote_user: root
 tasks:
 - name: ensure apache is at the latest version
   yum: name=httpd state=latest
 - name: write the apache config file
   template: src=/srv/httpd.j2 dest=/etc/httpd.conf
   notify:
   - restart apache
 - name: ensure apache is running (and enable it at boot)
   service: name=httpd state=started enabled=yes
 handlers:
   - name: restart apache
     service: name=httpd state=restarted
---

"key=value"となっている部分は、ディクショナリ形式でも書けます。

---
- hosts: webservers
 vars:
   http_port: 80
   max_clients: 200
 remote_user: root
 tasks:
 - name: ensure apache is at the latest version
   yum:
       name: httpd
       state: latest
 - name: write the apache config file
   template:
       src: /srv/httpd.j2
       dest: /etc/httpd.conf
   notify:
   - restart apache
 - name: ensure apache is running (and enable it at boot)
   service:
       name: httpd
       state: started
       enabled: yes
 handlers:
   - name: restart apache
     service:
         name: httpd
         state:restarted
---

さて、どちらが見やすい(あるいはメンテしやすい、Excel等から自動生成しやすい)ですかね。

hostsとremote_user

hosts

hosts行は1つ以上のグループやホストパターンのリストです。複数指定する場合はコロン":"で区切ります。
詳細はpatternの項に記載のとおり。

remote_user

説明の必要がないくらい文字通り、管理対象サーバで"play"を実行するユーザ名。
タスク単位で指定可能。

---
hosts: webservers
   remote_user: root
   tasks:
       - name: test
       ping:
       remote_user: ec2-user
---

become

sudoとかで権限昇格して実行する場合に指定。

---
hosts: webservers
   remote_user: ec2-user
   tasks:
       - name: test
       ping:
       become: root
       become_method: sudo
---

順序制御

複数のホストが対象となっている場合、"order"で実行順序を制御可能。

inventory
これがデフォルト。インベントリファイルに記載のとおりの順序で実行する。
reverse_inventory
インベントリファイルの逆順で実行する。
sorted
実行ホスト名のアルファベット降順で実行する。
reverse_sorted
実行ホスト名のアルファベット昇順で実行する。
shuffle
ランダムな順序で実行する。

タスクリスト

各"play"はタスクのリストを含められ、上から順に逐次実行します。エラーとなったホストは、以後スキップされます。失敗したら修正してやり直せとのことです(だからこそモジュールの冪等性が重要で、"playbook"内で使用するモジュールに冪等性があれば、"playbook"全体も冪等性があるでしょうと)。
すべてのタスクには名前("name")をつけましょう。結果のログに読みやすい形で出力されます。指定がない場合は、"action"とそっけなく表示されます。

変数

変数は"playbook"のvarsセクション、またはインベントリの"Host Variables"や"Group Variables"で宣言し、アクション行から"{{varName}}"で参照します。
変数名に使える文字種は、文字(a-zA-Z)とアンダースコア("_")と数字で、必ず文字から始まる必要があります。
YAMLではディクショナリも使えるので、"[]"や"."記法を使った参照も可能です。

---
- hosts: webservers
 vars:
   hoge1: hogevalue1
   hoge2: hogevalue2
 tasks:
   - name: test1
     command: /bin/echo {{ hoge1 }}
   - name: test2
     command: /bin/echo {{ hoge2 }}
   - name: test3
     command: /bin/echo vars.hoge1
   - name: test4
     command: /bin/echo vars['hoge2']

---

ハンドラ

例えば設定ファイルを変更するタスクを定義し、実際に変更があった場合にのみ特定のサービスを再起動させたいような場合、ハンドラを使うことで実現できるというお話。

---
- hosts: webservers
 tasks:
   - name: replace httpd.conf
     template: 
       src: template.conf
       dest: /etc/apache/conf/httpd.conf
     notify:
       - restart memcached
       - restart apache
 handlers:
     - name: restart memcached
       service: 
         name: memcached
         state: restarted
     - name: restart apache
       service:
         name: apache
         state: restarted
---

"nofify"に指定したリストがハンドラであり、"handlers"セクションに実際のアクションを記載します(普通の"tasks"とほぼ同じ)。"handlers"セクションのリストで、"name"にハンドラで定義した文字列を設定します(グローバルにユニークである必要)。
"handlers"アクションの実行順序は、"handlers"に定義した順番となり、"notify"した順番ではないことに注意が必要。
上記とは別の方法として、"handers"のタスクに"listen"を加えることでも実現可能。

---
 tasks:
  - name: replace httpd.conf
    template: src=template.conf dest=/etc/apache/conf/httpd.conf
    nofity: "restart web services"

 handlers:
     - name: restart memecached
       service: name=memcached state=restarted
       listen: "restart web services"
     - name: restart apache
       service: name=apache state=restarted
       listen: "restart web services"
---

また、全てのハンドラを実行したい場合、次のように"meta"行を入れることで実現可能です。

tasks:
 - shell: /bin/echo executing all handler tasks
 - meta: flush_handlers
 - shell: /bin/echo done

YAMLのシンタックスチェック

ansible-playbookコマンドに--syntax-checkオプションを付与することで確認可能です。また、実行対象ホストを確認するには`--list-hosts"オプションを付与します。

$ ansible-playbook playbook.yml --syntax-check
$ ansible-playbook playbook.yml --list-hosts

スクリーンショット 2018-02-28 19.33.17.png
ちなみにですが、日本語のフォルダ作成もいけました。

まだまだ奥というか底が深そうなAnsiblですが、必要に迫られたらもう少しお勉強したいところです。

14
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11