

# ドリフト検出を使用してスタックとリソースへのアンマネージド型設定変更を検出する
<a name="using-cfn-stack-drift"></a>

CloudFormation を通じてリソースを管理している場合でも、ユーザーは CloudFormation の外部でそれらのリソースを変更できます。ユーザーは、リソースを作成した基盤となるサービスを使用してリソースを直接編集できます。例えば、Amazon EC2 コンソールを使用して、CloudFormation スタックの一部として作成されたサーバーインスタンスを更新できます。一部の変更は偶発的になされますが、時間的制約のある操作上のイベントに対応するために意図的になされる場合もあります。しかし、CloudFormation の外部で行われた変更はスタックの更新または削除オペレーションを複雑にする可能性があります。ドリフト検出を使用して、CloudFormation 管理外で構成変更がされたスタックリソースを識別できます。その後、スタックリソースがスタックテンプレート内の定義と再度同期するように是正措置を行うことができます。たとえば、ドリフトされたリソースがテンプレート定義と一致するように直接更新します。ドリフトを解決することにより、構成の一貫性と正常なスタックオペレーションを確実にします。

**Topics**
+ [ドリフトとは](#what-is-drift)
+ [ドリフト検出ステータスコード](#drift-status-codes)
+ [ドリフトを検出する際の考慮事項](#drift-considerations)
+ [CloudFormation スタック全体のドリフトを検出する](detect-drift-stack.md)
+ [個々のスタックリソースのドリフトを検出](detect-drift-resource.md)
+ [インポートオペレーションでドリフトを解決する](resource-import-resolve-drift.md)

## ドリフトとは
<a name="what-is-drift"></a>

ドリフトの検出により、スタックの実際の構成が、意図した構成と異なっていたり、*ドリフト*していないか確認できます。CloudFormation を使用して、スタック全体、またはスタック内の個々のリソースのドリフトを検出します。リソースの実際のプロパティ値が予期されるプロパティ値と異なる場合、そのリソースはドリフトしたと見なされます。これには、プロパティまたはリソースが削除されたかどうかも含まれます。スタックの 1 つ以上のリソースがドリフトした場合、スタックはドリフトしたと見なされます。

リソースがドリフトしたかどうかを判断するために、CloudFormation はスタックテンプレートとテンプレートパラメータとして指定された値で定義されているように、期待されるリソースプロパティ値を決定します。CloudFormation は、それらの期待値を現在スタックに存在しているリソースプロパティの実際の値と比較します。1 つ以上のリソースのプロパティが削除された場合、またはリソースの値が変更された場合、リソースはドリフトしたと見なされます。

CloudFormation は、ドリフトしたスタック内の各リソースに関する詳細情報を生成します。

CloudFormation は、これらのドリフト検出をサポートしている AWS リソースのドリフトを検出します。ドリフト検出をサポートしないリソースには、ドリフトステータス NOT\$1CHECKED が割り当てられます。ドリフト検出をサポートする AWS リソースのリストについては、「[リソースタイプのサポート](resource-import-supported-resources.md)」を参照してください。

さらに、CloudFormation は、*プロビジョニング可能な*プライベートリソースタイプ、つまりプロビジョニングタイプが `FULLY_MUTABLE` または `IMMUTABLE` のいずれかであるドリフト検出をサポートします。プライベートリソースタイプのリソースでドリフト検出を実行するには、アカウントに登録されたリソースタイプのデフォルトバージョンがプロビジョニング可能である必要があります。リソースのプロビジョニングタイプの詳細については、「*AWS CloudFormation API リファレンス*」の [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html) アクションおよび「*AWS CLI コマンドリファレンス*」の [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-type.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-type.html) コマンドの `ProvisioningType` パラメータをご覧ください。プライベートリソースの詳細については、「[CloudFormation レジストリによる拡張機能の管理](registry.md)」をご参照ください。

次のステータスでスタックのドリフト検出を実行できます。`CREATE_COMPLETE`、`UPDATE_COMPLETE`、`UPDATE_ROLLBACK_COMPLETE`、および `UPDATE_ROLLBACK_FAILED`。

スタックのドリフトを検出すると、CloudFormation はそのスタックに属するネストされたスタックのドリフトを検出しません。詳細については、「[ネストされたスタックを使用してテンプレートを再利用可能な部分に分割する](using-cfn-nested-stacks.md)」を参照してください。代わりに、ネストしたスタックに対して直接ドリフト検出オペレーションを開始できます。

**注記**  
CloudFormation は、スタックテンプレートを通じて、またはテンプレートパラメータを指定することによって、明示的に設定されたプロパティについてのみドリフトを判断します。これには、リソースプロパティのデフォルト値は含まれません。ドリフトを決定する目的で CloudFormation にリソースプロパティを追跡させるには、デフォルト値に設定している場合でも、プロパティ値を明示的に設定します。

## ドリフト検出ステータスコード
<a name="drift-status-codes"></a>

このセクションの表では、ドリフト検出で使用されるさまざまなステータスタイプについて説明しています。
+ [**Drift detection operation status (ドリフト検出オペレーションステータス)**] は、ドリフト動作の現在の状態を示します。
+ **ドリフトステータス** 

  スタックセットの場合、スタックセットに属するスタックインスタンスのドリフトステータスに基づいて、スタックセット全体のドリフトステータスについて説明します。

  スタックインスタンスの場合、関連付けられたスタックのドリフトステータスに基づいて、スタックインスタンスのドリフトステータスについて説明します。

  スタックの場合、これは、そのリソースのドリフトステータスに基づいて、スタック全体のドリフトステータスを表します。
+ [**リソースのドリフトステータス**] は、個々のリソースのドリフトステータスを表します。

次の表は、CloudFormation がスタックドリフト検出オペレーションに割り当てるステータスコードの一覧です。


| ドリフト検知オペレーションステータス | 説明 | 
| --- | --- | 
|  `DETECTION_COMPLETE`  |  スタックドリフト検出オペレーションは、ドリフト検出をサポートするスタック内のすべてのリソースに対して正常に完了しました。  | 
|  `DETECTION_FAILED`  |  スタックドリフト検出オペレーションは、スタック内の少なくとも 1 つのリソースに対して失敗しました。CloudFormation がドリフト検出を正常に完了したリソースで、結果が利用可能になります。  | 
|  `DETECTION_IN_PROGRESS`  |  スタックドリフト検出オペレーションは現在進行中です。  | 

次の表は、CloudFormation がスタックに割り当てるドリフトステータスコードの一覧です。


| ドリフトステータス | 説明 | 
| --- | --- | 
|  `DRIFTED`  |  スタックの場合: スタックは、意図したテンプレート構成とは異なるか、*ドリフト*しています。スタックの 1 つ以上のリソースがドリフトした場合、スタックはドリフトしたと見なされます。 スタックインスタンスの場合: スタックインスタンスに関連付けられたスタックがドリフトした場合、スタックインスタンスはドリフトしたと見なされます。 スタックセットの場合: 1 つ以上のスタックインスタンスがドリフトした場合、スタックセットはドリフトしたと見なされます。  | 
|  `NOT_CHECKED`  |  CloudFormation では、スタック、スタックセット、またはスタックインスタンスが、予想されるテンプレート構成と異なるかどうかをチェックしません。  | 
|  `IN_SYNC`  |  サポートされている各リソースの現在の構成は、意図したテンプレート構成と一致します。ドリフト検出をサポートするリソースを持たないスタック、スタックセット、またはスタックインスタンスも IN\$1SYNC ステータスになります。  | 

次の表は、CloudFormation がスタックリソースに割り当てるドリフトステータスコードの一覧です。


| リソースのドリフトステータス | 説明 | 
| --- | --- | 
|  `DELETED`  |  リソースが削除されたため、リソースは意図したテンプレート構成と異なります。  | 
|  `MODIFIED`  |  リソースは意図したテンプレート構成とは異なります。  | 
|  `NOT_CHECKED`  |  CloudFormation は、リソースが意図したテンプレート構成と異なるかどうかを確認していません。  | 
|  `IN_SYNC`  |  リソースの現在の構成は、意図したテンプレート構成と一致します。  | 

次の表は、CloudFormation が意図したテンプレート構成とは異なるリソースプロパティに割り当てる差分タイプのステータスコードを示しています。


| 差分タイプのプロパティ | 説明 | 
| --- | --- | 
|  `ADD`  |  配列またはリストのデータ型であるリソースプロパティに値が追加されました。  | 
|  `REMOVE`  |  プロパティは現在のリソース構成から削除されました。  | 
|  `NOT_EQUAL`  |  現在のプロパティ値は、スタックテンプレートで定義されている予測値とは異なります。  | 

## ドリフトを検出する際の考慮事項
<a name="drift-considerations"></a>

スタックでドリフト検出を正常に実行するには、ユーザーは次のアクセス許可を持っている必要があります。
+ スタックに含まれるドリフト検出をサポートする各リソースに対する読み取り権限です。たとえば、スタックに `AWS::EC2::Instance` リソースが含まれている場合、スタックでドリフト検出を実行するには `ec2:DescribeInstances` アクセス許可が必要です。
+ `cloudformation:DetectStackDrift`
+ `cloudformation:DetectStackResourceDrift`
+ `cloudformation:BatchDescribeTypeConfigurations`

CloudFormation でアクセス許可を設定する方法の詳細については、「[AWS Identity and Access Management で CloudFormation アクセスを制御する](control-access-with-iam.md)」をご参照ください。

特定のエッジケースでは、CloudFormation が正確なドリフト結果を返すことができない場合があります。ドリフト検出結果を正しく解釈するために、これらのエッジケースに注意する必要があります。
+ 場合によっては、プロパティ配列に含まれるオブジェクトが、実際にはリソースを担当する基盤となるサービスからプロパティに提供されたデフォルト値であった場合に、ドリフトとして報告されます。
+ 一部のリソースは、関連するリソースとアタッチメントの関係を持ちます。そのため、リソースは、同一のまたは別のテンプレートで定義された別のリソースのプロパティ値を実際にアタッチまたは削除できます。たとえば、`AWS::EC2::SecurityGroupIngress` および `AWS::EC2::SecurityGroupEgress` リソースを使用して、`AWS::EC2::SecurityGroup` リソースから値をアタッチしたり削除したりできます。このような場合、CloudFormation はドリフト比較を実行する前にアタッチメントのスタックテンプレートを分析します。ただし、CloudFormation はスタック間ではこの分析を実行できないため、接続されているリソースが異なるスタックに存在する場合、正確なドリフト結果を返さない可能性があります。

  ドリフト検出をサポートし、他のリソースからの添付ファイルを許可または要求するリソースには、次のものがあります。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html)
+ CloudFormation は、リソースの `KMSKeyId` プロパティに対してドリフト検出を実行しません。AWS KMS キーは複数のエイリアスによって参照される可能性があるため、CloudFormation はこのプロパティに対して常に正確なドリフト結果を保証することはできません。
+ スタックテンプレートで指定できる特定のリソースプロパティがあります。その性質上、CloudFormation は結果として得られるスタックリソースのプロパティと比較できません。したがって、これらのプロパティをドリフト検出結果に含めることはできません。このようなプロパティは、大きく 2 つのカテゴリに分けられます。
  + CloudFormation がスタックテンプレートの初期リソースプロパティ値にマッピングできないプロパティ値です。

    例えば、CloudFormation は Lambda 関数のソースコードを [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) リソースの [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-lambda-function-code.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-lambda-function-code.html) プロパティタイプにマッピングできません。そのため CloudFormation はそれをドリフト検出結果に含めることができません。
  + リソースを担当するサービスが返さないプロパティ値です。

    設計上、リソースが属するサービスでは返されることがない特定のプロパティ値があります。これらには、パスワードやその他の機密データなどの、公開されない機密情報が含まれる傾向があります。例えば、IAM サービスは [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-iam-user-loginprofile.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-iam-user-loginprofile.html) プロパティタイプの `Password` プロパティの値を返すことはないため、CloudFormation はそれをドリフト検出結果に含めることができません。
  + 配列内のオブジェクトは実際にはサービスの既定値である場合があり、手動で追加されたドリフトではありません。
+ 誤検知が発生した場合は、[CloudFormation コンソール] のフィードバックリンクを使用してご意見をご送信いただくか、[AWS re:Post](https://repost.aws/) からご連絡ください。
+ プロパティによっては、等しいが同一ではない入力値を持つことがあります。誤検出を防ぐには、想定した設定が実際の設定と一致していることを確認する必要があります。
  + たとえば、リソースプロパティの予想される設定は 1,024 MB で、同じリソースプロパティの実際の設定は 1 GB になる可能性があります。1,024 MB と 1 GB は同等ですが同一ではありません。

    このリソースプロパティでドリフト検出を実行すると、ドリフトの結果が通知されます。

    この誤検出を回避するには、リソースプロパティの想定される設定を 1,024 MB に変更してから、ドリフト検出を実行します。

# CloudFormation スタック全体のドリフトを検出する
<a name="detect-drift-stack"></a>

スタックでドリフト検出オペレーションを実行すると、スタックが予想されるテンプレート構成からドリフトしたかどうかが判断され、ドリフト検出をサポートするスタック内の各リソースのドリフトステータスに関する詳細情報が返されます。

**AWS マネジメントコンソール を使用してスタック全体のドリフトを検出するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. スタックのリストから、ドリフト検出を実行するスタックを選択します。スタックの詳細ペインで、[**Stack actions (スタックアクション)**] を選択し、[**Detect drift (ドリフトの検出)**] を選択します。  
![\[選択したスタックの [Stack actions (スタックアクション)] メニューで [現在のスタックのドリフトを検出] コマンドを選択しました。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/console-stacks-actions-detect-drift-1.png)

   CloudFormation により、選択されたスタックに対してドリフト検出が開始されたことを示す情報バーが表示されます。

1. CloudFormation がドリフト検出オペレーションを完了するまで待ちます。ドリフト検出オペレーションが完了すると、CloudFormation によって、スタックの [**Drift status**] (ドリフトステータス) と [**Last drift check time**] (前回のドリフトチェック時間) が更新されます。これらのフィールドは、スタックの詳細ページの **[Stack info]** (スタック情報) ペインの **[Overview]** (概要) セクションにリスト表示されます。

   スタックに含まれるリソースの数によっては、ドリフト検出オペレーションに数分かかることがあります。特定のスタックに対して同時に実行できるドリフト検出オペレーションは 1 つだけです。情報バーを閉じた後でも、CloudFormation によってドリフト検出オペレーションが継続されます。

1. スタックとそのリソースのドリフト検出結果を確認します。スタックを選択した状態で、[**Stack actions (スタックアクション)**] メニューから [**View drift results (ドリフト結果の表示)**] を選択します。

   CloudFormation によって、スタックの全体的なドリフトステータス、およびスタックまたはその個々のリソースのいずれかで最後にドリフト検出が開始された時刻がリスト表示されます。スタックの 1 つ以上のリソースがドリフトした場合、スタックはドリフトしたと見なされます。  
![\[選択したスタックの [Drifts (ドリフト)] ページに、スタック全体のドリフトステータス、ドリフト検出ステータス、およびスタックまたはその個々のリソースで最後にドリフト検出が開始された時刻が表示されます。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/console-stacks-drifts-overview-1.png)

   [**Resource drift status**] (リソースのドリフトステータス) のセクションに、CloudFormation で各スタックリソース、そのドリフトステータス、およびリソースで最後にドリフト検出が開始された時刻がリスト表示されます。各リソースの論理 ID と物理 ID は、それらを識別しやすくするために表示されます。さらに、ステータスが [**MODIFIED**] のリソースの場合、CloudFormation はリソースドリフトの詳細を表示します。

   ドリフトステータスに基づいてリソースをソートするには、[**ドリフトステータス**] 列を使用します。

   1. 変更されたリソースの詳細を表示します。

     1. 変更されたリソースを選択した状態で、[**View drift details (ドリフトの詳細を表示)**] を選択します。

       CloudFormation により、そのリソースのドリフト詳細ページが表示されます。このページに、リソースの意図した値と現在のプロパティ値、およびその 2 つの違いがリスト表示されます。

       違いを強調表示するには、[**違い**] セクションでプロパティ名を選択します。
       + 追加されたプロパティは **[Details]** (詳細) セクションの **[Current]** (最新の) 列で緑色で強調表示されます。
       + 削除されたプロパティは **[Details]** (詳細) セクションの **[Expected]** (期待される) 列で赤色で強調表示されます。
       + 値が変更されたプロパティは、[**Expected**] 列と [**最新の**] 列の両方で黄色で強調表示されます。  
![\[[ドリフト詳細] ページの [リソースドリフトステータス] セクションには、ドリフト検出をサポートするスタックに各リソースのドリフト情報が含まれています。詳細には、ドリフトステータス、意図した値、現在のプロパティ値などがあります。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/console-stacks-drifts-drift-details-differences-1.png)

**AWS CLI を使用してスタック全体のドリフトを検出するには**
**重要**  
古いデータが使用されることのないようにするため、スタックの **[前回のドリフトチェック時刻]** をチェックして、リソースのドリフト結果に表示されるタイムスタンプより前の時刻になっていることを確認します。

AWS CLI を使用してスタック全体のドリフトを検出するには、次の AWS CLI コマンドを使用します。
+ **detect-stack-drift** はスタックでドリフト検出オペレーションを開始します。
+ **describe-stack-drift-detection-status** はスタックドリフト検出動作の状態を監視します。
+ **describe-stack-resource-drifts** はスタックドリフト検出オペレーションの詳細を確認します。

1. **detect-stack-drift** を使用してスタック全体のドリフトを検出します。スタックの名前または ARN を指定してください。このドリフト検出オペレーションのフィルターとして使用したい特定のリソースの論理 ID を指定することもできます。

   ```
   aws cloudformation detect-stack-drift --stack-name my-stack-with-resource-drift
   ```

   出力:

   ```
   {
       "StackDriftDetectionId": "624af370-311a-11e8-b6b7-500cexample"
   }
   ```

1. スタックドリフト検出オペレーションは長時間実行される可能性があるため、**describe-stack-drift-detection-status** を使用してドリフト操作のステータスを監視します。このコマンドは、**detect-stack-drift** コマンドによって返されたスタックドリフト検出 ID を受け取ります。

   以下の例では、上記の **detect-stack-drift** の例から返されたスタックドリフト検出 ID を取得し、**describe-stack-drift-detection-status** へのパラメータとして渡します。このパラメータは、ドリフト検出オペレーションが完了したこと、単一のスタックリソースがドリフトしたこと、および結果としてスタック全体がドリフトしたと見なされることを示すオペレーションの詳細を返します。

   ```
   aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id 624af370-311a-11e8-b6b7-500cexample
   ```

   出力:

   ```
   {
       "StackId": "arn:aws:cloudformation:us-east-1:099908667365:stack/my-stack-with-resource-drift/489e5570-df85-11e7-a7d9-50example", 
       "StackDriftDetectionId": "624af370-311a-11e8-b6b7-500cexample", 
       "StackDriftStatus": "DRIFTED", 
       "Timestamp": "2018-03-26T17:23:22.279Z", 
       "DetectionStatus": "DETECTION_COMPLETE", 
       "DriftedStackResourceCount": 1
   }
   ```

1. スタックドリフト検出オペレーションが完了したら、**describe-stack-resource-drifts** コマンドを使用して、ドリフトしたリソースの実際のプロパティ値と意図したプロパティ値を含む結果を確認します。

   以下の例では `--stack-resource-drift-status-filters` オプションを使用し、変更または削除されたリソースのスタックドリフト情報を要求します。リクエストは、値が変更された 2 つのプロパティに関する詳細を含む、変更された 1 つのリソースに関する情報を返します。リソースは削除されていません。

   ```
   aws cloudformation describe-stack-resource-drifts --stack-name my-stack-with-resource-drift --stack-resource-drift-status-filters MODIFIED DELETED
   ```

   出力:

   ```
   {
       "StackResourceDrifts": [
           {
               "StackId": "arn:aws:cloudformation:us-east-1:099908667365:stack/my-stack-with-resource-drift/489e5570-df85-11e7-a7d9-50example", 
               "ActualProperties": "{\"ReceiveMessageWaitTimeSeconds\":0,\"DelaySeconds\":120,\"RedrivePolicy\":{\"deadLetterTargetArn\":\"arn:aws:sqs:us-east-1:099908667365:my-stack-with-resource-drift-DLQ-1BCY7HHD5QIM3\",\"maxReceiveCount\":12},\"MessageRetentionPeriod\":345600,\"MaximumMessageSize\":262144,\"VisibilityTimeout\":60,\"QueueName\":\"my-stack-with-resource-drift-Queue-494PBHCO76H4\"}", 
               "ResourceType": "AWS::SQS::Queue", 
               "Timestamp": "2018-03-26T17:23:34.489Z", 
               "PhysicalResourceId": "https://sqs.us-east-1.amazonaws.com/099908667365/my-stack-with-resource-drift-Queue-494PBHCO76H4", 
               "StackResourceDriftStatus": "MODIFIED", 
               "ExpectedProperties": "{\"ReceiveMessageWaitTimeSeconds\":0,\"DelaySeconds\":20,\"RedrivePolicy\":{\"deadLetterTargetArn\":\"arn:aws:sqs:us-east-1:099908667365:my-stack-with-resource-drift-DLQ-1BCY7HHD5QIM3\",\"maxReceiveCount\":10},\"MessageRetentionPeriod\":345600,\"MaximumMessageSize\":262144,\"VisibilityTimeout\":60,\"QueueName\":\"my-stack-with-resource-drift-Queue-494PBHCO76H4\"}", 
               "PropertyDifferences": [
                   {
                       "PropertyPath": "/DelaySeconds", 
                       "ActualValue": "120", 
                       "ExpectedValue": "20", 
                       "DifferenceType": "NOT_EQUAL"
                   }, 
                   {
                       "PropertyPath": "/RedrivePolicy/maxReceiveCount", 
                       "ActualValue": "12", 
                       "ExpectedValue": "10", 
                       "DifferenceType": "NOT_EQUAL"
                   }
               ], 
               "LogicalResourceId": "Queue"
           }
       ]
   }
   ```

# 個々のスタックリソースのドリフトを検出
<a name="detect-drift-resource"></a>

スタック全体ではなく、スタック内の特定のリソースの変動を検出できます。これは、特定のリソースが意図されたテンプレート構成に一致しているかどうかを再度判断するだけでよい場合に特に役立ちます。

リソースでドリフト検出を実行すると、CloudFormation は、必要に応じて、スタックドリフトステータス全体および [**Last drift check time**] (前回のドリフトチェック時刻) も更新します。たとえば、スタックに `IN_SYNC` のドリフトステータスがあることを想定します。CloudFormation はそのスタックに含まれる 1 つ以上のリソースに対してドリフト検出を実行し、CloudFormation はそれらのリソースの 1 つ以上がドリフトしたことを検出します。CloudFormation はスタックドリフトのステータスを `DRIFTED` に更新します。逆に、ドリフトリソースが 1 つあることでドリフトステータスが `DRIFTED` になっているスタックがあるとします。そのリソースを意図したプロパティ値に戻し、リソースで再度ドリフトを検出した場合、CloudFormation はリソースのドリフトステータスとスタックのドリフトステータスの両方を `IN_SYNC` に更新するため、スタック全体でドリフトを再度検出する必要はありません。

**AWS マネジメントコンソール を使用して個々のリソースの変動を検出するには**

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. スタックのリストから、リソースを含むスタックを選択します。CloudFormation により、そのスタックのスタックの詳細が表示されます。

1. 左のナビゲーションペインの [**スタック**] で、[**スタックアクション**] を選択し、[**ドリフトの検出**] を選択します。

1. [**リソースのドリフトステータス**] でリソースを選択し、[**リソースのドリフトを検出**] を選択します。

   CloudFormation は選択されたリソースに対してドリフト検出を実行します。成功すると、CloudFormation は必要に応じてリソースのドリフトステータスと全体的なスタックドリフトステータスを更新します。CloudFormation は、ドリフト検出がリソースおよびスタック全体で最後に実行された時刻のタイムスタンプも更新します。リソースが変更されている場合、CloudFormation はリソースの意図した値と現在のプロパティ値に関する詳細なドリフト情報を表示します。

1. リソースのドリフト検出結果を確認します。

   1. 変更されたリソースの詳細を表示します。

     1. 変更されたリソースを選択した状態で、[**View drift details (ドリフトの詳細を表示)**] を選択します。

       CloudFormation により、リソースのドリフトの詳細が表示され、リソースの意図した値と現在のプロパティ値、およびその 2 つの差異が示されます。

       違いを強調表示するには、[**違い**] セクションでプロパティ名を選択します。
       + 追加されたプロパティは **[Details]** (詳細) セクションの **[Current]** (最新の) 列で緑色で強調表示されます。
       + 削除されたプロパティは **[Details]** (詳細) セクションの **[Expected]** (期待される) 列で赤色で強調表示されます。
       + 値が変更されたプロパティは、[**Expected**] 列と [**最新の**] 列の両方で黄色で強調表示されます。  
![\[[ドリフト詳細] ページの [リソースドリフトステータス] セクションには、ドリフト検出をサポートするスタックに各リソースのドリフト情報が含まれています。詳細には、ドリフトステータス、意図した値、現在のプロパティ値などがあります。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/console-stacks-drifts-drift-details-differences-1.png)

**AWS CLI を使用して個々のリソースの変動を検出するには**
+ 
**重要**  
古いデータが使用されることのないようにするため、スタックリソースの **[前回のドリフトチェック時刻]** をチェックして、リソースのドリフト結果に表示されるタイムスタンプより前の時刻になっていることを確認します。

  **detect-stack-resource-drift** を使用して個々のリソースの変動を検出するには AWS CLI コマンドを使用します。リソースの論理 ID とそれが含まれているスタックを指定します。

  次の例では、特定のスタックリソースの `my-drifted-resource` に対してドリフト検出オペレーションが実行されます。レスポンスは、値が変更された 2 つのプロパティに関する詳細を含む、リソースが変更されたことを確認する情報を返します。

  ```
  aws cloudformation detect-stack-resource-drift \
      --stack-name my-stack-with-resource-drift \
      --logical-resource-id my-drifted-resource
  ```

  出力:

  ```
  {
      "StackResourceDrift": {
          "StackId": "arn:aws:cloudformation:us-east-1:099908667365:stack/my-stack-with-resource-drift/489e5570-df85-11e7-a7d9-50example", 
          "ActualProperties": "{\"ReceiveMessageWaitTimeSeconds\":0,\"DelaySeconds\":120,\"RedrivePolicy\":{\"deadLetterTargetArn\":\"arn:aws:sqs:us-east-1:099908667365:my-stack-with-resource-drift-DLQ-1BCY7HHD5QIM3\",\"maxReceiveCount\":12},\"MessageRetentionPeriod\":345600,\"MaximumMessageSize\":262144,\"VisibilityTimeout\":60,\"QueueName\":\"my-stack-with-resource-drift-Queue-494PBHCO76H4\"}", 
          "ResourceType": "AWS::SQS::Queue", 
          "Timestamp": "2018-03-26T18:54:28.462Z", 
          "PhysicalResourceId": "https://sqs.us-east-1.amazonaws.com/099908667365/my-stack-with-resource-drift-Queue-494PBHCO76H4", 
          "StackResourceDriftStatus": "MODIFIED", 
          "ExpectedProperties": "{\"ReceiveMessageWaitTimeSeconds\":0,\"DelaySeconds\":20,\"RedrivePolicy\":{\"deadLetterTargetArn\":\"arn:aws:sqs:us-east-1:099908667365:my-stack-with-resource-drift-DLQ-1BCY7HHD5QIM3\",\"maxReceiveCount\":10},\"MessageRetentionPeriod\":345600,\"MaximumMessageSize\":262144,\"VisibilityTimeout\":60,\"QueueName\":\"my-stack-with-resource-drift-Queue-494PBHCO76H4\"}", 
          "PropertyDifferences": [
              {
                  "PropertyPath": "/DelaySeconds", 
                  "ActualValue": "120", 
                  "ExpectedValue": "20", 
                  "DifferenceType": "NOT_EQUAL"
              }, 
              {
                  "PropertyPath": "/RedrivePolicy/maxReceiveCount", 
                  "ActualValue": "12", 
                  "ExpectedValue": "10", 
                  "DifferenceType": "NOT_EQUAL"
              }
          ], 
          "LogicalResourceId": "my-drifted-resource"
      }
  }
  ```

# インポートオペレーションでドリフトを解決する
<a name="resource-import-resolve-drift"></a>

リソースの構成が意図した構成から逸脱したために、新しい構成を意図した構成として受け入れる必要が生じることがあります。ほとんどの場合は、スタックテンプレート内のリソースの定義を新しい構成で更新することでドリフト結果を解決してから、スタックの更新を実行します。ただし、置換が必要なリソースプロパティが新しい構成によって更新された場合、リソースはスタックの更新中に再作成されます。既存のリソースを保持する場合は、リソースのインポート機能を使用してリソースを更新し、リソースを置き換えることなくドリフト結果を解決できます。

インポートオペレーションによるリソースのドリフトの解決は、次の基本的なステップで行います。
+ [Retain に設定されている DeletionPolicy 属性をリソースに追加します](#resource-import-resolve-drift-console-step-01-update-stack)。これにより、既存のリソースがスタックから取り除かれたときに、削除されるのではなく、保持されます。
+ [テンプレートからリソースを取り除き、スタック更新オペレーションを実行します](#resource-import-resolve-drift-console-step-02-remove-drift)。これにより、スタックからリソースが取り除かれますが、削除はされません。
+ [スタックテンプレートでリソースの実際の状態を記述し、既存のリソースをスタックにインポートし直します](#resource-import-resolve-drift-console-step-03-update-template)。これにより、リソースがスタックに戻され、ドリフト結果を発生させていたプロパティの差異が解決されます。

リソースのインポートについて詳しくは、「[AWS リソースを CloudFormation スタックに手動でインポートする](import-resources-manually.md)」を参照してください。インポートをサポートしているリソースのリストについては、「[リソースタイプのサポート](resource-import-supported-resources.md)」を参照してください。

この例では、`templateToImport.json` という名前の次のテンプレートを使用します。

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        },
        "GamesTable": {
            "Type": "AWS::DynamoDB::Table",
            "Properties": {
                "TableName": "Games",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "BillingMode": "PROVISIONED",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 5,
                    "WriteCapacityUnits": 1
                }
            }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
  GamesTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Games
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
```

------

この例では、ユーザーが CloudFormation の 外部でリソースを変更したと仮定します。ドリフト検出の実行により、`GamesTable` の `BillingMode` が `PAY_PER_REQUEST` に変更されていることが検出されました。ドリフト検出の詳細については、「[ドリフト検出を使用してスタックとリソースへのアンマネージド型設定変更を検出する](using-cfn-stack-drift.md)」を参照してください。

![\[コンソールのドリフト結果には、予想される結果と実際の結果が表示されます。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/drift-results-gamestable.png)


スタックは古くなっており、リソースはライブですが、意図したリソース構成を保持する必要があります。サービスを中断することなく、インポートオペレーションでドリフトを解決することでこれを達成できます。

## CloudFormation コンソールを使用して、インポートオペレーションでドリフトを解決する
<a name="resource-import-resolve-drift-console"></a>

### ステップ 1. Retain 削除ポリシーでスタックを更新する
<a name="resource-import-resolve-drift-console-step-01-update-stack"></a>

**`DeletionPolicy` 属性の `Retain` オプションを使用してスタックを更新するには**

1. AWS マネジメントコンソール にサインインし、CloudFormation コンソール ([https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)) を開きます。

1. [**Stacks (スタック)**] ページで、ドリフトしているスタックを選択します。

1. [**Update (更新する)**] を選択し、スタックの詳細ペインから [**Replace current template (既存テンプレートを置き換える)**] を選択します。

1. [**Specify template (テンプレートの指定)**] ページで、次のいずれかの方法を使用して、`Retain` オプションが指定されている `DeletionPolicy` 属性を含む更新済みテンプレートを指定します。
   + [**Amazon S3 URL**] を選択し、テキストボックスでテンプレートの URL を指定します。
   + [**Upload a template file (テンプレートファイルのアップロード)**] を選択し、テンプレートを参照します。

   その後、**[Next]** を選択します。

1. [**Specify stack details (スタックの詳細を指定)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Configure stack options (スタックオプションの設定)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Review *stack-name* (スタック名の確認)**] ページで、[**Update stack (スタックの更新)**] を選択します。

*結果*: スタックの [**Events (イベント)**] ページのステータスは `UPDATE_COMPLETE` です。

サービスを中断せずにインポートオペレーションでドリフトを解決するには、スタックから取り除くリソースに対して `Retain` [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html) を指定します。次の例では、`Retain` に設定されている [DeletionPolicy](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-deletionpolicy.html) 属性を `GamesTable` リソースに追加しました。

------
#### [ Example JSON ]

```
    "GamesTable": {
        "Type": "AWS::DynamoDB::Table",
        "DeletionPolicy": "Retain",
        "Properties": {
            "TableName": "Games",
```

------
#### [ Example YAML ]

```
  GamesTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: Games
```

------

### ステップ 2. ドリフトしたリソース、関連パラメータ、出力を取り除く
<a name="resource-import-resolve-drift-console-step-02-remove-drift"></a>

**ドリフトしたリソース、関連パラメータ、出力を取り除くには**

1. [**Update (更新する)**] を選択し、スタックの詳細ペインから [**Replace current template (既存テンプレートを置き換える)**] を選択します。

1. [**Specify template (テンプレートの指定)**] ページで、次のいずれかの方法を使用して、更新されたテンプレートにリソース、関連パラメータ、およびスタックテンプレートから削除された出力を指定します。
   + [**Amazon S3 URL**] を選択し、テキストボックスでテンプレートの URL を指定します。
   + [**Upload a template file (テンプレートファイルのアップロード)**] を選択し、テンプレートを参照します。

   その後、**[Next]** を選択します。

1. [**Specify stack details (スタックの詳細を指定)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Configure stack options (スタックオプションの設定)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Review *stack-name* (スタック名の確認)**] ページで、[**Update stack (スタックの更新)**] を選択します。

結果: スタックの **[Events]** (イベント) ページの **[Logical ID]** (論理 ID) `GamesTable` のステータスは `DELETE_SKIPPED` です。

CloudFormation がスタックの更新オペレーションを完了するまで待ちます。スタックの更新オペレーションが完了したら、リソース、関連パラメータ、および出力をスタックテンプレートから取り除きます。次に、更新されたテンプレートをインポートします。これらのアクションを完了すると、テンプレートの例は次のようになります。

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
```

------

### ステップ 3. リソースのライブ状態に合わせてテンプレートを更新する
<a name="resource-import-resolve-drift-console-step-03-update-template"></a>

**リソースのライブ状態に合わせてテンプレートを更新するには**

1. 更新されたテンプレートをインポートするには、[**Stack actions (スタックアクション)**] を選択し、[**Import resources into stack (スタックへのリソースのインポート)**] を選択します。  
![\[コンソールの [Import resources into stack (リソースをスタックにインポートする)] オプション。\]](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/images/stack-actions-import.png)

1. このオペレーション中に指定する必要がある項目の一覧に関して [**Import overview (概要をインポート)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Specify template (テンプレートの指定)**] ページで、次のいずれかの方法を使用して、更新したテンプレートを指定します。
   + [**Amazon S3 URL**] を選択し、テキストボックスでテンプレートの URL を指定します。
   + [**Upload a template file (テンプレートファイルのアップロード)**] を選択し、テンプレートを参照します。

   その後、**[Next]** を選択します。

1. [**Identify resources (リソースの識別)**] ページで、各ターゲットリソースを識別します。詳細については、「[リソース識別子](import-resources-manually.md#resource-import-identifiers-unique-ids)」を参照してください。

   1. [**Identifier property (識別子のプロパティ)**] で、リソース識別子のタイプを選択します。たとえば、`TableName` プロパティは `AWS::DynamoDB::Table` リソースを識別します。

   1. [**Identifier value (識別子の値)**] に、実際のプロパティ値を入力します。テンプレートの例では、`GamesTable` リソースの `TableName` は `Games` です。

   1. [**次へ**] を選択します。

1. [**Specify stack details (スタックの詳細を指定)**] ページを確認し、[**Next (次へ)**] を選択します。

1. [**Import overview (概要をインポート)**] ページで、インポートするリソースを確認し、[**Import resources (リソースをインポート)**] を選択します。これにより、`AWS::DynamoDB::Table` リソースタイプがスタックにインポートされます。

*結果*: この例では、サービスを中断することなく、インポートオペレーションによってリソースのドリフトを解決しました。インポートアクションの進行状況は、CloudFormation コンソールの [Events] (イベント) タブで確認できます。インポートされたリソースでは、`IMPORT_COMPLETE` ステータスに続いて `CREATE_COMPLETE` ステータスが続き、ステータス理由は**リソースのインポート完了**になります。

CloudFormation がスタックの更新オペレーションを完了するまで待ちます。スタックの更新オペレーションが完了したら、リソースの実際のドリフト状態と一致するようにテンプレートを更新します。たとえば、`BillingMode` は `PAY_PER_REQUEST` に設定され、`ReadCapacityUnits` と `WriteCapacityUnits` は `0` に設定されます。

------
#### [ Example JSON ]

```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Import test",
    "Resources": {
         "ServiceTable":{
           "Type":"AWS::DynamoDB::Table",
           "Properties":{
              "TableName":"Service",
              "AttributeDefinitions":[
                 {
                    "AttributeName":"key",
                    "AttributeType":"S"
                 }
              ],
              "KeySchema":[
                 {
                    "AttributeName":"key",
                    "KeyType":"HASH"
                 }
              ],
              "BillingMode": "PROVISIONED",
              "ProvisionedThroughput":{
                 "ReadCapacityUnits":5,
                 "WriteCapacityUnits":1
              }
           }
        },
        "GamesTable": {
            "Type": "AWS::DynamoDB::Table",
            "DeletionPolicy": "Retain",
            "Properties": {
                "TableName": "Games",
                "AttributeDefinitions": [
                    {
                        "AttributeName": "key",
                        "AttributeType": "S"
                    }
                ],
                "KeySchema": [
                    {
                        "AttributeName": "key",
                        "KeyType": "HASH"
                    }
                ],
                "BillingMode": "PAY_PER_REQUEST",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 0,
                    "WriteCapacityUnits": 0
                }
            }
        }
    }
}
```

------
#### [ Example YAML ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: Import test
Resources:
  ServiceTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Service
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PROVISIONED
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 1
  GamesTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: Games
      AttributeDefinitions:
        - AttributeName: key
          AttributeType: S
      KeySchema:
        - AttributeName: key
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST
      ProvisionedThroughput:
        ReadCapacityUnits: 0
        WriteCapacityUnits: 0
```

------