[アップデート] AWS Backup で AWS CloudFormation スタックを保護する際に、スタック内の特定リソースを除外出来るようになりました

2023.09.07

いわさです。

re:Invent 2022 にて AWS Backup は CloudFormation スタックのバックアップをサポートしています。
ステートレスなリソースはテンプレートの一部として、ステートフル(かつスナップショット作成が可能)なリソースについては通常どおりバックアップが作成され、デプロイ済みの CloudFormation スタック全体をバックアップすることが出来ます。

これまで CloudFormation スタックをバックアップ対象にすると、スタックに含まれるステートフルリソース(仮想マシンストレージやデータストアなど)も個別にバックアップ対象となっていたのですが、本日のアップデートで特定のリソース ID を指定してバックアップから除外が出来るようになりました。
これによってそもそもバックアップが不要だったり、別の方法でバックアップを行っていて冗長なバックアップになっているものなどを除外する使い方が出来ます。

これまで私が AWS Backup で CloudFormation スタックのバックアップを行ったことがなかったため、以前の動作を確認することが出来ないのですが、冒頭の記事を確認してみると以前からリソース除外の UI は使えているようにも見えます。

ただし、公式ドキュメントでは次のように記述が追加されています。

5."How do I exclude resources in my CloudFormation stack backup?"

When you back up your CloudFormation stack, you can exclude resources from being part of the backup. In the console, during the create a backup plan and update a backup plan processes, there is an assign resources step. In this step, there is a Resource selection section. If you choose include specific resource types and have included CloudFormation as a resource to backup, you can exclude specific resource IDs from the selected resource types. You can also use tags to exclude resources within the stack.

Using CLI, you can use
- NotResources in your backup plan to exclude a specific resource from your CloudFormation stacks.
- StringNotLike to exclude items through tags.

設定できなかったか、あるいは設定しても動作しなかったかだと思うのですが、今となっては確認が出来ないのと除外していた記事が見当たらなかったので、出来ていなかったものとして今回アナウンスされ使えるようになったという前提で以降は記述します。
もし以前も出来ていたとしても、こういう手順で構成するんだなくらいに思っておいてください。

検証用のテンプレートと CloudFormation スタック

今回は次のような Lambda と DynamoDB テーブルで構成される簡単な CloudFormation テンプレートを用意しました。

AWSTemplateFormatVersion: 2010-09-09
Description: ---
Resources:
  myLambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Handler: index.handler
      Role: !GetAtt myLambdaExecutionRole.Arn
      Code:
        ZipFile: |
          exports.handler = async (event) => {
            const response = {
              statusCode: 200,
              body: JSON.stringify('Hello, World!'),
            };
            return response;
          };
      Runtime: nodejs16.x
      Timeout: 10
      
  myLambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties: 
      AssumeRolePolicyDocument: 
        Version: '2012-10-17'
        Statement: 
          - Effect: "Allow"
            Principal: 
              Service: 
                - 'lambda.amazonaws.com'
            Action: 
              - 'sts:AssumeRole'
      ManagedPolicyArns: 
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'

  myDynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      TableName: myTable
      AttributeDefinitions: 
        - 
          AttributeName: id
          AttributeType: S
      KeySchema: 
        - 
          AttributeName: id
          KeyType: HASH
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5

上記のテンプレートを使って CloudFormation スタックをデプロイしています。

AWS Backup でリソース除外

ではここから、AWS Backup で CloudFormation スタックをバックアップ対象として選択し、さらにリソース除外を行ってみます。

バックアッププラン作成・更新時のリソース選択時に指定出来る

はじめにバックアップルールを作成します。
ここではバックアップのスケジュールや対象ボールトなどを構成します。

バックアッププランが作成出来ると、バックアッププランに対して対象リソースを構成するステップがあります。
ここで「2. 特定のリソースタイプを選択」で CloudFormation を選択します。
さらに、先程デプロイした CloudFormation スタックを選択したので、スタック内のリソース一式がバックアップ対象となります。

続いて「3. 選択したリソースタイプから特定のリソース ID を除外する - オプション」で除外リソースを選択します。
このリストを見た限りでは今回除外出来るものは CloudFormation スタックとは別で Backup が動作するステートフルなリソースが対象のようですね。

今回は DynamoDB を除外してみたいのでリソースタイプに DynamoDB を選択します。複数選択可能です。

リソースタイプ DynamoDB のうち、さらにどのテーブルを除外対象とするかまで指定します。

これでプランの作成が完了しました。
今回は直接リソースを指定しましたが、「4. タグを使用して選択を絞り込む - オプション」を使った除外方法も使うことが出来ます。

オンデマンドバックアップでは指定出来無さそう

なお、オンデマンドバックアップの場合でも構成出来るのか確認してみましたが、こちらはリソース割り当て時に除外オプションがないので除外設定が出来ないようでした。

通常どおり CloudFormation スタックを指定してオンデマンドバックアップジョブを実行すると次のように DynamoDB のバックアップも作成されました。

保護されたリソースを確認してみると CloudFormation スタックとは別で DynamoDB テーブルのバックアップも取得されていることが確認出来ます。

リソース除外を設定されたジョブとバックアップ

オンデマンドではなくバックアッププランでリソース除外設定がされたジョブを観察してみましょう。

ジョブを見てみると、先程と異なり DynamoDB の対象テーブルがバックアップされていませんね。
スタック全体のバックアップステータスも「部分的」とされています。

保護されたリソースを確認してみると DynamoDB テーブルが存在しませんね。除外されています。

なお、スタックを復元してみると次のようにテンプレートに含まれる DynamoDB リソースも作成されます。
ただしバックアップは存在しないので新規で DynamoDB テーブルが作成されている形です。通常はステートフルリソースは個別で追加のリストア操作が必要なのですが、このテーブルは除外されているのでバックアップが作成されていません。

さいごに

本日は AWS Backup で AWS CloudFormation スタックを保護する際に、スタック内の特定リソースを除外出来るようになったので試してみました。

わたしは最初、今回試した例であれば復元したスタックで DynamoDB が作成されないのかなと思っていたのですがそうではありませんでした。
実際にはリソース構成自体は CloudFormation 自体でバックアップされているのですが、DynamoDB 自体のデータバックアップについては取得されない。という形でした。なるほど。

CloudFormation スタックのバックアップを行っている場合でも必要なリソースだけを対象とすることで冗長なバックアップ構成を避けることが出来るので活用してみてください。