akishin999の日記

調べた事などを書いて行きます。

Playbook 実行時に任意の値を指定する

Playbook 内に直接値を定義せず、実行時に外部から値を渡したい場合、 --extra-vars 引数を使う方法と vars_prompt を使う方法があります。

--extra-vars

Passing Variables On The Command Line
http://docs.ansible.com/ansible/playbooks_variables.html#passing-variables-on-the-command-line

※ www.ansibleworks.com は使われなくなったようなので URL を修正

予め Playbook 内で変数を使用しておき、 ansible-playbook コマンドの実行時に --extra-vars オプションによって実際の変数の値を渡す事が出来ます。

Playbook は以下のような感じで定義します。

  • extra-vars.yml
---
- user: '{{ user }}'
  hosts: '{{ hosts }}'
  tasks:
    - name: install mlocate
      yum: name=mlocate state=installed

「user」と「hosts」の値をそれぞれ同名の変数を参照するようにしていますが、このファイル内では変数は定義していません。
これらの変数は Playbook 実行時に以下のように --extra-vars 引数の値として指定します。

$ ansible-playbook extra-vars.yml --extra-vars "hosts=all user=root" -i hosts -k

Ansible 1.2 からは以下のように JSON 形式で指定することも出来るようです。

$ ansible-playbook extra-vars2.yml --extra-vars '{ "foo":"FOO", "fruits":["apple", "cherry", "orange"] }' --connection=local

以下のように debug モジュールを使うと簡単に動作確認が出来ます。

  • extra-vars2.yml
---
- user: root
  hosts: all
  tasks:
    - debug: msg="{{ foo }}"

    - debug: msg="${item}"
      with_items: fruits

vars_prompt

Prompts
http://docs.ansible.com/ansible/playbooks_prompts.html#prompts

※ www.ansibleworks.com は使われなくなったようなので URL を修正

vars_prompt を使う場合、Playbook 内の vars_prompt セクションで外部から入力を受け付けたい変数を定義しておきます。

  • vars-prompt.yml
- user: root
  hosts: all
  vars_prompt:
    - name: "name"
      prompt: "Please enter your name"
      private: no
      default: "John Doe"
  tasks:
    - debug: msg="Hello, {{ name }}"


実行すると以下のように「prompt」で指定した「Please enter your name」というメッセージが表示され入力待ちになります。
任意の文字列を指定して Enter を押すと debug モジュールが実行されます。

$ ansible-playbook vars-prompt.yml --connection=local
Please enter your name:

vars_prompt では以下のようなオプションを使用できます。

オプション 意味
name 入力値を参照する際の変数名
prompt 入力を促すプロンプト文字列
default デフォルト値
private yes にするとエコーバックされない(パスワード等で使う)
confirm yes にすると確認のための再入力を求める

エコーバックしない private オプションや確認のための confirm オプションがあるので、パスワードの変更などに使うと良さそうです。

vars_prompt で入力された文字列でパスワードを変更する Playbook を書いてみると以下のような感じになりました。

- hosts: all
  user: root
  vars:
    username: johnd
    saltstr: saltstr
  vars_prompt:
    - name: "new_password"
      prompt: "Enter new password"
      confirm: true
      private: yes
  tasks:
    - name: "create password salt"
      shell: echo somesalt | /usr/bin/md5sum | awk '{print $1}'
      register: password_salt

    - name: "create new password hash"
      command: python -c 'import crypt; print crypt.crypt("{{ new_password }}", "$1${{ password_salt.stdout }}$")'
      register: password_hash

    - name: "change password"
      user: name={{ username }} password={{ password_hash.stdout }} state=present

どちらかというと環境構築用の Playbook では --extra-vars の方が使えそうですが、運用系の作業を Playbook 化する場合などは vars_prompt の方が適している場合もありそうですね。