スタックのリソースが更新されないようにする - AWS CloudFormation

スタックのリソースが更新されないようにする

スタックを作成するとき、すべてのリソースですべての更新アクションが許可されます。デフォルトでは、スタック更新アクセス権限を持つユーザーであれば誰でもスタック内のすべてのリソースを更新できます。更新処理中、リソースの中断や完全な置き換えが必要になった場合は、新しい物理 ID やまったく新しいストレージが使用される結果になります。スタックポリシーを使用すると、スタックの更新中にスタックのリソースが意図せずに更新または削除されるのを防止できます。スタックポリシーは、指定したリソースに対して実行できる更新アクションを定義する JSON ドキュメントです。

スタックポリシーを設定すると、デフォルトでスタック内のすべてのリソースが保護されます。特定のリソースでの更新を許可するには、スタックポリシーでこれらのリソースに対して Allow ステートメントを明示的に指定します。1 つのスタックに定義できるスタックポリシーは 1 つのみですが、1 つのポリシー内で複数のリソースを保護することができます。スタックポリシーは、スタックの更新を試みるすべての CloudFormation ユーザーに適用されます。異なるスタックポリシーを異なるユーザーに関連付けることはできません。

スタックポリシーは、スタックの更新時のみ適用されます。AWS Identity and Access Management (IAM) ポリシーのようなアクセスコントロールは提供しません。特定のスタックリソースを誤って更新しないように、スタックポリシーはフェイルセーフメカニズムとしてのみ使用してください。AWS リソースまたはアクションへのアクセスを制御するには、IAM を使用します。

スタックポリシーの例

次のスタックポリシーの例は、ProductionDatabase リソースの更新が禁止されます。

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

スタックポリシーを設定すると、デフォルトですべてのリソースが保護されます。すべてのリソースの更新を許可するには、すべてのリソースですべてのアクションを許可する Allow ステートメントを追加します。Allow ステートメントではすべてのリソースが指定されますが、ProductionDatabase 論理 ID を持つリソースに関しては明示的な Deny ステートメントが優先されます。この Deny ステートメントにより、置き換えや削除など、すべての更新アクションが ProductionDatabase リソースで禁止されます。

Principal 要素が必要ですが、ワイルドカード (*) のみサポートされています。つまり、ステートメントはすべてのプリンシパルに適用されます。

注記

スタックの更新中、CloudFormation は、更新された他のリソースに依存するリソースを自動的に更新します。例えば、CloudFormation は、更新されたリソースを参照するリソースを更新します。CloudFormation は自動的に更新されたリソースに物理的な変更 (リソースの ID など) は行いませんが、これらのリソースにスタックポリシーが関連付けられている場合は、リソースを更新する許可が必要になります。

スタックポリシーの定義

スタックを作成するとき、スタックポリシーは設定されないため、すべてのリソースですべての更新アクションが許可されます。スタックリソースを更新アクションから保護するには、スタックポリシーを定義し、そのポリシーをスタックに設定します。スタックポリシーは JSON ドキュメントで、CloudFormation ユーザーが実行できる CloudFormation スタック更新アクションと、そのアクションが適用されるリソースを定義します。スタックポリシーを含むテキストファイルを指定するか、入力することにより、スタックの作成時にスタックポリシーを設定します。スタックにスタックポリシーを設定した場合、明示的に許可されていないすべての更新がデフォルトで拒否されます。

スタックポリシーは、EffectActionPrincipalResourceCondition の 5 つの要素によって定義します。スタックポリシーの構文を次の擬似コードに示します。

{ "Statement" : [ { "Effect" : "Deny_or_Allow", "Action" : "update_actions", "Principal" : "*", "Resource" : "LogicalResourceId/resource_logical_ID", "Condition" : { "StringEquals_or_StringLike" : { "ResourceType" : [resource_type, ...] } } } ] }
Effect

指定されたリソースでの指定されたアクションを拒否するかまたは許可するかを決定します。Deny または Allow のみ指定できます ( など)。

"Effect" : "Deny"
重要

