yourlabs.remember
yourlabs.remember
`````````````````
Ansible自動化アーキテクトのためのメタロール。
このロールはAnsibleのワークフローをスマートにします:
- 大幅なスピードアップ:依存ロールを1回だけ要求
- インベントリレスのドライ:ホストでCLIから注入された変数を記憶
- CLI変数のプロンプト:ユーザーに対してインタラクティブに質問
.. 注意:このロールは依存ロールを自動でダウンロードしません。bigsudo <https://pypi.org/project/bigsudo/>
_ コマンドの仕事です。
デモ
試すのは簡単です::
pip install --user bigsudo ~/.local/bin/bigsudo yourlabs.fqdn user@somehost
または、勇気がある方は(ホスト名を省略してローカルホストに適用)
~/.local/bin/bigsudo yourlabs.traefik
もちろん、ansible
コマンドを使用することもできますが、その場合はコマンドとオプションが多くなります。小さなサーバーや非HAサービス、ピザチームにとって、kubectl の実践からインスピレーションを得ています。もし私がする必要があれば、bigsudo yourlabs.k8s
を使ってk8sインスタンスを設定します...
使用法
このロールを使用すると、自分のロールに必要な変数を定義でき、ユーザーに表示される説明、デフォルト、正規表現によるバリデーションなども設定できます。
OAOOロール依存性の注入
例として、yourlabs.traefik
(Dockerベースのロードバランサー)がyourlabs.docker
を必要とする場合を考えます。ここでは、例のためにyour.parent
と your.child
を使用してそれぞれyourlabs.docker
とyourlabs.traefik
の使用例を示します。
your.child/requirements.yml
に次のように記述します::
- your.parent
your.parent/requirements.yml
に次のように記述します::
- yourlabs.remember
このようにして、your.child
はyour.parent
に依存し、your.parent
はyourlabs.remember
に依存しています。
.. 注意:bigsudoは、bigsudo your.child
を実行するときに、要求が再帰的にインストールされることを透過的に保証します。
remember
ロールがない場合、通常はyour.parent
ロールを次のようにyour.child/tasks/main.yml
の最上部に含めます::
- name: Install your.parent prior to running our tasks include_role: name=your.parent
ただし、これでは毎回ロールが実行されるため、実行が長くなります。your.child
を実行する際にyour.parent
が完全に実行されるのを待ちたくない場合、次のように記述できます。最上部でのyour.child/tasks/main.yml
では:
.. コードブロック:: yaml
- name: Install your.parent if never done on this host include_role: name=your.parent when: ansible_facts['ansible_local']['your_parent']['state']|default('') != 'success'
これが機能するためには、your.parent/tasks/main.yml
の最後に次のように追加する必要があります:
.. コードブロック:: yaml
- include_role: name=yourlabs.remember tasks_from=success
このようにして、bigsudo your.parent
を実行すると(ansibleでも動作します)、/etc/ansible/facts.d/your_parent.fact
に次の内容が作成されます::
#!/bin/sh echo '{ "state": "success" }'
これにより、次回はロールを含める必要がなくなります。
インタラクティブな設定を使ってカスタムの永続的なロール変数を追加する方法を続けて読んでください。
インタラクティブロールの設定
your.parent/vars/main.yml
では、ロールデプロイメント変数の名前空間であるremember_fact
を定義し、ロールが依存している変数を次のように設定します::
remember_fact: your_parent remember:
- name: email_enable question: カスタムメールを有効にしますか? default: false type: bool
- name: email question: どのメールを使用しますか? type: email default: '{{ lookup("env", "USER") }}@{{ inventory_hostname }}' when: email_enable
次に、your.parent/tasks/main.yml
では、yourlabs.remember
を含めると、変数が読み込まれ、ユーザーに新しい変数についてインタラクティブに質問します。Action Pluginのおかげで非常に迅速です::
- include_role: name=yourlabs.remember
もっとできます。もちろん、test.yml
のプレイブックを参照してください。我々はこれを次のコマンドで実行します:
ansible-playbook -c local -i localhost, test.yml -v --become
:
.. include:: test.yml
複数のデプロイメント:変数の名前空間
同じホスト上でのロールの複数のデプロイメントを可能にするには、すなわちeXtreme DevOpsを実現するために、remember_fact
が変数に依存する必要があります。
例えば、異なるディレクトリにdocker-composeをデプロイしたい場合、home
変数が必要です:
.. コードブロック:: yaml
remember:
- name: home
question: どのホームディレクトリにデプロイしますか?(正規表現の例として/homeで始める必要があります)
default: /home/test
type: path
regexp: /home.*
つまり、コマンドラインでhome
変数を渡さなかった場合(例:-e home=/home/bar
)、ホームディレクトリを促します。今、私たちがすべきことは、そのホーム変数をremember_fact
に再利用して、各ホームディレクトリごとに変数を名前空間にすることです:
.. コードブロック:: yaml
remember_fact: your_role_j2((home))
ご覧のように、{{ }}
の代わりにj2(( ))
を使用しています。これは、Ansibleがホーム変数に値を取得する前にレンダリングしないようにするためです。実際、rememberアクションプラグインは:
- 既存の変数をロードするために
remember_fact
をレンダリングしようとします。 AnsibleUndefinedVariable
例外をキャッチします。- 必要な未定義変数の定義を
remember
で見つけます。 - それらを保存せずに質問します。
- 既存の変数をロードし、新しい変数の質問をします。
結論
ついに、私たちは明確で比較的簡単な方法を持つところに到達しました:
- 依存ロールを動的に注入して、ロールの後続の実行をスピードアップし、不必要な依存ロールの二重実行を防ぎます(例えば、Docker、ロードバランサー、より低いレベルの自動化など)。
- インベントリを抑制します。各サーバーは自分の変数を保持しますので、無駄に心配するリポジトリが1つ減ります。
- インタラクティブなファクトプロンプトにより、インターネットで見つけたロールを実行する前にドキュメントを読む必要がなくなります!
クレジット
beta.gouv.frのtotakokoさんに長い議論と、私のインベントリが過剰であることのデモンストレーションに感謝します。
#ansible
@irc.freenode.net
の、最高のIRCチャンネルの一つにも感謝します:
- agaffney
- mackerman
- jborean93
そして、私の小さな冒険を読んでくれたあなたにも感謝します!