ぽよメモ

レガシーシステム考古学専攻

Ansibleの冪等性について深く考えたことはありますか?

はじめに

 僕は今,修士論文の執筆に向けて構成管理ツールと冪等性についての論文を複数読んでいます.それらを踏まえて,一般によく見られるAnsibleへの誤解についての自分の見解,そして2019年現在,構成管理ツールについてどういった研究がされているかを簡単に述べていきたいと思います.

冪等性

 そもそも冪等性とは「ある操作を一回行っても,複数回行っても,結果が変わらない」という概念です.例えば,

  • 例えば1や0と任意の自然数のかけ算
    •  N \times 1 = N \times 1 \times 1 = N \times 1 \times 1 \times 1= \cdots
    •  N \times 0 = N \times 0 \times 0 = N \times 0 \times 0 \times 0= \cdots
  • 絶対値の計算
    •  abs(x) = abs(abs(x)) = abs(abs(abs(x))) = \cdots

などが冪等性を持った処理に当たります.

Ansibleにおける冪等性

 さて,Ansibleのモジュールを使用した操作はよく冪等であると言われています.ここで,Ansibleにおける「冪等」とは何でしょうか?Ansibleの用語集*1を引いてみます.

An operation is idempotent if the result of performing it once is exactly the same as the result of performing it repeatedly without any intervening actions.

