48
51

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ansible】かゆいところに手が届くTips その2

Last updated at Posted at 2016-05-12

Ansibleを使っていて、個人的にハマって調べたことをTipとしてまとめていきたいと思います。Tipsが溜まったらその3もやります!

今回紹介するTips

  1. OSユーザのパスワードは事前にハッシュ化しなくてもいい!
  2. role内変数を、role内のみで使うプライベート変数にする
  3. Ansibleモジュール内で*(アスタリスク)を使用する
  4. RPMパッケージをインストールさせたい
  5. become使用時にsudoパスワードを自動入力したい
  6. ansible-vault使用時にパスワードを環境変数で渡したい
  7. 何回も書く必要のあるパラメーターをまとめる!
  8. Ansibleでevalチックな変数の中に変数がある場合

OSユーザのパスワードは事前にハッシュ化しなくてもいい!


password_hashを使う

以前お伝えしたテクニックでは事前に暗号化しておく手順でしたが、
リファレンスをよくよく見ると暗号化してくれる書き方がありました。

以下に対応しています。

  • sha256
  • sha512

使い方

yaml
  - name: ユーザー作成
    user:
      name: test
      #SHA256の時はこちら
      password: "{{ 'password' |password_hash('sha256', 'mysecretsalt') }}"
      #SHA512の時はこちら
      password: "{{ 'password' |password_hash('sha512', 'mysecretsalt') }}"
      home: /home/test

ただし注意点として、以下のように変数をリスト化しループを回した場合、実行結果にパスワードが平文で流れてしまいます。

  vars:
    test:
      - name: test1
        password: password
        home: /home/test1

      - name: test2
        password: password
        home: /home/test2

  tasks:
    - user:
        name: "{{ item.name }}"
        password: "{{ item.password |password_hash('sha256', 'mysecretsalt') }}"
        home: "{{ item.home }}"
      with_items:
        - "{{ test }}"

passwordが平文で見える!

PLAY ***************************************************************************

TASK [user] ********************************************************************
changed: [rhel6_d] => (item={u'home': u'/home/test1', u'password': u'password', u'name': u'test1'})
changed: [rhel6_d] => (item={u'home': u'/home/test2', u'password': u'password', u'name': u'test2'})

なので、リスト化する場合はno_log: Trueをつけ、出力しないようにします。

  vars:
    test:
      - name: test1
        password: password
        home: /home/test1

      - name: test2
        password: password
        home: /home/test2

  tasks:
    - user:
        name: "{{ item.name }}"
        password: "{{ item.password |password_hash('sha256', 'mysecretsalt') }}"
        home: "{{ item.home }}"
      with_items:
        - "{{ test }}"
      no_log: True

こうなります

TASK [user] ********************************************************************
changed: [rhel6_d] => (item=(censored due to no_log))
changed: [rhel6_d] => (item=(censored due to no_log))

role内変数を、role内のみで使うプライベート変数にする

private_role_vars = yesを使う

roleで呼び出された・定義された変数は、別のroleに処理が移っても引き継がれます。Ansibleの変数命名ルールにて、先頭にrole名をつけろと記載されているのもそのためです。

しかし、そうもできない場合はroleの中で変数を閉じる必要がありますのでansible.cfgに以下の記載を追記します。

ansible.cfg
private_role_vars = yes

Ansibleモジュール内で*(アスタリスク)を使用する

with_fileglobを使う

tasks
- copy: 
    src: {{ item }} 
    dest: /path

  with_fileglob:
    - "/etcsysconfig/network-scripts/ifcfg-*"

ちなみにfetchモジュールで、with_fileglobを使用すると出力はOKとでるのにファイルが取得されないケースがあります。これは、with_fileglobの解決がローカルホストで行われるのに対し、fetchはターゲットマシン(構成管理対象サーバー)で実施されるためです。

そのため、*指定をしたい場合には、shellモジュールでfind検索を実施し、registerで登録した値をwith_itemsに入れるやり方となります。
※他のうまいやり方あったら教えて下さい。

RPMパッケージをインストールさせたい

