注目の記事

Ansibleのための YAML入門

2017.06.28

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。

いよいよ今週末にDeveloersIO 2017が開催されます。 当日はAnsibleのハンズオンを担当しますので、参加予定の方はよろしくお願いします。 早速ですが、予習用の資料を用意しました(笑)

Ansibleでは、設定ファイルなどのフォーマットとしてYAMLを利用します。 本エントリーでは、Ansibleを利用する時に役立つYAMLフォーマットについて解説します。

データ構造フォーマット

YAMLはJSONに似た、データ定義のためのフォーマットです。 プログラミング言語とは異なり、ロジックを記述するフォーマットではありません。 アプリケーションでのデータシリアライズに利用されるケースが多く、Ansibleでは設定データの定義ファイルとして利用されます。

ハッシュ

ハッシュは、キー: 値のデータ構造です。 プログラミング言語では、連想配列やMapなどと言われます。

キーとコロン(:)に続けて、対応する値を記述してください。 コロンの後に半角スペースをいれましょう。

db_user: master
db_password: Pass1234
db_name: wp

YAMLでは、文字列をダブルクォート(")やシングルクォート(')で囲む必要はありません。 ですが、エディタのハイライト機能を活用するために、ダブルクォートやシングルクォートで囲むことも可能です。

db_user: "master"
db_password: "Pass1234"
db_name: "wp"

ただし、Ansibleで変数展開を行う時、ダブルクォートで囲む必要があります(後述)。

リスト

リストは複数のデータを格納するデータ構造です。 プログラミング言語でも同様にリストや配列などと言われます。

配列は行頭にハイフン(-)をつけてください。 また、ハイフンの後に半角スペースをいれましょう。

- common
- mysql56-server
- apache24

ハッシュのリスト

Ansibleで多く見かける構造は、ハッシュのリストです。 ハッシュのリストを定義するには、リストとするためにハイフンを使い、さらにインデントを揃えてハッシュのキーを列挙します。

- name: "Suzuka Nakamoto"
  metal_name: "SU-METAL"
- name: "Yui Mizuno"
  metal_name: "YUI-METAL"
- name: "kikuchi moa"
  metal_name: "MOA-METAL"

YAMLではインデントの位置によりデータ構造が決まります。 原則として、インデントは2文字の半角スペースで記述してください。 4文字でも認識しますが、可読性がイマイチです。

ハッシュのネスト

ハッシュはネストできます。 Ansibleでは、タスク定義でよく使われるフォーマットでしょう。

- name: apache24 installed
  yum:
    name: httpd24
- name: httpd service started
  service:
    name: httpd
    state: started
    enabled: yes

Ansibleの場合、タスクリストのキーがモジュール名に対応します。 モジュールのパラメータをネストしたハッシュとして定義してください。

最初のタスクでは、yumモジュールのnameパラメータにhttpd24を指定します。 次のタスクでは、serviceモジュールのnameパラメータにhttpdを、stateパラメータにstartedを、enabledパラメータにyesを指定しています。

ここでもインデントが重要です。 インデントを間違えるとフォーマットエラーになったり、異なる構造と認識されたりします。

インデントを利用しないリストとハッシュ

YAMLではインデントを利用してデータ構造を記述します。 このため、行単位で変更を追いやすく、Gitなどのバージョン管理システムと相性が良いです。 しかし、YAMLでは、インライン記法(一行で書く記法)も用意されています。

空のリスト

空のリストはインライン記法で最も利用される状況です。 次のように[]で記述します。

- hosts: wordpress-servers
  roles: []

なお、空のリストを記述したい場合、インデントを利用した記法は利用できません。

インラインのリスト

インラインのリストは、[]の中に要素をカンマ区切りで列挙します。

- hosts: wordpress-servers
  roles: ["common", "mysql56-server"]

バージョン管理で差分を認識しにくいため、Ansibleではあまり利用しません。

インラインのハッシュ

インラインのハッシュは、{}の中にキーと値をカンマ区切りで列挙します。

  with_items:
    - { regexp: "^define\\('DB_NAME'.+$", replace: "define('DB_NAME', '{{ db_name }}');"}
    - { regexp: "^define\\('DB_USER'.+$", replace: "define('DB_USER', '{{ db_user }}');"}

この記述方法は、with_items句などでハッシュを利用する場合によく使います。 この場合、行単位で意味があるため、バージョン管理での差分管理も問題ありません。

コメント

YAMLではコメントを記述できます。

# Playbook for wordpress
- hosts: wordpress-servers
  roles: []

#の後ろがコメントです。

YAMLドキュメントの先頭

Ansibleでは使うことがありませんが、YAMLではひとつのファイルに複数のYAMLを定義できます。 この時、---で定義と定義の区切りを指定します。 Ansibleを利用する場合は、慣習として先頭に---を記述することがあります。

---
# Playbook for wordpress
- hosts: wordpress-servers
  roles: []

データ型

Ansibleを利用する場合、基本的にすべての値は文字列と考えて問題ありません。 しかし、YAMLを読み込む際にデータ型が影響するケースがあります。 注意したいのは数字だけで構成される文字列です。 YAMLとしては数値として扱われてしまうため、先頭のゼロが失われてしまうからです。

- name: "/etc/httpd/conf.d/wordpress.conf"
  template:
    src: wordpress.conf
    dest: /etc/httpd/conf.d/wordpress.conf
    owner: root
    group: root
    mode: "0644"

templateモジュールのmodeパラメータに0644を設定してます。 ここでダブルクォートで囲まないと644という数字として解釈されるでしょう。 モジュールで上手く処理していれば問題がありませんが、モジュールによってはエラーとなることがあります。 このため、数字のみで記述する場合、ダブルクォートで囲む方が良いでしょう。

Ansibleの変数展開

最後にAnsible特有の機能である変数展開についての解説です。 Ansibleでは変数を扱う機能があり、Playbookの一部を変数で置き換えます。

次のタスクでは、変数wp_pathをYAMLに展開します。

- name: "check {{ wp_path }}/wp-config.php' if exist"
  stat:
    path: "{{ wp_path }}/wp-config.php"
  register: stat_wp_config

変数を利用する場合、{{}}で変数名を記述してください。 この時、必ずダブルクォートで全体を囲む必要があります。

次のようにダブルクォートがないと変数展開が行われないので注意してください。

- name: check {{ wp_path }}/wp-config.php' if exist
  stat:
    path: {{ wp_path }}/wp-config.php
  register: stat_wp_config

なお、変数名の前後に半角スペースは必須ではありません。 可読性向上のため、半角スペースを推奨します。

まとめ

YAMLフォーマットはデータ構造を直感的なインデントで表記します。 ネストした構造やインライン記法もあり、柔軟さもそなえています。 AWSでもCloudFormationやCodeXX系のサービスで使われるフォーマットなので、ポイントを抑えておきましょう。