目次
はじめに
こんにちは、クラウド事業部の菅です。
ClouFormationで作成したリソースが、手動などで変更されて困った経験はありませんか?
スタックとリソースとで設定に差異が生じている状態は、トラブルの原因にもなります。
AWSには、スタックとリソースとの設定の差異を検出する機能があります。
今回は、CloudFormationのドリフト検出機能についてご紹介いたします。
ドリフトとは?
AWSのページには、ドリフト(構成ドリフト)とは「システム構成がビジネス要件や関連環境と一致しなくなったこと」とあります。
CloudFormationの場合、スタックで定義された構成とリソースに差分が生じている状態を指します。
ドリフトが発生している状態は、構成を正確に把握できないだけでなく、スタック更新時に予期せぬ問題が発生する恐れがあります。
例えば、以下のスタックを作成し、作成したSecurityGroupに手動で変更を加えたとします。

手動変更1 : タグ追加

※手動で test というタグを追加しています。
手動変更2 : インバウンドルール追加

※手動で上記インバウンドルールを追加しています。
この状態で、以下のテンプレートファイルを使用してスタックを更新するとどうなるでしょうか?
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SecurityGroup
VpcId:
Ref: VpcId
Tags:
- Key: Name
Value: sg-test
- Key: User
Value: apc-kan
SecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId:
Fn::GetAtt: SecurityGroup.GroupId
IpProtocol: TCP
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/24
Description: stack
※赤字が更新部分
上記テンプレートでスタックを更新すると、以下の状態となります。
スタック更新後 : タグ

スタック定義(NameとUser)だけでなく、手動追加(test)のタグも登録されています。
スタック更新後 : インバウンドルール

説明が更新されていないことから、スタック定義の内容は反映されず手動設定のままとなっています。
※画像は取得していませんが、このときスタック更新は成功しています。
上記のように、ドリフトによってスタックでの構成管理が困難となり、スタック更新時も意図した変更が行われない場合があります。
このように、スタックを使用したリソース管理ではドリフトは非常に厄介な存在となります。
CloudFormationのドリフト検出機能
CloudFormationでは、スタック定義の構成とリソースとの差分をドリフトとして検出することができます。
ほとんどのリソースタイプでドリフトの検出が可能ですが、一部のリソースタイプはドリフト検出に対応していません。
また、以降で説明しますが、ドリフト検出に対応しているリソースタイプでもスタックの構成によっては検出できない場合があります。
ドリフト検出を行う場合、対象となるリソースタイプの読み取り権限が必要となります。
また、KMSKeyIdプロパティに対するドリフト検出は実行されないようです。
ドリフト検出の実行
ドリフトとは?で作成したスタックに対してドリフト検出を行ってみます。
ドリフトの検出はCloudFormationのページから対象スタックを選択し、スタックアクション > ドリフトの検出 から実行します。

ドリフト検出の結果は、スタックの情報のドリフトステータスから確認することができます。
今回はドリフトが発生していますので、ドリフトステータスが「DRIFTED」となっています。

スタックの情報画面で表示されるドリフトステータスは以下の通りです。
ステータス | 説明 |
---|---|
NOT_CHECKED | ドリフトの検出が行われていない状態です。 |
IN_SYNC | スタック内のリソースにドリフトが発生していない状態です。 スタック内に検出可能なリソースが存在しない場合もこのステータスが表示されます。 |
DRIFTED | スタック内の1つ以上のリソースでドリフトが発生している状態です。 ドリフトが発生しているリソースはスタックアクションから確認することができます。 |
スタック内のドリフトの詳細は、スタックアクション > ドリフト結果を表示 から確認できます。

ドリフト画面では、スタックに定義されているリソース単位でドリフト検出結果が表示されます。

