Ansible

Ansibleの小技

More than 1 year has passed since last update.

※既出のものが含まれている可能性が高いですが、過去記事調査はしてないです(・ω・)

Ansibleのタスク量を少し削減する小技をいくつか紹介。

ファイルを一括で転送する

前提: roleを切っており、転送するファイルはroles/hoge/templates以下に格納されていること

copytemplateなどでファイルを転送する際にはsrcdestを指定する。
素直に書くと複数タスクに分けることになるが、ファイルごとに一々タスクを切るのは非効率である。

- name: transfer files
  template:
    src: templates/{{ item }}
    dest: /{{ item }}
  with_items:
    - etc/hoge/hoge.conf
    - etc/fuga/fuga.conf
    - usr/local/bin/test.sh

ファイルをtemplates/etc/hoge/hoge.confのようにディレクトリを切って格納しておくことで
上記のような書き方が可能になる。src,dest共にただのStringなので問題無く動く。

Ansible変数を展開する必要の無いファイルはcopyを用いてfiles/以下から転送するのが慣例だが、
何もかもtemplateで転送したところで特に不都合は無い。

追記

jinja templateの拡張子は.j2じゃないと許せないという人は、以下のように書く。

- name: transfer files
  template:
    src: templates/{{ item }}
    dest: /{{ item | regex_replace('\.j2$', '') }}
  with_items:
    - etc/hoge/hoge.conf.j2
    - etc/fuga/fuga.conf.j2
    - usr/local/bin/test.sh #こいつはjinja templateではないとする

拡張子がj2じゃないものはそのままにしてくれるので、意図した通りに配置される。

参考: Ansible Jinja2 filters 正規表現で変数の文字列を置換、抽出する

with_itemsを省略する

ceph-deployのように、複数の引数をスペース区切りで並べることで一括操作が可能なものに有効。

例: $ ceph-deploy purge host1 host2 host3 ...

mkdiraptなども該当するが、それはfileaptモジュールを使うのがベター。

with_itemsで回すと以下のようになる。
この場合、内部的には3回ceph-deployが実行されてしまう。

- name: purge nodes
  shell: ceph-deploy purge {{ item }}
  with_items:
    - host1
    - host2
    - host3

jinja filterを用いて以下のように書くことで、1回の実行で済む。
(以下の例ではベタ書きだが、基本的に変数はgroup_varsなどの変数をまとめるファイルに書くのがベター)

- name: purge nodes
  shell: ceph-deploy purge {{ nodes | join(' ') }}
  vars:
    nodes:
      - host1
      - host2
      - host3

join(' ')の空白を,などに変えることで、カンマ区切りで複数の対象を指定する用途にも使える。

おまけ: Python未インストールのホストでAnsibleを使用可能にする

Ansibleは対象ホストにPythonがインストールされていないと動作しない。
(例外はある。NW機器用のモジュールなど)

ただしrawモジュールは動作するので、対象ホストのパッケージ管理システムが既知の場合は以下を実行することで
次回から通常のモジュールを使用することができる。

ただしほとんどのケースでパスワード無sudoが必須のため、使い所が難しい。
一部のクラウドサービスでは「パスワード無sudoは可能だがpythonは無いイメージ」を採用しているため、
そのようなホストをセットアップする場合に有用。

init.yml
- host: hoge
  gather_facts: false
  tasks:
    - raw: 'sudo apt-get update'
    - raw: 'sudo apt-get install python-simplejson -y'

gather_facts: falseを抜いた場合、Ansibleが相手hostのPythonを用いて環境情報の収集を試みてしまうので失敗する。


なんか見つけたら追記するかも。