CloudFormation StackSets でドリフトを検出する方法 ── 複数リージョンに配ったリソースの手動変更を見つける

目次

概要

CloudFormation StackSets を使うと、1 つのテンプレートから、複数のアカウント・複数のリージョンへ同じスタックを配れます。ログの設定や監視用のリソースなど、どこでもそろえておきたいものを配るのに便利です。

ところが運用していると、誰かがある 1 つのリージョンだけ、コンソールから設定を手で変えてしまうことがあります。テンプレートの定義と実際のリソースがずれた状態を ドリフト と呼びます。StackSets には、配ったすべてのスタックインスタンスについて、まとめてドリフトを調べる ドリフト検出 があります。CloudTrail のログから変更を探して回る必要はありません。

この記事では、StackSets の構成要素と、ドリフト検出の結果(StackSet・スタックインスタンス・リソースの 3 段階)の見方を整理します。実践では、1 つのアカウントの東京と大阪の 2 リージョンに StackSet でパラメータを配り、大阪の値だけを手で変えて、ドリフト検出で見つけるところまでを行います。

1 つのアカウントの東京・大阪に StackSet で配り、大阪だけが手で変更されてドリフトになる
1 つのアカウントの東京・大阪に StackSet で配り、大阪だけが手で変更されてドリフトになる
クラウドおさる

長老会が「どの猿山の倉庫も、扉の札はこう書く」と決めて配ったのに、大阪の猿山だけ札が勝手に書き換わっていた。そんなずれを、全部の猿山まとめて見つけに行くのでござる。

この記事のメリット

  • StackSets の管理者アカウント・ターゲットアカウント・スタックインスタンスの関係を説明できるようになる
  • セルフマネージド型とサービスマネージド型のアクセス許可の違いが分かる
  • StackSet のドリフト検出を実行し、どのスタックインスタンスのどのプロパティが変わったかを確認できるようになる
  • 手動変更の「検出」と、CloudFormation フックなどの「事前の検証」の違いを整理できる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。

クラウドおさる

基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

StackSets の構成要素

用語意味
StackSet配るテンプレートと設定のまとまり。管理者アカウントの 1 つのリージョン(管理リージョン)に作る
管理者アカウントStackSet を作るアカウント
ターゲットアカウントスタックが作られるアカウント。管理者アカウント自身もターゲットにできる
スタックインスタンス「アカウント × リージョン」ごとのスタックへの参照。実体は各リージョンの通常のスタック
オペレーション作成・更新・削除・ドリフト検出などの処理の単位。履歴が残る

アクセス許可のモデルは 2 つあります。

モデル仕組み向いている場面
セルフマネージド型管理者アカウントに管理ロール(AWSCloudFormationStackSetAdministrationRole)、ターゲットアカウントに実行ロール(AWSCloudFormationStackSetExecutionRole)を自分で作るOrganizations を使わない、または単一アカウントで複数リージョンに配る
サービスマネージド型AWS Organizations と連携し、必要な IAM ロールを StackSets が作る。組織に加わったアカウントへの自動デプロイもできる組織の管理アカウント(または委任管理者)から、組織単位でまとめて配る

セルフマネージド型では、StackSets が管理ロールを引き受け、そこから各ターゲットアカウントの実行ロールを引き受けてスタックを操作します。実行ロールの公式テンプレートは全権限を持つので、配るリソースの種類に合わせて権限を絞るのが推奨です。

セルフマネージド型: 管理ロールから実行ロールを引き受けて各リージョンのスタックを操作する
セルフマネージド型: 管理ロールから実行ロールを引き受けて各リージョンのスタックを操作する

StackSet のドリフト検出

StackSet のドリフト検出は、各スタックインスタンスのスタックについて、リソースの現在の状態とテンプレート・パラメータで定義した状態を比べます。結果は 3 段階で積み上がります。

  • 1 つでもリソースが変わっていれば、そのスタックインスタンスが DRIFTED
  • 1 つでもスタックインスタンスが DRIFTED なら、StackSet が DRIFTED
  • すべて一致していれば IN_SYNC

