[和訳] なぜ”Why-Run”モードは有害と考えられるのか #getchef
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
本稿は Why“Why-Run”Mode Is Considered Harmful (2018/03/14) の和訳です。
今回のブログ記事は、製品マーケティングとしては少し異色のものになります。自社製品の特定の機能の使用を お勧めしない 記事だからです。3月のウェビナーでChefの"why-run"モードに関する質問があり、私たちはまたいまだにこのモードを使用しているユーザがいることを知りました。そこで私たちは、明確なガイダンスを示すことにしました: もしもあなたがいまだに "why-run" モードを使用しているなら、 使用を中止してください。今回の記事で、そのwhyをご説明します(ダジャレではありません)。代替案もあわせてご紹介します。
Why-Runモードの起源
Chefを最初にリリースした2009年1月に遡ると、元々dry-runやno-opモードなどが提案されていました。これはおそらくCFEngineとPuppetの両方にこの機能があったので、Chefのアーリーアダプターは本番環境に投入する前に変更を「検証」するという方式に慣れていたためです。しかし初めから、これらのツールの以前からの経験に基づいて、誰もがそのような機能は「どうかしてる欠点」があることを分かっていました。これらの欠点があるにもかかわらず、コミュニティはその後数年間に及び、それを実装するかどうか議論しました。Chefは最終的に、2012年頃のバージョン10.14でwhy-runモードを取り入れました。
誰もがもう少し待っていたら。2011年6月に出版されたStephen Nelson-Smith氏の書籍 Test-Driven Infrastructure with Chef が、根本的に異なる道を私たちに教えてくれました: Stephen氏は、私たちに本当に必要なのは、本番環境にデプロイする 前に 独立した環境でinfrastructure-as-codeをテストする信頼性の高いワークフローであることを気づかせてくれました。最初、Stephen氏は Cucumber を使って論点を明らかにしました。彼の業績に影響を受けたChefコミュニティーはシステム管理者向けのインフラテストツール、Test Kitchen、ChefSpec、Foodcritic、Cookstyle、さらに最近では InSpec などを開発しました。2010年に最初にリリースされたVagrantのようなエコシステムツールと組み合わせることで、エンジニアは既知のイメージから仮想マシンを迅速にプロビジョニングして機能テストを行い、後にDockerを使用し、大幅に起動時間を短縮して同じことを成し遂げることができるようになったので、今日では本番環境でのテストを続行する正当な理由は見当たりません。
Why-Runモードは機能しない
先に、no-opまたはdry-runモードは本当に機能しないと述べました。これは、構成管理システムのリソースが相互に関連する可能性があるためです。Chefの実行時(またはPuppetカタログ、またはAnsibleプレイブック)に先に実行するものはシステムを変更できるので、後に実行するリソースは異なる状態を観測してしまい、異なる動作を示してしまう可能性があります。しかし、定義によるno-opモードでは独立したリソースを個別に観察することしかできず、その限られた視野に基づいて何が起こるかを 予測 しようとするほかありません。これは、相互に依存するリソースを監視している場合に特に問題になります。コードスニペットの例をご覧ください:
package 'httpd' do
action :install
end
execute '/tools/letsencrypt.sh' do
action :run
only_if 'rpm -q httpd'
end
Why-runモードは1つのリソースだけを変更すると予測するはずです。なぜなら、後続の execute ブロックの内容を評価する際に、その値が最初のリソースの execute ブロックの実行結果に基いて変化することを知る方法がないからです。このレシピを実行すると、2つのリソースを実際に変更します。しかし、そのことをwhy-runは教えてくれないのです。
同じように警告します: その名前にもかかわらず、no-opモードは一般にシステムに対して副作用を起こさないわけではありません。これは、本番環境でno-opモードを実行することが安全だと思う人々への警告かもしれません。例えば、夜間に実行しているwhy-runのcronジョブが本番環境サーバーを無作為に破壊していると顧客が報告した概要を目の当たりにしました。彼らのOSバージョンは、サービスの状態を"変更をしていない"にも関わらず、実行中のサービスの状態を問い合わせると、ときおりロックするバグのあるバージョンの systemd を偶然実行していました。非常に多数のサーバ群を横断してこのcronジョブを実行することは、毎晩本番環境の少なくともいくつかのマシンを確実に動作不能状態にするのに十分でした。
Why-Runはコンプライアンスではありません
本番環境でのテストが正しいアプローチではないことが明らかになったと期待しています。しかし、システムコンプライアンスについて報告するために、why-runモードを使用するのはどうでしょうか?
変更を加える前、または後にシステム状態を継続的に評価、または監査したいと思っていることは素晴らしいです。我々は、これを 検出・修正・自動化 のパターンと呼んでいます。しかし、(「修正」を担当している)構成管理システムに「検出」フェーズを持たせることは正しいアプローチではありません。構成管理は、あなたが宣言した通りに状態を強制することに適しています。あなたが宣言していないシステムの状態はどうなっていますか?
さらに重要なのは、権限分離 の要件です。これは、最初に監査人が必要な理由と同じです。プログラムやチームが行う変更よりも、異なるプログラム(または異なるチーム)による変更の検証を行うときにのみ、「信じよ、されど確認せよ」という悪名高いことわざが成立します。InSpecを開発し、リリースした理由の1つは、役割と責任の明確な線引きを描くことです。開発者とシステム管理者は、Chefのコードを担当し、セキュリティエンジニアはInSpecのコントロールを担当します。そして、両者は決して会うことはありません(ChefのAttributeをInSpecのコントロールにインポートすることに強く反対するのと同じ理由でもあります)。
言い換えれば、コンプライアンスのためにdry-runまたはno-opモードに頼らないでください。結果が不完全であるだけでなく、監査人の精査にもおそらく耐えられないでしょう。
まとめ
why-runモードについてまとめると:
- 非本番環境で構成管理コードのテストを適切に実行するためのツールが登場する以前、構成管理の初期段階の時代の産物。why-runの代わりに、そのようなツールとテストワークフローを使用することをお勧めします。
- 定義が不完全であり、多くを詳細に明記していない状況では、不正確な結果をもたらします。それによって、実際の実行時に適用する変更について、大丈夫だという誤った感覚を持ってしまいます。本番システム上に望ましくない影響を及ぼす可能性もあります。
- コンプライアンスを検証するために使用することはできません。これは、前述の技術的な理由(それだけでも重大ですが)だけでなく、権限分離の欠如は、実際に構成したコンプライアンスを監査人が承認しそうにないという意味です。
推奨していない機能をそのままにしておかないという精神で、Chefの今後のメジャーバージョンでは、why-runモードを削除するよう検討いたします。