訳すなら,「一度実行した結果が,介入する操作無しで繰り返し実行した結果とまったく同じならば,操作は冪等である」という感じでしょうか*2.うーんなんとなくいいかんじに思えますね!(?

 しかしこの「まったく同じ」というのは何を要求するのでしょうか.例えばlineinfileモジュールを用いて,あるファイルにある行が一文あるということを宣言したとします.

- lineinfile:
    path: /path/to/hoge
    line: "Some line"

実行したとき,必ず一度はその存在を確認するためにファイルにアクセスする必要があります.すると,その行がある場合も無い場合も,Linuxではそのファイル(ここでは/path/to/hoge)のatime,つまりアクセス日時が更新されてしまいます.また,(オフに設定しない限り)実行の度に対象のホストへログも書き込まれます.これは「冪等性」を満たすのでしょうか?

冪等性は主観によって決まる

 おそらくほとんどのケースでは,atimeの更新やsyslogへの書き込みのような,求める操作に伴う暗黙的な副作用は問題にならないでしょう.この場合には「(当人から見て)冪等性は満たされている」と言えるかと思います.しかし逆に,(あるのか知りませんが)atimeが重要で容易に更新されて欲しくないケースにおいてはどうでしょうか?もしかすると,「(当人から見て)冪等で無い」と考えるかも知れません.

 このように,構成管理ツールにおける冪等性というものは,実際にはその結果を観測した人の主観に左右されます.冪等なモジュールであるからといって,得られる結果が完全に何もかも実行前と同じとは限らないということに留意した上で,こうしたツールと付き合っていく必要があるでしょう.

 このような必ずしも何もかもが完全に同一とはならない現実のシステムにおいて,「冪等」という概念をそのまま適用することは非常に難しいと言わざるを得ません.あまりしっくり来る定義を見つける事ができなかったのですが,天才*3から教えてもらったRFC7231の4.2.2*4がなかなかしっくりくるなと思ったので紹介します.ここではGETやPUTなどのHTTPリクエストについて,どのような場合にそのリクエストを「冪等」と見なすかを述べています.

Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request.

つまり,「冪等」と判定する要素は,ユーザが要求した属性についてのみであり,それに伴うサーバサイドでの副作用(例えば各リクエストについてログを取るなど)は感知しないということのようです.Infrastructure as Codeの文脈において考えてみても,各ツールはユーザが要求した属性(例えばファイルの存在とか)についてのみ冪等であることを保証できるように努力し,それに伴う副作用(サーバサイドにログが残る,atimeが更新される…etc)については保証しない,という考え方をすれば,比較的まともな「Ansibleにおける冪等性」への理解を得られるかと思います.

モジュールの冪等性

 現状構成管理ツールのあるモジュールによる操作が,(他の何らかの操作の介入を受けなかったとしても)完全に冪等性を保証することは知る限りでは証明されていません*5.つまり,Ansibleによる操作が完全に冪等であることを,誰も保証してくれません.もちろんIssueには冪等性(idempotence)に関するものも多くあり,努力はされていますが,最終的には自分で検証してなんとかするしかありません.
 このような現状なので,当然どのモジュールのドキュメントにも,「これは冪等なモジュールです」とは書いていません.Issueを漁っていると,過去に「冪等かどうかドキュメントに書いてくれ」というものが上がっていました.

github.com

これに関連したIssueコメントは以下です.

github.com

非常に短いメモが残されているだけなので,実際のその場での議論などは分かりませんが,

  • 冪等でないモジュールもある
  • でもそれらのために多大な労力を払って冪等かどうかを表示するのはコストが高すぎる
  • 今のところ何もしない

というような決着を迎えたようです.以降これに関連したIssueは探しましたが見つからず,Ansibleの方向性として冪等性のしっかりとした証明は目指さず,あくまで努力目標であるということが伺えます*6.活躍するドメインから考えても,これはあくまで実務上のツールであり,理想を追い求める物ではないので,この判断は正しいことだと思います.

 とはいえ,冪等な操作を売りにしているツールにしては,そのやり方でみんな納得しているのか?という気持ちがあります.

Playbookの冪等性

 全てのタスクが冪等であったとしても,複数のタスク・ロールを束ねたときに,全体を通して冪等になるとは限りません.例えばあるミドルウェアをインストールするというロールと,そのミドルウェアをアンインストールするというロールを同時に使用すれば,毎回インストール→アンインストールを繰り返すことになり,冪等性が保たれなくなります*7

 こうした事象を避けるためには,

  • 一つのRoleの責務を小さくかつ明確にすること
  • Ansible GalaxyなどでインストールしたRoleの中身に一度は目を通しておくこと

などが重要かと思います.

構成管理ツールについての研究の今

 それなりの数に目を通したのですが,ちゃんと研究になっているものとしては以下の3種類に分類できると考えました.現状この分野の研究はほぼPuppetのものに限定されており,Ansibleは構成管理ツールとしての紹介がされているのみです.

冪等であるかどうかをテストする系

 2013年にChefのCookbookを対象に,冪等性検証フレームワークを提唱した論文です.LXCを使用して実際にCookbookを実行するのですが,ただ二回実行するというような方法ではなく,STGという状態遷移グラフを構築して様々な実行パターンを検証します.状態の変化の検知にはOhai*8を使用していたようです.

Testing Idempotence for Infrastructure as Code | SpringerLink

2016年に上の論文の結果を受けてPuppetでの冪等性検証フレームワークの提唱をしたのが下記の論文です.Ohaiを参考にした上で,straceやptraceを使って任意のファイルの変更まで追いかけたのが特徴です.

Asserting reliable convergence for configuration management scripts

結果の可視可もよく出来ています.

citac.github.io

同じく2016年にPuppet向けの冪等性検証フレームワークとしてRehearsalというものを提唱した論文です.これは単にPuppetコードを実行するのではなく,Puppetの各リソースを彼らが提唱したファイル操作をするための小さなDSLに置き換え,Puppetの非決定的な実行順序による操作のコンフリクトを検証できます.

Rehearsal: a configuration verification tool for puppet

難しいのでしっかりとは読み込めていませんが,そもそも構成管理ツールのある操作は任意のファイルへの操作であると考えると,これは割と面白いアプローチかと思いました.

品質モデルを提唱する系

 2016年にMSRというリポジトリマイニングの国際会議にて提唱された,Puppetコードのコードスメル*9に関する研究です.いわゆるバッドプラクティスを検知して「匂う」コードを見つけようというものです.

Does your configuration code smell?

下記の論文では,Puppetコードの品質モデルを提唱しています.実際に開発者らへのアンケートからモデルを定義し,自社・他社のPuppetエンジニアによる品質の分類と,品質モデルによる分類を比べて,ある程度正確な品質モデルを定義する事が出来たと述べられています.

How good is your puppet? An empirically defined and validated quality model for puppet - IEEE Conference Publication

セキュリティ系

 以下の論文も又コードスメルの検出なのですが,内容がよりセキュリティに寄っています.

2019.icse-conferences.org

以下のブログに簡単なまとめがあります.

jagijagijag1.qrunch.io

IaCに関する研究はブルーオーシャン

 ここでは構成管理ツールに関する研究に絞っていますが,IaC(というかDevOps)という分野自体が若く,研究はあまり進んでいません.実務と結びついた領域であるために,研究者が手を出しにくい分野なのかもしれません.出すなら今ですよ!(?

 特にそのツールや概念に詳しい研究者を集めることは容易ではなく,GitHubなどから開発者らにメールを送ってアンケートに答えてもらう,など,泥臭いことが多々行われています.その回答率も芳しくなく,結果の信頼性としてもかなり微妙と言わざるを得ません.Ansibleはユーザコミュニティも活発で,実務で使用しているプロフェッショナルが多数います.研究にはもってこいなのでは? 🤔

まとめ

  • Ansibleに限らず,構成管理ツールにおける冪等性というものは,使用者の主観によって左右される
  • 今のところ,Ansibleモジュールが真に冪等であることは証明されていない
  • モジュールが冪等だから!と適当にやっていると容易に冪等性を失う
  • IaCは実務に関わる部分が大きく,研究者にはなじみが薄いため,論文を書き放題
    • ツールへの造詣が深いエンジニアの意見を使って論文が書けるのは企業の強み
    • 是非いかがですか?

*1:https://docs.ansible.com/ansible/2.9/reference_appendices/glossary.html?highlight=idempotency

*2:ニュアンス違ったらすいません

*3:弊ラボのドクターです

*4:tools.ietf.org

*5:これは研究者の怠慢であるかもしれませんね

*6:続報があるとか何か知っておられる方いらっしゃれば教えてください

*7:こういうのをAnsibleのdry-run時に検知する方法とかないんでしょうか?

*8:github.com

*9:qiita.com