Ansibleでの連番ホスト名をつけるなど

クックパッドの新オフィスでitamaeによる寿司の無限プロビジョニングを体験して、Ansibleのお悩み相談してきた #infra_sushi

という記事を拝見しました。

お悩みの詳細はスライドを見てもらうとして、一つのツールですべて賄おう
として頑張ってしまうと、構成に矛盾が出てしまうので、
適材適所で組み合わせて使わないといけないというのは、完全に正論。

というのはぼくも完全に同意します。

ですが、実はこの2つの悩みはたぶんansibleでも解決できます。(LTを聞いていたわけではないので、意図とずれていたらごめんなさい)

1. EC2インスタンス作成の時の変数設定

[webservers]
prod-web01
prod-web02
prod-web03

[webservers:vars]
ami=ami-785bae10
group_tag=web

というinventoryファイルがすでにあるときに

---
- hosts: webservers
  gather_facts: no  # noにしておくと捗る
  tasks:
    - local_action:
        module: ec2
        (パラメータは一部略しています)
        instance_type: t2.micro
        image: "{{ ami }}"  # inventory
        exact_count: 3
        instance_tags:
          role: "{{group_tag }}" # ここちゃんと使えます
        region: us-east-1
      run_once: true  # 1.7以降で使えます
      register: ec2

local_action はansible-playbookコマンドを実行するホストですので、 hostsになにが書いてあろうとも、localhostで実行されます。

ただ、複数のホストが含まれているグループを指定した場合、local_actionで 指定したモジュールもその数だけ実行されてしまいます。

このため、1.7から導入された run_once を使います。run_onceは、グルー プ内の先頭で定義されたホストでのみ実行されるようにするためのパラメーター です。今回はlocal_actionですから、ローカルホストで一回だけ実行されるこ とに鳴ります。

ホスト名自動採番

自動採番とありますが、ここでは連続の番号を振る、と解釈します。

採番は with_indexed_items を使うと、 {{ item.0 }} にインデック ス番号 が、 {{ item.1 }} にリストの中身が入ります。

- debug: msg="{{ item.1 }} at {{ item.0 }}"
  with_indexed_items: some_list

これを利用します。

最初こうしてみたのですが、

- hostname: name="{{ host_prefix }}-{{ item.0 }}"
  with_indexed_items: play_hosts

これだと、例えば3台あれば、その3台に対して3回、合計9回実行されてしまい ます。

というわけで、前述の run_once と組み合わせます。ただし、単に run_onceだと、一台でしか設定できないことになってしまいます。ここで delegate_to を使います。

- hostname: name="{{ host_prefix }}-{{ item.0 }}"
  run_once: yes
  delegate_to: "{{ item.1 }}"
  with_indexed_items: play_hosts

ちなみに play_hosts は今回のplayで対象となるホストのリストが入って いる、最初から定義済みの変数です。

余談

0から始まるのがいやだ?贅沢だねぇ。

- hostname: name="{{ host_prefix }}-{{ item.0 + 1}}"

まとめ

ということで、2つの問題に対してansibleでも解決できることを示しました。

ただ、見て分かる通り結構トリッキーですので、適材適所で組み合わせて使っ たほうがいい、というのは合意します。

宣伝

ツキノワ では、 ansibleの有償セミナー (ハンズオン付き)を計画しています。

興味のある方はwebページからお問い合わせください。

Comments

comments powered by Disqus