yum モジュールを使う

yumモジュールでは、nameアトリビュートにてフルパスでの指定ができるため、ローカル上のRPMファイルを指定することでインストールが可能です。

tasks
yum:
  name: xxxxx.rpm
  state: present

参考:Ansible で RPM を扱う

become使用時にsudoパスワードを自動入力したい

ansible_become_passを使う

自動入力ができない!ということで、sudo時のパスワードをNOPASSWDにしている皆さん朗報です。

以前はsudo_passwordとかありましたが、becomeが推奨されてからはansible.cfg内では指定できなくなりました。じゃあどうするのか!というと、ansible_become_passが用意されています。

こいつの使い方は2通りあります。

  • インベントリファイルで指定
  • 変数ファイルで指定(変数として作成する)
インベントリファイルの場合
[target]
hostname1 ansible_become_pass=xxxx
変数ファイルの場合
ansible_become_pass: xxxx

発展ケース(環境変数渡し)

変数ファイルの場合
ansible_become_pass: "{{ lookup('env','SUDO_PASSWD') }}"

ansible-vault使用時にパスワードを環境変数で渡したい

JenkinsなどのCIツールを使用している場合や、vaultのパスワードファイルを残しておきたくない場合に使えるテクニックです。

--vault-password-fileを使います。

--vault-password-fileは引数にファイルだけではなく、実行権限の付与されたスクリプトを取ることができ、その標準出力をパスワードとして利用することができます。

つまり、環境変数をスクリプトで解析し標準出力させることで、vaultパスワードをローカルに残す必要がなくなります。ダイナミックインベントリ的な使い方ですね。

vault.sh
#!/bin/bash
echo $VAULT_PASS
bash
export VAULT_PASS=xxx
ansible-playbook site.yml --vault-password-file vault.sh

メモ

プロセス置換を利用して、シェルすら作りたくない!という場合はMacのみプロセス置換にて以下が可能です。(CentOSではできなかった)

bash
ansible-playbook site.yml --vault-password-file <(echo $VAULT_PASS)

Centos系のLinuxではプロセス置換時に一時ファイルを以下のようにpipe:[xxxxxxxx]で管理しています。

[server ]# ll <(date)
lr-x------ 1 root root 64  4月  8 11:01 /dev/fd/63 -> pipe:[24349835]

ansible-vaultコマンド実行時に読み込まれる以下のファイルでは、os.path.realpath(実際のファイルのパスを参照する)とかかれているためにpipe:[xxxxxxxx]が読まれてしまいうまく動作しないようです。(realpathを取り除くとうまくいった)

//github.com/ansible/ansible/blob/7f8e8ddca9cf103c05bf39d68ebb2e2ded4067f2/lib/ansible/parsing/dataloader.py:python

this_path = os.path.realpath(to_bytes(os.path.expanduser(vault_password_file), errors='strict'))
if not os.path.exists(to_bytes(this_path, errors='strict')):
  raise AnsibleFileNotFound("The vault password file %s was not found" % this_path)

MacではCentosとプロセス管理の仕組み(proc周辺)が異なるため、プロセス置換でもうまくいくようです。

何回も書く必要のあるパラメーターをまとめる!

YAMLのマージ記法を使う。

参考:ansible-playbook内でもYAMLのマージ記法が使えます!

task
 - file:
     path: /tmp/a
     << : &DEF
       owner: ansible
       group: ansible
       mode: 0755
       state: directory
 - file:
     path: /tmp/b
     << : *DEF

DEF変数にowner/group/mode/stateの設定をいれ、それを使いまわしています。これにより次回以降のパーミッション周りの設定をすっきりさせています。(変数名はなんでもよいです<< : &<< : *が大事)

これ色々と使えそうですね!

Ansibleでevalチックな変数の中に変数がある場合

{{ somvar_{{other_var}} }}

こういうことしたいときは、以下のようにします。

{{['somevar_'  + other_var] }}

host_varsを使ってる時はこっちらしい
{{ hostvars[inventory_hostname]['somevar_'  + other_var] }}

48
51
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
48
51

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?