AWS CloudFormation のベストプラクティス - AWS CloudFormation

AWS CloudFormation のベストプラクティス

ベストプラクティスはワークフロー全体で AWS CloudFormation をより効率的かつ安全に使用するために役立つ推奨事項です。スタックの計画方法と整理方法を学習し、リソースとそこで実行するソフトウェアアプリケーションを記述するテンプレートを作成して、スタックとそのリソースを管理します。次のベストプラクティスは、現在の CloudFormation のお客様の実際の経験に基づいています。

フィードバックループを短縮して配信速度を向上させる

CloudFormation テンプレートで記述したインフラストラクチャのフィードバックループを短縮するのに役立つ、プラクティスやツールを採用します。これには、ワークステーションで早期にテンプレートのリンティングとテストを行うことが含まれます。そうすることで、コントリビューションをソースコードリポジトリに送信する前でも、潜在的な構文や構成上の問題を発見する機会が得られます。このような問題を早期に発見することで、開発、品質保証、生産などの正式なライフサイクル環境に問題を持ち込まないようにすることができます。この早期テストによるフェイルファストのアプローチには、やり直しの待ち時間が減り、潜在的な影響範囲が減り、プロビジョニングオペレーションが成功する自信が高まるというメリットがあります。

フェイルファストの実践に役立つツールの選択肢には、「AWS CloudFormation Linter」(cfn-lint) や「TaskCat」コマンドラインツールが含まれます。cfn-lint ツールは、CloudFormation テンプレートを「AWS CloudFormation リソース仕様」に対して検証する機能をもたらします。これには、リソースプロパティの有効な値の確認やベストプラクティスが含まれます。cfn-lint のプラグインは多くのコードエディターで利用できます。エディター内の問題を視覚化し、リンターのフィードバックを直接得ることができます。ソースコードリポジトリの設定に cfn-lint を統合することも選択できるため、コントリビューションをコミットするときにテンプレートの検証を実行できます。詳細については、「cfn-lint による AWS CloudFormation テンプレートの Git コミット前検証」を参照してください。最初のリンティングを実行し、cfn-lint で発生した可能性のある問題を修正したら、選択した AWS リージョン にプログラムでスタックを作成することにより、TaskCat を使用してテンプレートをテストできます。TaskCat は、選択した各リージョンに対して合格/不合格の評価を含むレポートも生成します。

両方のツールを使用してフィードバックループを短縮する方法について、ステップバイステップで実践的なウォークスルーを行うには、「AWS CloudFormation ワークショップ」の「リンティングとテストラボ」に従ってください。

ライフサイクルと所有権によるスタックの整理

AWS リソースのライフサイクルと所有権を使用して、各スタックでどのリソースを使うを判断します。最初はすべてのリソースを 1 つのスタックに置いてもかまいませんが、スタックの規模が大きくなり範囲が拡大するにつれて、単一のスタックの管理は面倒で時間かかる場合があります。共通のライフサイクルと所有権を持つリソースのグループ化により、所有者は独自のプロセスやスケジュールを使用して、他のリソースに影響を与えることなくリソースのセットを変更できます。

たとえば、ロードバランサーの背後にある Amazon EC2 Auto Scaling インスタンスにホストされているウェブサイトを所有するデベロッパーおよびエンジニアのチームがあることを想定します。ウェブサイトは独自のライフサイクルを持ちウェブサイトチームによって保守されているため、このウェブサイトのスタックやそのリソースを作成できます。それでは、同様にバックエンドのデータベースを使用するウェブサイトがあり、そのデータベースは別のスタックでデータベース管理者が所有し保守しているとしましょう。ウェブサイトチームまたはデータベースチームがリソースを更新する必要があるときはいつでも、互いのスタックに影響を与えることなく実行できます。すべてのリソースが単一のスタックにある場合は、更新の連携や連絡は難しくなるでしょう。

スタックの整理についての詳細なガイダンスについては、2 つの一般的なフレームワークを使用できます。多層アーキテクチャーとサービス指向アーキテクチャー (SOA) です。

多層アーキテクチャーは、スタックを積み上げて構築する複数の水平の層に整理します。各層はその直下の層に依存します。各層には 1 つ以上のスタックを持つことができますが、各層のスタックは類似したライフサイクルと所有権を持つ AWS リソースを持つ必要があります。

サービス指向アーキテクチャーを使用すると、業務上の大きな問題を処理しやすい大きさに整理できます。これらのパートはそれぞれ、明確に定義された目的があり、機能の自己充足単位を表します。これらのサービスを、それぞれ独自のライフサイクルと所有者があるスタックにマッピングできます。これらのサービス (スタック) を 1 つに繋いで、相互に通信するようにできます。

クロススタック参照を使用して共有リソースをエクスポートします

ライフサイクルと所有権に基づいて AWS リソースを整理するときに、別のスタックにあるリソースを使用するスタックを構築することもできます。値をハードコード化または入力パラメータを使用して、リソース名と ID を渡すことができます。ただし、これらのメソッドはテンプレートの再利用を困難にしたり、スタック実行のオーバーヘッドを増やす場合があります。代わりに、スタックからリソースをエクスポートするクロススタック参照を使用すると、他のスタックがリソースを使用できます。スタックは Fn::ImportValue 関数を使用して、エクスポートされたリソースを呼び出して使用できます。

たとえば、VPC、セキュリティグループ、およびサブネットを含むネットワークスタックがあるかもしれません。すべてのパブリックウェブアプリケーションにこれらのリソースを使用する場合。リソースをエクスポートすることによって、パブリックウェブアプリケーションのすべてのスタックでリソースが使用できるようになります。詳細については、「デプロイされた CloudFormation スタックからエクスポートされた出力を取得する」を参照してください。

すべてのリソースタイプのクォータを確認する

スタックを起動する前に、必要なすべてのリソースを AWS アカウントの制限に触れずに作成できることを確認します。制限に触れる場合は、クオータを増やすかまたは追加リソースを削除するまで、CloudFormation でスタックが正常に作成されません。各サービスには、スタックを起動する前に知っておくべきさまざまな制限があります。たとえば、デフォルトでは、AWS アカウント でリージョンごとに起動できる CloudFormation スタックは 2,000 件のみです。制限およびデフォルトの制限を引き上げる方法の詳細については、「AWS 全般のリファレンス」の「AWS のサービスクォータ」を参照してください。

テンプレートを再利用して複数の環境にスタックを複製する

スタックとリソースをセットアップした後、テンプレートを再利用してインフラストラクチャを複数の環境に複製できます。たとえば、開発、テスト、本番の環境を作成して、本番環境に実装する前に変更をテストすることができます。テンプレートを再利用可能にするには、パラメーター、マッピング、および条件セクションを使用してスタックの作成時にカスタマイズできるようにします。たとえば、開発環境では、本番環境と比べて低価格のインスタンスタイプを指定し、その他の構成や設定は同じにできます。パラメーター、マッピング、条件の詳細については、「CloudFormation テンプレートセクション」を参照してください。

モジュールを使用してリソース構成を再利用する

インフラストラクチャが大きくなるにつれ、各テンプレートで同じコンポーネントを宣言する共通パターンができてきます。モジュールは、スタックテンプレート全体に含めるリソース構成をパッケージ化する、透過的で管理しやすく、繰り返し可能な方法です。モジュールは、共通のサービス構成とベストプラクティスを、スタックテンプレートに含めるためのモジュール式のカスタマイズ可能なビルディングブロックとしてカプセル化できます。

これらのビルディングブロックは、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスを定義するためのベストプラクティスなど、単一のリソース用にすることも、アプリケーションアーキテクチャの一般的なパターンを定義するために、複数のリソース用にすることもできます。これらのビルディングブロックは他のモジュールにネストできるため、ベストプラクティスを上位レベルのビルディングブロックに積み重ねることができます。CloudFormation モジュールは CloudFormation レジストリで利用できるため、ネイティブリソースのように使用できます。CloudFormation モジュールを使用すれば、モジュールテンプレートが使用テンプレートに展開され、Ref または Fn::GetAtt を使用してモジュール内のリソースにアクセスできるようになります。詳細については、「CloudFormation モジュールを使用してテンプレート全体に含めることができる再利用可能なリソース設定の作成」を参照してください。

AWS 固有のパラメータタイプを使用する

テンプレートは、既存の Amazon Virtual Private Cloud ID または Amazon EC2 キーペア名など、既存の AWS 固有値の入力が必須の場合、AWS 固有のパラメータタイプを使用します。たとえば、パラメータを AWS::EC2::KeyPair::KeyName タイプに指定すると、これには AWS アカウント と、スタックを作成したリージョンにある既存のキーペア名を使用できます。AWS CloudFormation は、スタックを作成する前に、すばやく AWS 固有パラメータタイプの値を検証します。また、CloudFormation コンソールを使用する場合、CloudFormation が有効な値のドロップダウンリストを表示するため、正しい VPC ID またはキーペア名を調べたり暗記したりする必要はありません。詳細については、「CloudFormation が提供するパラメータタイプを使用する、既存のリソースと Systems Manager パラメータの参照」を参照してください。

パラメータの制約の使用

制約を使用すると、許可される入力値を記述することで CloudFormation がスタックを作成する前に無効な値を捕捉できます。最小文字数、最長文字数、許可パターンなどの制限を設定できます。例えば、データベースのユーザー名の値は最小 8 文字で英数字のみ、といった制限を設定できます。詳細については、「CloudFormation テンプレートの Parameters セクション構文リファレンス」を参照してください。

疑似パラメータを使用して移植性を高める

テンプレート内の疑似パラメータを、RefFn::Sub などの組み込み関数の引数として使用できます。擬似パラメータは、CloudFormation によって事前定義されたパラメータです。テンプレートでは宣言しません。組み込み関数で擬似パラメータを使用すると、リージョンおよびアカウント間でスタックテンプレートのポータビリティが向上します。

例えば、特定のリソースプロパティについて、別の既存リソースの Amazon リソースネーム (ARN) を指定する必要があるテンプレートを作成したいとします。この場合、既存のリソースは ARN: arn:aws:ssm:us-east-1:123456789012:parameter/MySampleParameter を持つ AWS Systems Manager パラメータストアリソースです。「ARN 形式」を対象の AWS パーティション、リージョン、アカウント ID に合わせる必要があります。これらの値をハードコーディングする代わりに、AWS::PartitionAWS::RegionAWS::AccountId の疑似パラメータを使用してテンプレートの移植性を高めることができます。この場合に CloudFormation で ARN 内の要素を連結する方法の例としては、!Sub 'arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/MySampleParameter があります。

別の例として、リソースや設定を複数のスタック間で共有したいとします。この例では、VPC のサブネットを作成し、その ID を同じ AWS アカウント とリージョンで他のスタックと使用するためにエクスポートしたことを想定します。別のスタックでは、Amazon EC2 インスタンスを記述するときに、サブネット ID のエクスポートされた値を参照します。Export 出力フィールドと Fn::ImportValue組み込み関数の詳細な使用例については、別の CloudFormation スタックのリソース出力を参照する を参照してください。

スタックのエクスポートは、アカウントおよびリージョンごとに一意である必要があります。そのため、この場合は、AWS::StackName 擬似パラメータを使用してエクスポート用のプレフィックスを作成できます。スタック名もアカウントおよびリージョンごとに一意であることが必要なため、この疑似パラメータをプレフィックスとして使用すると、一意のエクスポート名を持つ可能性が高くなるだけではなく、値をエクスポートするスタック全体の再利用可能なアプローチも促進されます。また、任意のプレフィックスを使用することも可能です。

AWS::CloudFormation::Init を使用して Amazon EC2 インスタンスにソフトウェアアプリケーションをデプロイ

スタックを起動すると、cfn-init ヘルパースクリプトおよび AWS::CloudFormation::Init リソースを使用して、Amazon EC2 インスタンスにソフトウェアアプリケーションをインストールして設定できます。AWS::CloudFormation::Init を使用することで、スクリプトで手順を順番に実行するよりも自由に構成を記述できます。また、インスタンスを作り直すことなく構成を更新できます。また、構成に不具合があれば、CloudFormation が生成するログで問題を調査できます。

テンプレートで、AWS::CloudFormation::Init リソースにインストールと構成の状態を指定します。cfn-init および AWS::CloudFormation::Init の使用方法を記載したウォークスルーについては、「Amazon EC2 にアプリケーションをデプロイする」を参照してください。

最新のヘルパースクリプトを使用する

ヘルパースクリプトは定期的に更新されます。テンプレートの UserData プロパティに必ず次のコマンドを含めてからヘルパースクリプトを呼び出し、起動したインスタンスで最新のヘルパースクリプトを取得できるようにしてください。

yum install -y aws-cfn-bootstrap

最新のヘルパースクリプトの取得の詳細については、「CloudFormation ヘルパースクリプトリファレンス」を参照してください。

テンプレートを使用する前に検証する

スタックの作成または更新にテンプレートを使用する前に、CloudFormation を使用してテンプレートを検証できます。テンプレートを検証することで、CloudFormation がリソースを作成する前に、依存関係の循環などの構文エラーや意味的エラーを捕捉するのに役立ちます。CloudFormation コンソールを使用する場合は、入力パラメータを指定するとコンソールが自動的にテンプレートを検証します。AWS CLI または CloudFormation API の場合は、validate-template CLI コマンドまたは ValidateTemplate API 操作を実行してください。

検証中に、CloudFormation はテンプレートが有効な JSON であるかどうかをまず確認します。そうでない場合は、CloudFormation はテンプレートが有効な YAML であるかどうかを確認します。両方のチェックが失敗すると、CloudFormation はテンプレートの検証エラーを返します。

組織のポリシーに準拠するためにテンプレートを検証する

組織ポリシーガイドラインのコンプライアンス用のテンプレートを検証することもできます。AWS CloudFormation Guard (cfn-guard) は、オープンソースのコマンドラインインターフェース (CLI) ツールです。これは、コードとしてのポリシー言語を提供し、必要なリソースと禁止されたリソースの両方の構成をチェックできるルールを定義します。その後、これらのルールに対してテンプレートを検証できます。たとえば、管理者はルールを作成して、ユーザーが常に暗号化された Amazon S3 バケットを作成するようにできます。

ユーザーは、テンプレートの編集中にローカルで、または CI/CD パイプラインの一部として自動的に cfn-guard を使用して、非準拠リソースのデプロイメントを停止できます。

さらに、cfn-guard には、既存の準拠 CloudFormation テンプレートからルールを抽出できる機能 rulegen が含まれています。

詳細については、GitHub の cfn-guard リポジトリを参照してください。

AWS CloudFormation ですべてのスタックリソースを管理する

スタックを起動した後、CloudFormation コンソールAPIAWS CLI を使用して、スタック内のリソースを更新します。スタックのリソースを CloudFormation 以外の方法で変更しないでください。変更するとスタックのテンプレートとスタックリソースの現在の状態の間で不一致が起こり、スタックの更新または削除でエラーが発生する場合があります。これをドリフトと呼びます。CloudFormation テンプレート外でリソースが変更され、その後にスタックを更新すると、リソースに直接行われた変更は破棄され、リソース設定はテンプレートの設定に戻ります。

ドリフトの詳細については、「ドリフトとは」を参照してください。

スタックの更新に関する詳細は、「チュートリアル: スタックの更新」を参照してください。

スタックを更新する前に変更セットを作成する

変更セットは、スタックの変更案が実行中のリソースに与える影響を、実装前に確認できるようにします。CloudFormation は、変更セットが実行するまでスタックを変更しないため、変更案のまま続行するか、別の変更案を作成するかを決定できます。

変更セットを使用して、変更が実行中のリソース、特に重要なリソースに与える可能性のある影響を確認できます。例えば、Amazon RDS データベースインスタンスの名前を変更すると、CloudFormation によって新しいデータベースが作成され、古いものは削除されます。古いデータベースのデータをバックアップしていないと、データは失われます。変更設定を生成することで、変更によってデータベースが置き換えられることがわかります。このように、スタックを更新する前に計画を立てることができます。詳細については、「変更セットを使用して CloudFormation スタックを更新する」を参照してください。

スタックポリシーを使用する

スタックポリシーは、重要なスタックリソースを保護して、意図しない更新でリソースが中断されたり置き換えられるのを防ぎます。スタックポリシーは、指定したリソースに対して実行できる更新アクションを記述する JSON ドキュメントです。重要なリソースがあるスタックを作成するときは常に、スタックポリシーを指定してください。

スタックの更新中に、保護されたリソースを明示的に指定して更新する必要があります。指定しない場合は保護されたリソースは変更されません。詳細については、「スタックのリソースが更新されないようにする」を参照してください。

コードの確認とリビジョン管理を使用してテンプレートを管理する

スタックのテンプレートには、プロパティ値などの AWS リソースの構成が記述されています。リソースの変更を確認し正確な履歴を保持するには、コードの確認とリビジョン管理を使用します。この方法は、テンプレートの異なるバージョン間の変更を追跡するのに役立ちます。また、スタックリソースの変更を追跡するのにも役立ちます。また、履歴を保守することで、いつでもスタックをテンプレートの特定のバージョンに戻すことができます。

Amazon EC2 インスタンスを定期的に更新

CloudFormation で作成されたすべての Amazon EC2 Windows インスタンスと Amazon EC2 Linux インスタンスに対して、定期的に yum update コマンドを実行して RPM パッケージを更新します。こうすることで、最新の修正およびセキュリティの更新を確実に取得します。