スタックポリシーに重複ステートメントが含まれる場合 (リソースでの更新を許可するステートメントと拒否するステートメントの両方)、常に Deny ステートメントが Allow ステートメントより優先されます。リソースが必ず保護されるようにするには、そのリソースに対して Deny ステートメントを使用します。

アクション

拒否または許可する更新アクションを指定します。

Update:Modify

変更の適用中にリソースで中断が発生しない更新アクションまたはなんらかの中断が発生する更新アクションを指定します。すべてのリソースで物理 ID が保持されます。

Update:Replace

リソースが再作成される更新アクションを指定します。CloudFormation は、指定された更新を使用して新しいリソースを作成してから、古いリソースを削除します。リソースが再作成されるため、新しいリソースの物理 ID が変更される場合があります。

Update:Delete

リソースが削除される更新アクションを指定します。スタックテンプレートから完全にリソースを削除する更新の場合は、このアクションを使用する必要があります。

更新:*

すべての更新アクションを指定します。アスタリスクは、すべての更新アクションを表すワイルドカードです。

次の例では、replace アクションと delete アクションのみを指定しています。

"Action" : ["Update:Replace", "Update:Delete"]

1 つのアクションを除くすべての更新アクションを許可するには、NotAction を使用します。たとえば、Update:Delete を除くすべての更新アクションを許可するには、次の例に示すように NotAction を使用します。

{ "Statement" : [ { "Effect" : "Allow", "NotAction" : "Update:Delete", "Principal": "*", "Resource" : "*" } ] }
Principal

Principal 要素は、ポリシーを適用するエンティティを指定します。この要素は必須ですが、ワイルドカード (*) のみサポートされています。つまり、ポリシーはすべてのプリンシパルに適用されます。

リソース

ポリシーを適用するリソースの論理 ID を指定します。リソースのタイプを指定するには、Condition 要素を使用します。

1 つのリソースを指定するには、論理 ID を使用します。例:

"Resource" : ["LogicalResourceId/myEC2instance"]

論理 ID には、ワイルドカードを使用できます。たとえば、すべての関連リソースに共通の論理 ID プレフィックスを使用している場合、ワイルドカードを使用してすべてのリソースを指定できます。

"Resource" : ["LogicalResourceId/CriticalResource*"]

これらのリソースに対して Not 要素を使用することもできます。たとえば、1 つを除くすべてのリソースに対する更新を許可するには、NotResource 要素を使用してそのリソースを保護します。

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }

スタックポリシーを設定した場合、明示的に許可されていないすべての更新が拒否されます。ProductionDatabase リソース以外のリソースに対する更新をすべて許可することで、ProductionDatabase リソースに対する更新を拒否します。

条件

ポリシーを適用するリソースタイプを指定します。論理 ID を指定するには、Resource 要素を使用します。

次の例に示すように、EC2 インスタンスや RDS DB インスタンスのようなリソースタイプを指定できます。

{ "Statement" : [ { "Effect" : "Deny", "Principal" : "*", "Action" : "Update:*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::EC2::Instance", "AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Principal" : "*", "Action" : "Update:*", "Resource" : "*" } ] }

Allow ステートメントはすべてのリソースに更新アクセス権限を付与し、Deny ステートメントは EC2 および RDS DB インスタンスに対する更新を拒否します。Deny ステートメントは、すべてのアクションを常にオーバーライドします。

リソースタイプでワイルドカードを使用できます。たとえば、次の例に示すように、ワイルドカードを使用して、すべての Amazon EC2 リソース (— インスタンス、セキュリティグループ、サブネット— など) に対する更新アクセス許可を拒否できます。

"Condition" : { "StringLike" : { "ResourceType" : ["AWS::EC2::*"] } }

ワイルドカードを使用する場合は、StringLike 条件を使用する必要があります。

スタックポリシーの設定

スタックを作成する際にスタックのポリシーを適用するには、コンソールまたは AWS CLI を使用します。AWS CLI を使用して、既存のスタックにスタックポリシーを適用することもできます。スタックのポリシーを適用すると、スタックからそれを削除することはできません。ただし、AWS CLI を使用して変更することはできます。