※SecurityGroupIngressはSecurityGroupの一部として扱われるため一覧に表示されません。
ドリフト画面で表示されるドリフトステータスは以下の通りです。
ステータス | 説明 |
---|---|
NOT_CHECKED | 対象リソースのドリフト検出が行われていない状態です。 |
IN_SYNC | 対象リソースにドリフトが発生していない状態です。 |
MODIFIED | 対象リソースにドリフトが発生している状態です。 リソースにスタック定義とは異なる値が設定されている場合に表示されます。 |
DELETED | 対象のリソースにドリフトが発生している状態です。 スタック定義されているリソースが存在しない場合に表示されます。 |
リソース内のドリフトの詳細は、リソースを選択して ドリフトの詳細を表示 を選択することで確認できます。

ドリフトの詳細画面では、ドリフトが発生しているプロパティが「違い」に一覧表示されます。
「違い」内の各プロパティを選択することで、詳細な差分をJSON形式で確認することができます。

注意が必要なリソースタイプ
ドリフトとは?でも記載しましたが、ドリフト検出に対応しているリソースタイプでもスタックの構成によっては検出できないものがあります。
例えば、SecurityGroupIngressは同一スタック内に設定対象のSecurityGroupが定義されているかどうかでドリフト検出の可否が異なります。
同一スタック内に設定対象のセキュリティグループが定義されている場合

※SecurityGroupのドリフトとして検出されます。
同一スタック内に設定対象のセキュリティグループが定義されていない場合

※スタック作成後、説明(Description)の設定を手動変更しています。

※スタック内に適用対象のセキュリティグループが定義されていないため、SecurityGroupIngressは検出対象外となります。
対象外となったことでドリフト発生リソースが存在しなくなり、スタックのドリフトステータスがIN_SYNCとなっています。
SecurityGroupIngress以外にも、同様のリソースタイプが存在します。
詳細は以下に記載されておりますので、ご参照ください。
様々な状況でのドリフト検出
スタックで定義していないプロパティを変更した場合
スタックでは定義されていない、デフォルト値が適用されているプロパティが変更された場合の挙動を確認します。
以下のスタックを作成し、作成したEC2インスタンスの送信元/送信先チェック(デフォルト値 : 有効)を手動で停止させます。

※スタック作成後、手動で送信元/送信先チェックを変更(停止)しています。

送信元/送信先チェックの変更は、ドリフトとして検出されませんでした。
ドリフトの検出対象は、あくまでスタックで明記されているプロパティのみを対象とするようです。
SecurityGroupルール削除後に同じルールを手動で追加した場合
スタックで作成したセキュリティグループルールを手動削除し、その後手動で同じルールを設定した場合の挙動を確認します。
以下のスタックを作成し、作成したインバウンドルールを手動削除します。
また、削除後に同じインバウンドルールを手動追加します。

※スタック作成後、手動でインバウンドルールを削除・同一ルールの追加を行っています。

手動修正によりセキュリティグループIDは変更されていましたが、ドリフトステータスは IN_SYNC となりました。
すべてのリソースではないかもしれませんが、ドリフトチェックではスタックによって作成されたかどうかまではチェックしないようです。
ちなみに、この状態のセキュリティグループルールも、スタックから問題なく更新できました!
ドリフト検出の定期実行
AWS Configのマネージドルールの1つ「cloudformation-stack-drift-detection-check」を使用することで、スタックのドリフト検出を定期的に実行することができます。
また、マルチリージョンやマルチアカウントでのドリフト発生を検知することもできるようです。
詳しくは、以下をご参照ください。
まとめ
今回はスタックのドリフト検出機能についてご紹介しました。
CloudFormationで管理しているつもりでも、いつの間にかドリフトが発生している可能性があります。
私も以前、確認のため手動追加した経路情報の削除を忘れたままスタックを更新してしまい、後々トラブルになったことがあります。
ドリフトを放置すると影響範囲が広がり、修正作業が複雑化する恐れがあります。
今回は手動によるドリフト検出のみご紹介しましたが、AWS Configなどを利用して定期的にドリフト発生を検知し、早い段階で対処することが重要です。
この記事が誰かのお役に立てば幸いです。
お知らせ
APCはAWS Advanced Tier Services (アドバンストティアサービスパートナー) 認定を受けております。
その中で私達クラウド事業部はAWSなどのクラウド技術を活用したSI/SESのご支援をしております。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。