リソース単位では、プロパティが変わったものは MODIFIED、消されたものは DELETED と表示され、期待値と現在の値を見比べられます。

クラウドおさる

StackSet → スタックインスタンス → リソース、と大きい単位から順に絞り込むのでござる。猿山の一覧で赤い札の山を見つけ、その山の倉庫、その倉庫の扉、と降りていく感じでござるな。

押さえておきたい性質があります。

  • ドリフトとして扱うのは CloudFormation の外で行われた変更だけ。CloudFormation 経由で個別のスタックを更新した差は対象外
  • 1 つの StackSet で同時に実行できるドリフト検出は 1 つだけ
  • 各スタックで個別に実行したドリフト検出の結果は、StackSets のコンソールには表示されない
  • ドリフト検出は差を「見つける」だけで、元に戻さない。戻すなら手で直すか、意図した変更ならテンプレートを直して StackSet を更新する
クラウドおさる

CloudFormation フックはリソースを作る前にテンプレートを確かめる仕組み、SCP は操作を止める仕組みでござる。どちらも「作ったあとに手で変えられた」ことは見つけてくれぬ。検出したいならドリフト検出でござるぞ。

単一のスタックを定期的に調べたいときは、AWS Config のマネージドルール cloudformation-stack-drift-detection-check で、スタックのドリフトを継続的に評価する方法もあります。

新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

実践

ハンズオンガイド7 ステップ画面 5 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

1 つのアカウントで、東京(管理リージョン)に StackSet soa-stackset-drift を作り、東京 ap-northeast-1 と大阪 ap-northeast-3 の 2 リージョンにスタックインスタンスを配ります。テンプレートは Systems Manager パラメータストアの標準パラメータを 2 つ作るだけなので、課金は発生しません。大阪のパラメータの値を手で書き換えてから、ドリフト検出で見つけます。

前提条件

  • リージョン: ap-northeast-1(東京)を管理リージョンとし、ap-northeast-3(大阪)にも配る
  • 以下のリソースが作成済みであること

まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。

リソース種別リソース名内容作り方の参考
IAM ロール(管理ロール)AWSCloudFormationStackSetAdministrationRole信頼: cloudformation.amazonaws.com。許可: AWSCloudFormationStackSetExecutionRole への sts:AssumeRoleAWS IAM でユーザー・ロール・ポリシーを作成しアクセス制御する
IAM ロール(実行ロール)AWSCloudFormationStackSetExecutionRole信頼: 自分のアカウント。許可: cloudformation:* と SSM パラメータの作成・参照・削除同上

StackSet で配るテンプレートは次の内容です。soa-stackset-drift.yaml という名前で手元に保存しておきます。

AWSTemplateFormatVersion: "2010-09-09"
Description: soa12 - StackSets drift detection sample (SSM parameters only)

Resources:
  LogLevel:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /soa/stackset/log-level
      Type: String
      Value: INFO
      Description: Application log level (managed by StackSets)

  MaintenanceMode:
    Type: AWS::SSM::Parameter
    Properties:
      Name: /soa/stackset/maintenance-mode
      Type: String
      Value: "off"
      Description: Maintenance mode switch (managed by StackSets)

作成するリソース一覧

リソース種別リソース名用途
StackSetsoa-stackset-drift東京・大阪にテンプレートを配る
スタックインスタンス自分のアカウント × ap-northeast-1 / ap-northeast-3各リージョンのスタック(StackSet-soa-stackset-drift-…)
SSM パラメータ/soa/stackset/log-level、/soa/stackset/maintenance-mode(各リージョン)StackSet が作る。大阪の log-level を手で変える

手順 1: StackSet を作る

AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。上部の検索バーに CloudFormation と入力し、「CloudFormation」を選択します。