スタックポリシーは、スタックの更新を試みるすべての CloudFormation ユーザーに適用されます。異なるスタックポリシーを異なるユーザーに関連付けることはできません。

ポリシーの記述方法については、「スタックポリシーの定義」を参照してください。

スタックの作成時にスタックポリシーを設定するには (コンソール)
  1. https://console.aws.amazon.com/cloudformation で AWS CloudFormation コンソール を開きます。

  2. [CloudFormation Stacks] ページで、[スタックの作成] を選択します。

  3. [スタックの作成] ウィザードの [Configure stack options (スタックオプションの設定)] ページで、[詳細設定] セクションを展開し、[スタックのポリシー] を選択します。

  4. 次のようにスタックポリシーを指定します。

    • コンソールにポリシーを直接作成するには、[Enter stack policy (スタックポリシーの入力)] を選択し、テキストフィールドにスタックポリシーを直接入力します。

    • 別のファイルで定義されたポリシーを使用するには、[ファイルのアップロード] を選択し、[ファイルの選択] を選択して、スタックポリシーを含むファイルを選択します。

スタックの作成時にスタックポリシーを設定するには (AWS CLI)
  • aws cloudformation create-stack コマンドを使用する際、--stack-policy-body オプションを使用して変更されたポリシーを入力するか、--stack-policy-url オプションを使用してポリシーを含むファイルを指定します。

既存のスタックでスタックポリシーを設定するには (AWS CLI のみ)
  • aws cloudformation set-stack-policy コマンドを使用する際、--stack-policy-body オプションを使用して変更されたポリシーを入力するか、--stack-policy-url オプションを使用してポリシーを含むファイルを指定します。

    注記

    既存のスタックにポリシーを追加するには、CloudFormation の SetStackPolicy アクションに対する許可が必要です。

保護されたリソースの更新

保護されたリソースを更新するには、スタックポリシーをオーバーライドする一時ポリシーを作成し、それらのリソースでの更新を許可します。スタックを更新するときにオーバーライドポリシーを指定します。オーバーライドポリシーによって、スタックポリシーが永続的に変更されるわけではありません。

保護されたリソースを更新するには、CloudFormation の SetStackPolicy アクションを使用する許可が必要です。CloudFormation 許可の設定については、「AWS Identity and Access Management によるアクセスを制御する」を参照してください。

注記

スタックの更新中、CloudFormation は、更新された他のリソースに依存するリソースを自動的に更新します。例えば、CloudFormation は、更新されたリソースを参照するリソースを更新します。CloudFormation は自動的に更新されたリソースに物理的な変更 (リソースの ID など) は行いませんが、これらのリソースにスタックポリシーが関連付けられている場合は、リソースを更新する許可が必要になります。

