こんにちは。サニービュー事業部の小寺です。

みなさんは、CloudFormationを利用されていますか。
今日は、CloudFormationを利用して環境を展開するときのベストプラクティスについてお伝えします。
本記事では、CloudFormationとは何か?、基本的な使い方については割愛しています。

CloudFormationとは

CloudFormationtとは、リソースの設定やプロビジョニングをコード化したテンプレートを使って、AWSでの環境構築を容易に行うことができるサービスです。以下の特徴があります。

・AWSリソースをテンプレートを使って、自動で作成できる
・テンプレートを作成すると、同じ構成で構築ができる
・CloudFormationのテンプレートは無料で使えます。料金がかかるのは、CloudFormationで構築したサービス分のみ

CloudFormationのベストプラクティス

ここでは、CloudFormationを効果的により安全に使える方法について、お伝えします。
ベストプラクティスなので、推奨事項だとご認識していただければと思います。

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

スタックを整理しましょう。
使い始めたときは、すべてのリソースを 1 つのスタックに置いても良いと思います。スタックの規模が大きくなり範囲が拡大するにつれて、単一のスタックの管理は面倒で時間かかる場合があります。

共通のライフサイクルと所有権を持つリソースをグループ化してみます。
グループ化を行うことで、所有者は独自のプロセスやスケジュールを使用して、他のリソースに影響を与えることなくリソースのセットを変更できます。

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

AWSリソースを整理するときに、別のスタックにあるリソースを使うスタックも作ることができます。値をハードコード化する、または入力パラメーターを使用して、リソース名と ID を割り当てることもできます。

ただし、上記の方法は管理が煩雑になってしまいます。
そのため、スタックからリソースをエクスポートするクロススタック参照を利用します。
スタックは Fn::ImportValue 関数を使用して、エクスポートします。
(例)スタック A エクスポート

“Outputs” : {
“PublicSubnet” : {
“Description” : “The subnet ID to use for public web servers”,
“Value” : { “Ref” : “PublicSubnet” },
“Export” : { “Name” : {“Fn::Sub”: “${AWS::StackName}-SubnetID” }}
},
“WebServerSecurityGroup” : {
“Description” : “The security group ID to use for public web servers”,
“Value” : { “Fn::GetAtt” : [“WebServerSecurityGroup”, “GroupId”] },
“Export” : { “Name” : {“Fn::Sub”: “${AWS::StackName}-SecurityGroupID” }}
}
}

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

スタックを起動する前に、必要なすべてのリソースをAWSで設定されたサービスクォータの制限に抵触しないように確認しておきましょう。
デフォルトでは、AWS アカウントのリージョンごとに起動できる AWS CloudFormation スタックは 200です。サービスクォータの上限申請はAWS Service Quotas コンソール を使用して、内容の表示と引き上げのリクエストができます。

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

スタックとリソースをセットアップした後に、テンプレートを再利用してインフラストラクチャを複数の環境に複製できます。
テンプレートを再利用可能にするには、パラメーター、マッピング、および条件セクションを使用してスタックを作っておくときに、カスタマイズしておきましょう。
【例】
・Parametersで作成時に環境名を指定できるようにする
・Mappingで本番環境と検証環境をそれぞれ定義しておく
・Outputsで文字列結合した値を渡す

・ネストされたスタックを使用して共通テンプレートパターンを再利用する

インフラストラクチャが大きくなるにつれ、各テンプレートで同じコンポーネントを宣言する共通パターンができてきます。これらの共通するコンポーネントを他と分類し、専用テンプレートを作成できます。
専用テンプレートができると、異なるテンプレートを組み合わせることができます。

ここで、単一の統合されたスタックを作成するにはネストされたスタックを使用しましょう。
AWS::CloudFormation::Stackを利用します。
ネスト用のスタックを指定して作成すると、「ネストされた」と表示がされて作成完了になります。

・AWS 固有のパラメータタイプの使用

テンプレートに Amazon Virtual Private Cloud ID や Amazon EC2 キーペア名など既存の AWS 固有値の入力が必須の場合は、AWS 固有パラメータタイプを使用します。

【例】サポートされている AWS 固有のパラメータタイプEC2
サポートされている AWS 固有のパラメータタイプ
AWS CloudFormation では次の AWS 固有型をサポートしています。
・AWS::EC2::AvailabilityZone::Name
アベイラビリティーゾーン (us-west-2a など)。

・AWS::EC2::Image::Id
Amazon EC2 イメージ ID (ami-0ff8a91507f77f867 など)。AWS CloudFormation コンソールには、このパラメータータイプの値のドロップダウンリストが表示されないことに注意してください。

・AWS::EC2::Instance::Id
Amazon EC2 インスタンス ID (i-1e731a32 など)。
・AWS::EC2::KeyPair::KeyName
Amazon EC2 のキーペア名。
・AWS::EC2::SecurityGroup::GroupName
EC2-Classic またはデフォルトの VPC セキュリティグループ名 (my-sg-abc など)。
・AWS::EC2::SecurityGroup::Id
セキュリティグループ ID (sg-a123fd85 など)。
・AWS::EC2::Subnet::Id
サブネット ID (subnet-123a351e など)。
・AWS::EC2::Volume::Id
Amazon EBS ボリューム ID (vol-3cdd3f56 など)。
・AWS::EC2::VPC::Id
VPC ID (vpc-a123baa3 など)。

・パラメータの制約の使用

制約を使用すると、許可される入力値を記述することで AWS CloudFormation がスタックを作成する前に無効な値が判別可能です。最小文字数、最長文字数、許可パターンなどの制限を設定することができます。

Defaultを使うと、スタックの作成時に値を指定しなかった場合に、テンプレートで使用される適切な型の値を決めておくことができます。

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

スタックを起動する際に、cfn-init ヘルパースクリプトと AWS::CloudFormation::Init リソースを使用して、Amazon EC2 インスタンスでソフトウェアアプリケーションをインストールして設定できます。

AWS::CloudFormation::Init を使用することで、例えば、EC2を作成する場合
インスタンス起動後にパッケージのインストールやファイル作成、コマンド実行を含めることができます。
また、メリットはスタック更新時にメタデータの変更も検知して再実行することもできます。

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

ヘルパースクリプトは定期的に更新されます。ヘルパースクリプトを使用する場合は、必ずスクリプトの最新バージョンを使用してインスタンスを起動してください。スクリプトを呼び出す前に、テンプレートの UserData プロパティに次のコマンドを含めます。
# yum install -y aws-cfn-bootstrap

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

スタックの作成または更新にテンプレートを使用する前に、AWS CloudFormation を使用してテンプレートを検証してみましょう。
検証しておくことで、事前の構文エラーなどを確認することができます。

1)AWS CloudFormation はテンプレートが有効な JSONかどうかチェック
2)AWS CloudFormation はテンプレートが有効な YAML であるかどうかチェック
3)1), 2)両方のチェックが失敗すると、AWS CloudFormation はテンプレートの検証エラーを返す

AWS CloudFormation Guard (cfn-guard) は、オープンソースのコマンドラインインターフェイス (CLI) ツールです。コードとしてのポリシー言語を提供し、必要なリソース設定と禁止されたリソース設定の両方をチェックできるルールを定義することができます。

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

スタックを起動した後、AWS CloudFormation コンソール、API、または AWS CLI を使用して、スタック内のリソースを更新します。
AWS CloudFormation以外の方法で、変更するとスタックのテンプレートとスタックリソースの現在の状態の間で不一致が起こり、スタックの更新または削除でエラーが発生する場合があります。

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

変更セットによって、スタックの更新前にリソースの更新や削除を把握することができます。AWS CloudFormation では変更セットが実行されるまでスタックは変更されないため、変更案のまま続行するか別の変更案を作成するかを検証して、決めることができます。

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

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

{
“Statement” : [
{
“Effect” : “Allow”,
“Action” : “Update:“, “Principal”: ““,
“Resource” : “” }, { “Effect” : “Deny”, “Action” : “Update:“,
“Principal”: “*”,
“Resource” : “LogicalResourceId/ProductionDatabase”
}
]
}

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

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

まとめ

いかがでしたでしょうか。
本日はCloudFormationをより活用いただくためのベストプラクティスについて、お伝えしました。

AWSをご利用いただくには、直接契約するより断然お得。
AWS利用料が5%割引、さらに日本円の請求書による支払いが可能です!