左側ナビゲーションの「StackSets」を選択し、「StackSet を作成」をクリックします。以下を設定します。

  • アクセス許可: 「セルフサービスのアクセス許可」(既定は「サービスマネージドアクセス許可」なので切り替えます)
  • IAM 管理ロール ARN – オプション: 1 つ目のドロップダウンで「IAM Role Name」、2 つ目で AWSCloudFormationStackSetAdministrationRole を選択
  • IAM 実行ロール名: AWSCloudFormationStackSetExecutionRole(最初から入っています)
  • テンプレートの準備: 「テンプレートの準備完了」
  • テンプレートソース: 「テンプレートファイルのアップロード」で soa-stackset-drift.yaml を選択
StackSet の作成画面(セルフサービスのアクセス許可・管理ロール・実行ロール・テンプレートのアップロード)
StackSet の作成画面(セルフサービスのアクセス許可・管理ロール・実行ロール・テンプレートのアップロード)

アップロードすると、テンプレートの S3 URL が表示されます。CloudFormation が自動で作るバケット(cf-templates- で始まる名前)に置かれたものです。

「次へ」をクリックし、StackSet 名に soa-stackset-drift と入力して「次へ」をクリックします(このテンプレートには入力するパラメータはありません)。「スタックセットオプションの設定」はデフォルトのまま「次へ」をクリックします。

手順 2: 東京と大阪にデプロイする

「デプロイオプションの設定」で以下を設定します。

  • スタックセットにスタックを追加: 「新しいスタックのデプロイ」のまま
  • アカウントの追加: 「スタックをアカウントにデプロイ」を選び、アカウント番号に自分のアカウント ID(12 桁)を入力
  • リージョンの指定: 1 行目で「アジアパシフィック (東京)」、行を追加して 2 行目で「アジアパシフィック (大阪)」を選択
  • デプロイオプション: その他はデフォルトのまま
デプロイオプションの設定(自分のアカウント ID と、東京・大阪の 2 リージョン)
デプロイオプションの設定(自分のアカウント ID と、東京・大阪の 2 リージョン)

「次へ」をクリックし、確認画面で「送信」をクリックします。StackSet の「スタックインスタンス」タブを開き、2 つのスタックインスタンスの「詳細ステータス」が SUCCEEDED になるまで待ちます(1 分ほど。API の list-stack-instances では Status が CURRENT になります)。「ドリフトステータス」はまだ NOT_CHECKED です。

スタックインスタンスタブ(東京・大阪の 2 件が SUCCEEDED)
スタックインスタンスタブ(東京・大阪の 2 件が SUCCEEDED)

手順 3: 大阪のパラメータを手で変える

画面右上のリージョンを「アジアパシフィック (大阪)」に切り替えます。上部の検索バーに Systems Manager と入力して開き、左側ナビゲーションの「パラメータストア」を選択します。

/soa/stackset/log-level を開き、「編集」をクリックします。値を INFO から DEBUG に書き換えて「変更を保存」をクリックします。CloudFormation を通さない、いわゆる「手で直した」変更です。

手順 4: ドリフト検出を実行する

リージョンを「アジアパシフィック (東京)」に戻し、CloudFormation の「StackSets」から soa-stackset-drift を開きます。「アクション」→「ドリフトの検出」を選択します。

「オペレーション」タブに、タイプ DETECT_DRIFT のオペレーションが表示されます。ステータスが SUCCEEDED になるまで、1 分ほど待ちます。

「スタックインスタンス」タブを開くと、大阪(ap-northeast-3)の「ドリフトステータス」が DRIFTED、東京(ap-northeast-1)が IN_SYNC になっています。「StackSet の情報」(概要)でも、StackSet 全体のドリフトステータスが DRIFTED になっています。

スタックインスタンスタブのドリフトステータス(大阪が DRIFTED・東京が IN_SYNC)
スタックインスタンスタブのドリフトステータス(大阪が DRIFTED・東京が IN_SYNC)
クラウドおさる

東京は無事で、大阪だけが赤札でござる。どこで誰かが手を入れたかが、リージョンの単位で一目で分かるのでござるな。

手順 5: どのプロパティが変わったかを確認する

「オペレーション」タブでドリフト検出のオペレーションを選択し、「ドリフトの詳細を表示」をクリックすると、同期中のインスタンスが 1、ドリフトしたインスタンスが 1 と表示されます。閉じたら、オペレーションタブの下のスタックインスタンスの表で大阪を選び、「ドリフト結果を表示」をクリックします。「リソースのドリフトステータス」に、LogLevel(/soa/stackset/log-level)が MODIFIED、MaintenanceMode が IN_SYNC と並びます。

LogLevel を選んで「ドリフトの詳細を表示」をクリックすると、「ドリフトの詳細」の画面の「違い」の表に、Value プロパティの期待値 INFO と現在の値 DEBUG が並んで表示されます。

ドリフトの詳細(Value の期待値 INFO と現在の値 DEBUG)
ドリフトの詳細(Value の期待値 INFO と現在の値 DEBUG)

同じ結果は CloudShell からも確認できます。

aws cloudformation list-stack-instances \
  --stack-set-name soa-stackset-drift \
  --filters Name=DRIFT_STATUS,Values=DRIFTED \
  --query 'Summaries[].[Region,DriftStatus,LastDriftCheckTimestamp]' --output table

大阪の 1 行だけが DRIFTED として表示されます。

まとめ

確かめたいこと見るところ
どこかで手動変更されていないかStackSet の概要のドリフトステータス(DRIFTED / IN_SYNC)
どのアカウント・リージョンか「スタックインスタンス」タブのドリフトステータス
どのリソースのどのプロパティか「オペレーション」タブ →「リソースドリフトを表示」→「ドリフトの詳細を表示」
  • StackSets は 1 つのテンプレートを複数のアカウント・リージョンに配る。配った先ごとにスタックインスタンスができる
  • セルフマネージド型は管理ロールと実行ロールを自分で作る。単一アカウントの複数リージョンにも使える。サービスマネージド型は Organizations と連携する
  • StackSet のドリフト検出は、全スタックインスタンスのリソースをテンプレートの定義と比べる。同時に実行できるのは 1 つだけ
  • ドリフト検出は差を見つけるだけで、元には戻さない
  • CloudFormation フック(作成前の検証)や SCP(操作の禁止)は、作成後の手動変更の検出には使えない
クラウドおさる

「配ったあとで手で変えられたものを、まとめて見つけたい」と来たら StackSet のドリフト検出でござる。作る前に確かめる仕組みや、操作を止める仕組みと取り違えやすいので、いつの何を見る仕組みかで見分けるのでござるな。

参照先

キャリア相談
クラウドおさる

独学の先に、AWS の仕事がある ── ジュニアおさるのキャリア相談

CLF には受かったけれど、次に何をすればいいのか分からない。独学で AWS を学ぶジュニアおさるの相談に、株式会社ジェニュイン代表の土肥が答えています。

  • ✓資格はゴールか、CLF の次に何から手を付けるか
  • ✓EC2 の次に作ってみる構成と、IaC・コスト管理
  • ✓実務経験ゼロでも、面接で話せる「これまで」の作り方
新卒・未経験の方へ
クラウドおさる

AWS を仕事にしたい方へ ── 新卒・未経験から

この記事を書いているのは、AWS の設計・構築を仕事にしている現役エンジニアです。運営元の株式会社ジェニュインでは、新卒・未経験の方も募集しています。異業種や文系からインフラエンジニアになり活躍しているメンバーもいます。

  • ✓システム開発・WEB エンジニア / インフラ構築などの職種で、未経験から応募できます
  • ✓未経験から入社した社員の声を含む社員アンケートを掲載
  • ✓応募フォームから 1 分で応募できます

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次