保護されたリソースを更新するには (コンソール)
  1. https://console.aws.amazon.com/cloudformation で AWS CloudFormation コンソール を開きます。

  2. 更新するスタックを選択し、[Stack actions (スタックアクション)]、[スタックの更新] の順に選択します。

  3. スタックテンプレートを変更していない場合は、[現在のテンプレートの使用] を選択し、[次へ] をクリックします。テンプレートを変更した場合は、[Replace current template (現在のテンプレートを置換)] を選択し、[Specify template (テンプレートの指定)] セクションで更新されたテンプレートの場所を指定します。

    • ローカルコンピュータに保存されているテンプレートの場合は、[テンプレートファイルをアップロード] を選択します。[ファイルの選択] を選択してファイルの場所に移動し、ファイルを選択して、[次へ] をクリックします。

    • Amazon S3 バケットに保存されているテンプレートの場合は、[Amazon S3 URL] を選択します。テンプレートの URL を入力するか貼り付けて、[次へ] をクリックします。

      バージョニングが有効なバケットにテンプレートがある場合、https://s3.amazonaws.com/templates/myTemplate.template?versionId=123ab1cdeKdOW5IH4GAcYbEngcpTJTDW のようにテンプレートの特定バージョンを指定することもできます。詳細については、「Amazon Simple Storage Service ユーザーガイド」の「バージョニングが有効なバケット内のオブジェクトの管理」を参照してください。

  4. テンプレートにパラメータが含まれている場合、[Specify stack details (スタックの詳細を指定)] ページで、パラメータ値を入力または変更し、[次へ] を選択します。

    CloudFormation は、スタックで現在設定されている値を各パラメータに入力します (NoEcho 属性で宣言されたパラメータを除く)。[既存の値の使用] を選択することで、それらのパラメータに現在の値を使用できます。

    NoEcho を使用して機密情報をマスクする方法、また動的なパラメータを使用してシークレットを管理する方法の詳細については、「テンプレートに認証情報を埋め込まない」ベストプラクティスを参照してください。

  5. オーバーライドスタックポリシーを指定します。

    1. [Configure stack options (スタックオプションの設定)] ページの [詳細オプション] セクションで、[スタックのポリシー] を選択します。

    2. [ファイルのアップロード] を選択します。

    3. [ファイルの選択] をクリックし、オーバーライドする側のスタックポリシーを含むファイルに移動するか、ポリシーを入力します。

    4. [Next] を選択します。

    オーバーライドポリシーでは、更新する保護されたリソースを対象として Allow ステートメントを指定する必要があります。たとえば、すべての保護されたリソースを更新するには、すべての更新を許可する一時オーバーライドポリシーを指定します。

    { "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }
    注記

    CloudFormation がオーバーライドポリシーを適用するのは、この更新の実行中のみです。オーバーライドポリシーによって、スタックポリシーが永続的に変更されるわけではありません。スタックのポリシーを変更するには、「スタックポリシーの変更 」を参照してください。

  6. 送信したスタック情報と変更を確認します。

    パラメータ値やテンプレートの URL が適切かなど、正しい情報を送信したことを確認します。テンプレートに IAM リソースが含まれる場合は、[I acknowledge that this template may create IAM resources (このテンプレートが IAM リソースを作成する可能性を認識しています)] を選択して、テンプレート内の IAM リソースを使用することを指定します。テンプレート内の IAM リソースの使用の詳細については、「AWS Identity and Access Management によるアクセスを制御する」を参照してください。

    [変更のプレビュー] セクションで、期待される変更のすべてを CloudFormation が実行することを確認します。例えば、追加、削除、または変更する予定のリソースを、CloudFormation が追加、削除、および変更することを確認します。CloudFormation は、スタックの変更セットを作成することによって、このプレビューを生成します。詳細については、「変更セットを使用して CloudFormation スタックを更新する」を参照してください。

  7. 変更内容が適切であることを確認できたら、[更新] をクリックします。

    注記

    この時点で、変更セットを表示するオプションを使用すると、提案された更新をより徹底的に確認することもできます。これを行うには、[Update] (更新) の代わりに [View change set] (変更セットを表示) をクリックしてください。CloudFormation により、更新に基づいて生成された変更セットが表示されます。スタックの更新を実行する準備ができたら、[実行] をクリックします。

    CloudFormation により、スタックの [Stack details (スタックの詳細)] ページが表示されます。スタックの状況が UPDATE_IN_PROGRESS になっていることを確認できます。CloudFormation によるスタックの更新が正常に完了したら、スタックの状況が UPDATE_COMPLETE に設定されます。

    スタックの更新が失敗した場合、CloudFormation によって変更が自動的にロールバックされ、スタックの状況が UPDATE_ROLLBACK_COMPLETE に設定されます。

保護されたリソースを更新するには (AWS CLI)
  • update-stack コマンドを使用する際、--stack-policy-during-update-body オプションを使用して変更されたポリシーを入力するか、--stack-policy-during-update-url オプションを使用してポリシーを含むファイルを指定します。

    注記

    CloudFormation がオーバーライドポリシーを適用するのは、この更新の実行中のみです。オーバーライドポリシーによって、スタックポリシーが永続的に変更されるわけではありません。スタックのポリシーを変更するには、「スタックポリシーの変更 」を参照してください。

スタックポリシーの変更

追加のリソースを保護するか、リソースから保護を削除するには、スタックポリシーを変更します。たとえば、保護するデータベースをスタックに追加するときは、そのデータベースの Deny ステートメントをスタックポリシーに追加します。ポリシーを変更するには、SetStackPolicy アクションを使用するアクセス権限が必要です。

AWS CLI を使用して、スタックポリシーを変更します。

スタックポリシーを変更するには (AWS CLI)
  • set-stack-policy コマンドを使用する際、--stack-policy-body オプションを使用して変更されたポリシーを入力するか、--stack-policy-url オプションを使用してポリシーを含むファイルを指定します。

スタックポリシーは削除できません。すべてのリソースからすべて保護を削除するには、すべてのリソースに対するすべてのアクションを明示的に許可するようにポリシーを変更します。次のポリシーは、すべてのリソースですべての更新を許可します。

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

スタックポリシーのその他の例

次のポリシー例では、すべてのスタックリソースの更新を禁止する方法、特定のリソースの更新を禁止する方法、特定のタイプの更新を禁止する方法を示します。

すべてのスタックリソースの更新を禁止する

すべてのスタックリソースの更新を禁止するため、次のポリシーでは、すべてのリソースのすべての更新アクションに対して Deny ステートメントを指定しています。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

1 つのリソースの更新を禁止する

次のポリシーでは、MyDatabase という論理 ID を持つデータベースについて、すべての更新アクションを拒否します。また、Allow ステートメントにより、他のすべてのスタックリソースにおいてすべての更新アクションを許可します。Deny ステートメントは常に許可アクションをオーバーライドするため、Allow ステートメントは MyDatabase リソースには適用されません。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "LogicalResourceId/MyDatabase" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

デフォルト拒否を使用することで、前の例と同じ結果が得られます。スタックポリシーを設定すると、CloudFormation は明示的に許可されていない更新をすべて拒否します。次のポリシーでは、デフォルトで拒否されている ProductionDatabase リソースを除くすべてのリソースの更新が許可されます。

{ "Statement" : [ { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "NotResource" : "LogicalResourceId/ProductionDatabase" } ] }
重要

デフォルト拒否の使用にはリスクがあります。ポリシーの他の場所で Allow ステートメントを使用している場合 (ワイルドカードを使用する Allow ステートメントなど)、知らないうちに意図しないリソースに更新アクセス権限を付与する可能性があります。ただし、明示的な拒否はすべての許可アクションをオーバーライドするため、Deny ステートメントを使用することでリソースが保護されることを保証できます。

特定のリソースタイプについてすべてのインスタンスの更新を禁止する

次のポリシーは、RDS DB インスタンスリソースタイプについて、すべての更新アクションを拒否します。また、Allow ステートメントにより、他のすべてのスタックリソースにおいてすべての更新アクションを許可します。Allow ステートメントは常に許可アクションをオーバーライドするため、Deny ステートメントは RDS DB インスタンスリソースには適用されません。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::RDS::DBInstance"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

特定のインスタンスについて置き換え更新を防止する

次のポリシーは、MyInstance という論理 ID を持つインスタンスの置き換えが発生する更新を拒否します。また、Allow ステートメントにより、他のすべてのスタックリソースにおいてすべての更新アクションを許可します。Deny ステートメントは常に許可アクションをオーバーライドするため、Allow ステートメントは MyInstance リソースには適用されません。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:Replace", "Principal": "*", "Resource" : "LogicalResourceId/MyInstance" }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }

ネストされたスタックの更新を禁止する

以下のポリシーは、CloudFormation スタックリソースタイプ (ネストされたスタック) でのすべての更新アクションを拒否します。また、Allow ステートメントにより、他のすべてのスタックリソースにおいてすべての更新アクションを許可します。Deny ステートメントは常に許可アクションを上書きするため、CloudFormation リソースに Allow ステートメントは適用されません。

{ "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*", "Condition" : { "StringEquals" : { "ResourceType" : ["AWS::CloudFormation::Stack"] } } }, { "Effect" : "Allow", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }