連載
» 2016年07月26日 05時00分 UPDATE

Ansibleで始めるサーバ作業自動化入門(3):Ansibleを効果的に使うのに欠かせないPlaybookの基本的な書き方まとめ (1/2)

本連載では、「マニュアルやシェルスクリプトを使ったサーバ管理に課題を持つ方」を対象に、Ansibleの基本的な使い方を紹介。今回は、プレイブックの作成に焦点を当て、変数、繰り返し実行、条件分岐といった基本的な機能を紹介します

[今泉俊幸,株式会社ビーブレイクシステムズ]

 「マニュアルやシェルスクリプトを使ったサーバ管理に課題を持つ方」を対象に、Ansibleの基本的な使い方を紹介する本連載「Ansibleで始めるサーバ作業自動化入門」。前回の「Ansibleにおける環境構築やリリース作業でよく使う5つのModule+α」では、環境構築やリリース作業でよく使うモジュールについて、使い方とよく使う引数を紹介しました。

 今回はプレイブックの作成に焦点を当て、変数、繰り返し実行、条件分岐といった基本的な機能を紹介します。これらを用いることで、ほとんどのサーバ作業は自動化できるようになるかと思います。

変数の利用

 連載初回の最後のプレイブックの例では、以下のようにユーザーの追加とファイルの転送を行いました。

- hosts: all
  become: yes
  become_user: root
  tasks:
    - user: name=piyo
    - copy: src=/home/foo/bar.txt dest=/home/piyo

 例えば、ここで「piyo」ではなく別のユーザーを追加したい場合、「user」「copy」の両方の行で「piyo」と書かれた箇所を新しいユーザー名に変更する必要があります。このように、変更し得る値をタスクに直接書いてしまうと変更箇所が多くなり、保守性が低下してしまいます。

 そこで、変数を利用し、別のユーザー名のユーザーを追加する場合も変更が1カ所で済むようにしてみます。以下のように連載初回で作成した「main.yml」を修正してください。

- hosts: all
  become: yes
  become_user: root
  vars:
    user_name: piyo
  tasks:
    - user: name={{ user_name }}
    - copy: src= /home/foo/bar.txt dest=/home/{{ user_name }}/

 変数定義は「vars」要素を使用します。今回は「user_name」という名前の変数に「piyo」という値を設定しました。変数名には、アルファベット、数字、アンダースコアのみが利用でき、変数名の先頭はアルファベットから始まる必要があります。

 定義した変数の値を参照するには「{{ user_name }}」のように「{{変数名}}」という形式を使います。また、以下のように変数の宣言時に他の変数の値を使うことも可能です。

vars: 
  user_name: piyo
  dest_file_path: /home/{{ user_name }}/

 ただし、以下のように値の定義の最初に変数の参照を書いた場合、YAMLの構文エラーとなってしまいます。

vars: 
  user_name: piyo
  file_name: {{ user_name }}.txt

 このような場合は以下のように値の箇所をダブルクオートで囲むことで参照できるようになります。

vars: 
  user_name: piyo
  file_name: "{{ user_name }}.txt"

変数の値をマッピングで定義する

 あるユーザーのユーザー名とパスワードのように、セットで扱った方が可読性が高まるような情報があります。

 この場合、以下のようにマッピングを使って階層的に変数を定義できます。

vars:
  admin_user_data:
    name: momo
    password: $6$rounds=656000$3Co6RKpfjN.qj23.

 マッピングの値については以下のように変数名に「.」を付けて参照します。

tasks:
  - user: name={{ admin_user_data.name }} password={{ admin_user_data.password }}

変数の値をコンソールから受け付ける

 変数はあらかじめプレイブックに書いておくだけではなく、ユーザーの入力を受け付けて値を設定することもできます。これは、例えばリリースを行う際、ファイル名にリリースバージョンが入っていてそれを参照したい、というような場面で便利です。

 この時、もしもリリースバージョンを変数にしてプレイブックに値を記載するようにすると、リリースの度にプレイブックを書き換える手間が掛かり、また変更漏れもあり得るためです。

 変数の値を入力させるには、「vars」の代わりに「vars_prompt」要素を利用します。vars_promptの利用例は以下の通りです。

vars_prompt:
  - name: release_version
    prompt: "input release_version. (ex.20160204 )"
    private: no
tasks:
  - copy: src=/home/foo/release_{{release_version}}.zip dest=/home/piyo

 「name」で指定した値が変数名となり、ユーザーが入力した値がこの変数に設定されます。「prompt」で指定したメッセージがユーザーに表示されます。「private」はユーザーの入力値がコンソールに表示されるかどうかを示します。もしパスワードのように他人に見られたくない入力をする場合はprivateに「yes」を指定します(デフォルト値はyes)。

 また、前回紹介したPasslibがインストールされている場合、以下のように入力値を暗号化することが可能です。

vars_prompt:
  - name: password
    prompt: "input newuser password"
    encrypt: sha512_crypt
    confirm: yes
tasks:
  - user: name=momo password={{ password }}

 「encrypt」では暗号化の種類を、「confirm」ではユーザーに確認用に2度入力をさせるかどうかを指定しています。

デフォルトで用意される変数を使う

 プレイブックを実行した際、プレイブック内に存在していない「setup」というタスクが最初に実行されていることに疑問を持った人もいたかもしれません。実は、このsetupというタスクでAnsibleは被管理ホストの情報を取得し、変数にセットしてくれています。

 setupタスクで取得される値については、以下のコマンドで確認可能です。

ansible -i hosts ホスト名 -m setup

 setupでは以下のような値が取得されています。

変数名 内容 値の例
ansible_distribution 被管理ホストのディストリビューション CentOS
ansible_date_time.date Ansibleの実行日時 2016-03-11
ansible_hostname 被管理ホスト名 localhost
ansible_pkg_mgr 被管理ホストで利用できるパッケージマネジャー名 yum

繰り返し実行

 複数のファイルをコピーしたり、複数のユーザーを追加したりしたい場合、追加したい数だけ対応するモジュールを書くことでも実現できますが、プレイブックが長く読みづらくなってしまいます。

 このような場合にはタスクの繰り返しを扱う機能を使うと便利です。

単純な繰り返しを行う「with_items」

 userコマンドを使い複数のユーザーを追加したいとします。このような場合、「with_items」をタスクに指定することで、一括で追加が可能です。

tasks:
  user: name={{ item }}
  with_items: 
    - momo
    - sora

 with_itemsに渡されたシーケンスの内容が順に「item」という名称の変数に設定され、繰り返し実行されます。

 以下のようにあらかじめシーケンスを変数で作っておき、with_itemsで指定することも可能です。

vars:
  users:
    - momo
    - sora
tasks:
  user: name={{ item }}
  with_items: "{{ users }}"

 上記の例で、ユーザー名と一緒にパスワードも指定したい場合は以下のようになります。

vars:
  users:
    - name: momo
      password: $6$rounds=656000$3Co6RKpfjN.qj23.
    - name: sora
      password: $6$rounds=656000$3Co6RKpfjN.qj23.
tasks:
  - user: name={{ item.name }} password={{item.password}}
    with_items: "{{ users }}"

マッピングを繰り返す「with_dict」

 先ほどの例では、シーケンスでユーザーの追加を繰り返していました。しかし、以下のようにマッピングを使っており、マッピングの全ての要素で繰り返し実行したい場合はwith_itemsは使えません。

vars:
  users:
    admin:
      - name: momo
        password: $6$rounds=656000$3Co6RKpfjN.qj23.
    workes:
      - name: sora
        password: $6$rounds=656000$3Co6RKpfjN.qj23.

 マッピングを繰り返しに利用する場合は「with_items」の代わりに「with_dict」を利用します。with_dictを利用すると、with_itemsと同様に「items」変数からマッピングのキーとバリューを取得できます。キーを取得するにはitem.keyを、バリューを取得するにはitem.valueを指定します。with_dictの利用例は以下の通りです。

tasks:
  - user: name={{ item.value.name }} password={{item.value.password}}
    with_dict: "{{ users }}"

ワイルドカードを使って繰り返す「with_fileglob」

 copyモジュールでファイルをコピーする際、ある拡張子のファイルだけコピーしたい、というような場合もあるかと思いますが、「src」引数にはワイルドカードを利用することはできません。以下のようにプレイブックを記述した場合、「*.txt」という名称のファイルをコピーしようとしてしまいます。

tasks:
  - copy: src=/home/vagrant/*.txt dest=/home/piyo/txt/

 このような場合には「with_fileglob」が使えます。with_itemsと同じようにシーケンスでファイルパスを指定することで、ヒットしたファイルパスだけタスクが繰り返し実行されます。with_fileglobの利用例は以下の通りです。

tasks:
  - copy: src={{ item }} dest=/home/piyo/dest/txt/
    with_fileglob:
      - /home/vagrant/*.txt
       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。