Chef、Puppet、Ansible、SaltStack、またはCloudFormationではなくTerraformを使用する理由

Update,November17,2016:このブログ記事シリーズを取り上げ、拡張し、Terraform:Up&Running!

更新、2019年7月8日:Terraform0.12のこのブログ記事シリーズを更新し、Terraformの第2版をリリースしました:Up&実行中!これは、Terraformシリーズの包括的なガイドのパート1です。

これは、Terraformシリーズの包括的なガイドのパート1です。 シリーズのイントロでは、すべての企業がinfrastructure-as-code(IAC)を使用する必要がある理由について説明しました。 私たちは選択の私たちのIACツールとしてTerraformを選んだ理由この記事では、我々は議論するつもりです。

インターネットで”infrastructure-as-code”を検索すると、最も人気のあるツールのリストを簡単に見つけることができます。

  • Chef
  • Puppet
  • Ansible
  • SaltStack
  • CloudFormation
  • Terraform

簡単ではないのは、これらのうちのどれを使用すべきかを考え出すことです。 これらのツールはすべて、インフラストラクチャをコードとして管理するために使用できます。 それらはすべてオープンソースであり、貢献者の大規模なコミュニティに支えられており、多くの異なるクラウドプロバイダーと連携しています(cloudformationはクローズド それらのすべては、企業のサポートを提供しています。 それらのすべては、公式文書と、ブログ投稿やStackOverflowの質問などのコミュニティリソースの両方で、十分に文書化されています。 では、どうやって決めるのですか?

これをさらに難しくするのは、これらのツール間でオンラインで見つけた比較のほとんどは、各ツールの一般的なプロパティをリストし、それらのいず それは技術的には真実ですが、それは役に立ちません。 技術的には真実ですが、良い決定を下すのに非常に有用であろう膨大な量の情報を省略する声明—それはあなたがPHP、C、またはアセンブリでwebサイトをこの記事では、他のIACツールよりもTerraformを選択した理由について、いくつかの非常に具体的な理由を説明します。 すべての技術的な決定と同様に、それはトレードオフと優先順位の問題であり、あなたの特定の優先順位は私たちとは異なるかもしれませんが、私たちの思考プロセスを共有することがあなた自身の決定を下すのに役立つことを願っています。 ここでは、私たちが検討した主なトレードオフがあります:

  • 構成管理Vsプロビジョニング
  • 変更可能なインフラストラクチャvs不変のインフラストラクチャ
  • 手続き型vs宣言的
  • マスター vsマスターレス
  • エージェントvsエージェントレス
  • 大規模なコミュニティvs小規模なコミュニティ
  • 成熟したvs最先端
  • 複数のツールを一緒に使用する

Chef、Puppet、Ansible、およびSaltStackは、すべての構成管理ツールです。既存のサーバーにソフトウェアをインストールおよび管理するように設計されています。 CloudFormationとTerraformはプロビジョニングツールであり、サーバー自体(およびロードバランサー、データベース、ネットワーク構成などのインフラストラクチャの残りの部分)をプロ ほとんどの構成管理ツールはある程度のプロビジョニングを行うことができ、ほとんどのプロビジョニングツールはある程度の構成管理を行うこ しかし、構成管理やプロビジョニングに焦点を当てることは、一部のツールが特定の種類のタスクに適していることを意味します。特に、DockerまたはPackerを使用している場合、構成管理のニーズの大部分はすでに処理されていることがわかりました。 DockerとPackerを使用すると、サーバーに必要なすべてのソフトウェアが既にインストールおよび構成されているイメージ(コンテナや仮想マシンイメージなど)を作 このようなイメージを取得したら、必要なのはそれを実行するためのサーバーだけです。 そして、あなたがする必要があるのがたくさんのサーバーをプロビジョニングすることだけであれば、Terraformのようなプロビジョニングツールは通常、設定管理

変更可能なインフラストラクチャと不変のインフラストラクチャ

Chef、Puppet、Ansible、SaltStackなどの構成管理ツールは、通常、変更可能なインフラストラクチャ たとえば、新しいバージョンのOpenSSLをインストールするようにChefに指示すると、既存のサーバーでソフトウェアの更新が実行され、変更はその場で行われます。 時間の経過とともに、更新プログラムを適用すると、各サーバーは一意の変更履歴を作成します。 これは、多くの場合、構成ドリフトと呼ばれる現象につながり、各サーバーが他のすべてのサーバーとわずかに異なり、診断が困難で再現がほぼ不可能な微妙な

DockerやPackerによって作成されたマシンイメージをデプロイするためにTerraformなどのプロビジョニングツールを使用している場合、すべての”変更”は実際には新 たとえば、新しいバージョンのOpenSSLをデプロイするには、新しいバージョンのOpenSSLが既にインストールされているPackerまたはDockerを使用して新しいイメージを作成し、そのイメージを完全に新しいサーバーのセットにデプロイしてから、古いサーバーをアンデプロイします。 この方法では、構成ドリフトのバグの可能性を減らし、サーバー上で実行されているソフトウェアを正確に知ることが容易になり、いつでも以前のバージョ もちろん、構成管理ツールに不変の展開を強制することも可能ですが、これらのツールの慣用的なアプローチではありませんが、プロビジョニングツールを使ChefとAnsibleは、目的の終了状態を達成する方法を段階的に指定するコードを記述する手続き型スタイルを推奨します。 Terraform、CloudFormation、SaltStack、およびPuppetはすべて、目的の終了状態を指定するコードを記述するより宣言的なスタイルを奨励し、IACツール自体がその状態を達成する方法を理解すたとえば、アプリのv1を実行するために10台のサーバー(AWS lingoの「EC2インスタンス」)をデプロイしたいとします。 ここでは、手続き型アプローチでこれを行うAnsibleテンプレートの簡略化された例を示します。

- ec2:
count: 10
image: ami-v1
instance_type: t2.micro

ここでは、宣言型アプローチを使用して同じことを行うTerraformテンプレートの簡略化された例を示します。

resource "aws_instance" "example" {
count = 10
ami = "ami-v1"
instance_type = "t2.micro"
}

表面では、これら二つのアプローチは似ている可能性があり、最初にAnsibleまたはTerraformでそれらを実行すると、同様のものが生成されます結果。 興味深いのは、あなたが変更を加えたいときに何が起こるかです。

たとえば、トラフィックが増加し、サーバーの数を15に増やしたいとします。 サーバーの数を15に更新してそのコードを再実行すると、15個の新しいサーバーがデプロイされ、合計25個になります。 そのため、代わりに、すでに展開されているものを認識し、5つの新しいサーバーを追加する全く新しい手続きスクリプトを記述する必要があります:宣言型コードでは、必要な終了状態を宣言するだけで、Terraformはその終了状態に到達する方法を把握するため、Terraformは過去に作成した状態も認識します。 したがって、さらに5つのサーバーを展開するには、同じTerraformテンプレートに戻り、カウントを10から15に更新するだけです。

resource "aws_instance" "example" {
count = 15
ami = "ami-v1"
instance_type = "t2.micro"
}

このテンプレートを実 実際、このテンプレートを実行する前に、Terraformのplanコマンドを使用して、どのような変更が行われるかをプレビューできます。

$ terraform plan+ aws_instance.example.11
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.12
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.13
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.14
ami: "ami-v1"
instance_type: "t2.micro"+ aws_instance.example.15
ami: "ami-v1"
instance_type: "t2.micro"Plan: 5 to add, 0 to change, 0 to destroy.

手続き的なアプローチでは、以前のAnsibleテンプレートの両方が再び役に立たないため、以前に展開した10台のサーバーを追跡するためにさらに別のテンプレートを)と慎重に新しいバージョンにそれぞれを更新します。 Terraformの宣言的なアプローチでは、まったく同じテンプレートにもう一度戻り、amiバージョン番号をv2に変更するだけです。

resource "aws_instance" "example" {
count = 15
ami = "ami-v2"
instance_type = "t2.micro"
}

明らかに、上記の例は簡略化されています。 Ansibleでは、新しいEC2インスタンスをデプロイする前にタグを使用して既存のEC2インスタンスを検索することができます(たとえば、instance_tagscount_tagパラメータを使用します)が、各リソースの過去の履歴に基づいてAnsibleで管理するすべてのリソースに対してこの種のロジックを手動で把握する必要がありますが、驚くほど複雑になる可能性があります(例: タグだけでなく、イメージバージョン、アベイラビリティーゾーンなどで既存のインスタンスを検索することもできます。 これは、手続き型IACツールの二つの主要な問題を強調しています。

  1. 手続き型コードを扱うとき、インフラストラクチャの状態がコード内に完全にキャプ 上記で作成した3つのAnsibleテンプレートを読むだけでは、何がデプロイされているのかを知るには不十分です。 また、これらのテンプレートを適用した順序も知っておく必要があります。 それらを別の順序で適用した場合、最終的には異なるインフラストラクチャになる可能性がありますが、それはコードベース自体では見られません。 言い換えれば、AnsibleまたはChefコードベースについて推論するには、これまでに発生したすべての変更の完全な履歴を知る必要があります。
  2. 手続き型コードの再利用性は、コードベースの現在の状態を手動で考慮する必要があるため、本質的に制限されています。 その状態は常に変化しているため、1週間前に使用したコードは、存在しなくなったインフラストラクチャの状態を変更するように設計されているため、使用できなくなる可能性があります。 その結果、手続き型コードベースは、時間の経過とともに大きく複雑になる傾向があります。

一方、Terraformで使用される一種の宣言的なアプローチでは、コードは常にインフラストラクチャの最新の状態を表します。 履歴やタイミングを気にすることなく、現在展開されている内容と構成方法を一目で確認できます。 これにより、世界の現在の状態を手動で考慮する必要がないため、再利用可能なコードを簡単に作成できます。 代わりに、目的の状態を記述することに焦点を当てるだけで、Terraformはある状態から別の状態に自動的に取得する方法を把握します。 その結果、Terraformコードベースは小さくて理解しやすい傾向があります。もちろん、宣言型言語にも欠点があります。 完全なプログラミング言語へのアクセスがなければ、あなたの表現力は限られています。 たとえば、ローリングダウンタイムゼロの展開など、一部の種類のインフラストラクチャの変更は、純粋に宣言的な用語で表現するのが困難です。 同様に、”ロジック”(if文、ループなど)を実行する機能がなければ、一般的で再利用可能なコードを作成するのは難しい場合があります(特にCloudFormationで)。 幸いなことに、Terraformは、入力変数、出力変数、モジュール、create_before_destroycountなどの強力なプリミティブを提供し、宣言型言語でもクリーンで構成可能なモジュー これらのツールについては、パート4、Terraformモジュールを使用して再利用可能なインフラストラクチャを作成する方法、パート5、Terraform tips&トリック:ループ、if文、および落とし穴で詳しく説明します。

Master Versus Masterless

デフォルトでは、Chef、Puppet、SaltStackはすべて、インフラストラクチャの状態を保存し、更新を配布するためにマスターサーバーを実行する必要があります。 インフラストラクチャ内の何かを更新するたびに、クライアント(コマンドラインツールなど)を使用してマスターサーバーに新しいコマンドを発行し、マスターサーバーは更新を他のすべてのサーバーにプッシュするか、それらのサーバーは定期的にマスターサーバーから最新の更新をプルダウンします。

マスターサーバーにはいくつかの利点があります。 まず、インフラストラクチャのステータスを表示および管理できる単一の中央の場所です。 多くの構成管理ツールは、マスターサーバーが何が起こっているのかを簡単に確認できるようにするためのwebインターフェイス(Chefコンソール、Puppet Enterprise Consoleなど)を提供し 第二に、一部のマスターサーバーはバックグラウンドで継続的に実行し、構成を強制することができます。 そうすれば、誰かがサーバー上で手動で変更を行った場合、マスターサーバーはその変更を元に戻して構成のドリフトを防ぐことができます。

しかし、マスターサーバーを実行する必要があることにはいくつかの深刻な欠点があります:

  • 余分なインフラストラクチャ:マスターを実行するだけで、余分なサーバー、または(高可用性とスケーラビリティのために)余分なサーバーのクラスターを展開
  • メンテナンス:マスターサーバーの保守、アップグレード、バックアップ、監視、およびスケールする必要があります。
  • セキュリティ:クライアントがマスターサーバーと通信する方法と、マスターサーバーが他のすべてのサーバーと通信する方法を提供する必要があります。

Chef、Puppet、SaltStackは、各サーバーでエージェントソフトウェアを実行するだけで、通常は定期的なスケジュール(例えば、5分ごとに実行されるcronジョブ)でマスターレスモー これにより、可動部品の数が大幅に削減されますが、次のセクションで説明するように、特にサーバーをプロビジョニングし、最初にエージェントソフトウェアをインストールする方法については、未回答の多くの質問が残されます。デフォルトでは、Ansible、CloudFormation、Heat、およびTerraformはすべてマスターレスです。 または、より正確に言うと、それらのいくつかはマスターサーバーに依存しているかもしれませんが、それはすでにあなたが使用しているインフラストラクチャの一部であり、あなたが管理しなければならない余分な部分ではありません。 たとえば、TerraformはクラウドプロバイダーのApiを使用してクラウドプロバイダーと通信するため、ある意味では、APIサーバーはマスターサーバーですが、余分なインフラストラクチャや余分な認証メカニズムを必要としません(つまり、APIキーを使用するだけです)。 AnsibleはSSH経由で各サーバーに直接接続することで機能するため、追加のインフラストラクチャを実行したり、追加の認証メカニズムを管理したりする必Chef、Puppet、およびSaltStackはすべて、構成する各サーバーにエージェントソフトウェア(Chef Client、Puppet Agent、Salt Minionなど)をインストールする必要があります。 エージェントは通常、各サーバー上でバックグラウンドで実行され、最新の構成管理更新プログラムのインストールを担当します。これにはいくつかの欠点があります。

  • ブートストラップ: どのようにサーバーをプロビジョニングし、最初の場所でそれらにエージェントソフトウェアをインス いくつかの設定管理ツールは、いくつかの外部プロセスがこれを処理すると仮定して、道を蹴ることができます(例えば、最初にTerraformを使用して、エージェントが既にインストールされているVMイメージを持つサーバーの束をデプロイします)。他の設定管理ツールには、クラウドプロバイダー Apiを使用してサーバーをプロビジョニングするための一回限りのコマンドを実行し、SSH経由でそれらのサーバーにエージェントソフトウェアをインストールする特別なブートストラッププロセスがあります。
  • メンテナンス: エージェントソフトウェアを定期的に慎重に更新し、マスターサーバーがある場合はマスターサーバーと同期しておくように注意する必要があります。 また、エージェントソフトウェアを監視し、クラッシュした場合は再起動する必要があります。
  • セキュリティ:エージェントソフトウェアがマスターサーバー(またはマスターを使用していない場合は他のサーバー)から構成をプルダウンする場合、すべてのサー マスターサーバーが構成をエージェントにプッシュする場合は、すべてのサーバーで受信ポートを開く必要があります。 いずれの場合も、エージェントが通信しているサーバーに対してエージェントを認証する方法を理解する必要があります。 このすべては、攻撃者にあなたの表面積を増加させます。

もう一度、Chef、Puppet、およびSaltStackには、エージェントレスモード(salt-sshなど)のサポートレベルがさまざまですが、これらは多くの場合、付け足しとして追加されたように感じ、設定管理ツールの完全な機能セットを常にサポートしているとは限りません。 そのため、野生では、Chef、Puppet、SaltStackのデフォルトまたは慣用的な設定には、ほとんどの場合、エージェントが含まれており、通常はマスターも含まれています。

これらの余分な可動部品はすべて、インフラストラクチャに多数の新しい故障モードを導入します。 午前3時にバグレポートを取得するたびに、アプリケーションコード、IACコード、configuration managementクライアント、マスターサーバー、またはクライアントがマスターサーバーと通信する方法、または他のサーバーがマスターサーバーと通信する方法、または…Ansible、CloudFormation、Heat、およびTerraformに追加のエージェントをインストールする必要がないかどうかを把握する必要があります。 または、より正確には、それらのいくつかはエージェントを必要としますが、これらは通常、使用しているインフラストラクチャの一部として既にイ たとえば、AWS、Azure、Google Cloud、およびその他のすべてのクラウドプロバイダーは、各物理サーバーにエージェントソフトウェアのインストール、管理、認証を行います。 Terraformのユーザーとして、あなたはそれのいずれかを心配する必要はありません:あなただけのコマンドを発行し、クラウドプロバイダーのエージェントは、すべての Ansibleを使用すると、サーバーはSSHデーモンを実行する必要があります。

大規模なコミュニティと小さなコミュニティ

あなたが技術を選ぶたびに、あなたはまた、コミュニティを選んでいます。 多くの場合、プロジェクトの周りのエコシステムは、技術自体の固有の品質よりもあなたの経験に大きな影響を与える可能性があります。 コミュニティは、プロジェクトに貢献する人の数、プラグイン、
統合、拡張機能の数、オンラインでヘルプを見つけるのがいかに簡単か(ブログ投稿、StackOverflow上の質問など)、あなたを助けるために誰かを雇うのがいかに簡単か(従業員、コンサルタント、サポート会社など)を決定します。

コミュニティ間で正確な比較を行うのは難しいですが、オンラインで検索することでいくつかの傾向を見つけることができます。 以下の表は、iacツールがオープンソースかクローズドソースか、サポートしているクラウドプロバイダー、GitHub上の貢献者とスターの総数、4月中旬から5月中旬までの1ヶ月間にコミットされたコミットとアクティブな問題の数、ツールに利用可能なオープンソースライブラリの数、StackOverflowにそのツールに記載されている質問の数、およびツールに言及しているジョブの数を含む、2019年5月に収集したデータと、一般的なIACツールの比較を示しています。Indeed.com.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です