[Amazon Athena]WorkGroups削除時のRecursiveDeleteOptionによる動作について

2021.01.31

こんにちは、CX事業本部の若槻です。

Amazon Athenaでクエリを実行する際にはWorkGroupsを必ず一つ指定して使用する必要があります。ユーザーや用途によってWorkGroupを使い分けることにより、クエリ実行によるアクセスやコストの制御を容易に行うことができます。

このWorkGroupsですが、削除する際にWorkGroupsに名前付きクエリやクエリ実行履歴が残っている場合はRecursiveDeleteOptionを使用する必要があるようです。

RecursiveDeleteOption
The option to delete the workgroup and its contents even if the workgroup contains any named queries or query executions.

そこで今回は、WorkGroups削除時のRecursiveDeleteOptionオプションによる動作について確認してみました。

確認してみた

CloudFormationとAWS CLIの2パターンで確認してみます。

CloudFormationでの削除

Athena WorkGroupsはCloudFormationではAWS::Athena::WorkGroupを使用してリソースを定義できます。

WorkGroupに適当なクエリ実行履歴を作成する際に使用するために、事前に作成済みの適当なGlueデータベースとテーブルを作成して、それぞれの名前を下記のように変数に指定しておきます。

% GLUE_DATABASE_NAME=devices_data_analystics
% GLUE_TABLE_NAME=devices_raw_data

RecursiveDeleteOptionなしの場合

そもそも今回の確認をしようとした発端が、CloudFormationで管理していたWorkGroupsを削除しようとした際に後述の事象が発生し、うまく削除できずに原因調査したことでした。

まず下記のようなCloudFormationスタックのテンプレートを使用してWorkGrouptest-wgを作成します。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test-${AWS::AccountId}-${AWS::Region}

  TestAthenaWorkGroup:
    Type: AWS::Athena::WorkGroup
    Properties:
      Name: test-wg
      WorkGroupConfiguration:
        ResultConfiguration:
          OutputLocation: !Sub s3://${TestBucket}/query-result
        EnforceWorkGroupConfiguration: true
        PublishCloudWatchMetricsEnabled: true

スタックをデプロイします。

% aws cloudformation deploy \
  --template-file template.yaml \
  --stack-name test-athena-wg-stack \
  --no-fail-on-empty-changeset

ここで作成したばかりのWorkGroupをスタック再デプロイにより一度削除してみます。WorkGroupのリソース定義を削除した下記のテンプレートを使用します。

template2.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test-${AWS::AccountId}-${AWS::Region}

スタックをデプロイします。結果はSuccessfullyとなりWorkGroupは削除できました。

% aws cloudformation deploy \
  --template-file template2.yaml \
  --stack-name test-athena-wg-stack \
  --no-fail-on-empty-changeset

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - test-athena-wg-stack

続いて、始めに使用したWorkGroupのリソース定義を未削除の下記のテンプレートを再度デプロイしてみます。

template.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test-${AWS::AccountId}-${AWS::Region}

  TestAthenaWorkGroup:
    Type: AWS::Athena::WorkGroup
    Properties:
      Name: test-wg
      WorkGroupConfiguration:
        ResultConfiguration:
          OutputLocation: !Sub s3://${TestBucket}/query-result
        EnforceWorkGroupConfiguration: true
        PublishCloudWatchMetricsEnabled: true
% aws cloudformation deploy \
  --template-file template.yaml \
  --stack-name test-athena-wg-stack \
  --no-fail-on-empty-changeset

作成したWorkGrouptest-wgを使用して適当なクエリを実行し、WorkGroupにクエリ実行履歴を作成します。

% aws athena start-query-execution \
  --query-string "SELECT * FROM ${GLUE_TABLE_NAME}" \
  --work-group test-wg \
  --query-execution-context \
    Database=${GLUE_DATABASE_NAME},Catalog=AwsDataCatalog

そしてWorkGroupをスタック再デプロイにより再度削除してみます。WorkGroupのリソース定義を削除した下記のテンプレートを使用します。

template2.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test-${AWS::AccountId}-${AWS::Region}

スタックをデプロイを実行すると、コマンドの実行完了まで5分くらい要しましたが結果はSuccessfullyとなりWorkGroupは削除できたように見えます。

% aws cloudformation deploy \
  --template-file template2.yaml \
  --stack-name test-athena-wg-stack \
  --no-fail-on-empty-changeset

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - test-athena-wg-stack

しかしマネジメントコンソールでスタックのイベントを見てみると、WorkGroupのリソースの削除が3回試行されて3回ともInvalid request provided: WorkGroup test-wg is not empty (Service: Athena, Status Code: 400というエラーで失敗していました。さらに不思議なことにスタックのデプロイ自体はWorkGroupの削除が成功しないままUPDATE_COMPLETEとなり正常に完了していました。

list-stack-resourcesコマンドでスタックのリソース一覧を取得してみると、結果はリソースはS3バケットだけなので、スタックからのWorkGroupのリソース削除はちゃんと行われているようです。

% aws cloudformation list-stack-resources \
  --stack-name test-athena-wg-stack

{
    "StackResourceSummaries": [
        {
            "LogicalResourceId": "TestBucket",
            "PhysicalResourceId": "test-XXXXXXXXXX-ap-northeast-1",
            "ResourceType": "AWS::S3::Bucket",
            "LastUpdatedTimestamp": "2021-01-30T14:33:30.906000+00:00",
            "ResourceStatus": "CREATE_COMPLETE",
            "DriftInformation": {
                "StackResourceDriftStatus": "NOT_CHECKED"
            }
        }
    ]
}

そしてWorkGrouptest-wgに対してget-work-groupコマンドを実行すると取得できました。

% aws athena get-work-group \
  --work-group test-wg \
  --query WorkGroup.Name
"test-wg"

結果として、CloudFormationでRecursiveDeleteOptionオプションなしで削除した場合は、WorkGroupはスタックのリソース一覧からは削除されましたが、物理的なリソースとしては削除されない動作となりました。

RecursiveDeleteOptionありの場合

下記のようなCloudFormationスタックのテンプレートを使用してWorkGrouptest-wg-2を作成します。

template3.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test2-${AWS::AccountId}-${AWS::Region}

  TestAthenaWorkGroup:
    Type: AWS::Athena::WorkGroup
    Properties:
      Name: test-wg-2
      RecursiveDeleteOption: true
      WorkGroupConfiguration:
        ResultConfiguration:
          OutputLocation: !Sub s3://${TestBucket}/query-result
        EnforceWorkGroupConfiguration: true
        PublishCloudWatchMetricsEnabled: true

先程との違いは、WorkGroupのリソースTestAthenaWorkGroupRecursiveDeleteOptionオプションを有効にしていることです。

スタックをデプロイします。

% aws cloudformation deploy \
  --template-file template3.yaml \
  --stack-name test-athena-wg-stack-2 \
  --no-fail-on-empty-changeset

作成したWorkGrouptest-wg-2を使用して適当なクエリを実行し、クエリ実行履歴を作成します。

% aws athena start-query-execution \
  --query-string "SELECT * FROM ${GLUE_TABLE_NAME}" \
  --work-group test-wg \
  --query-execution-context \
    Database=${GLUE_DATABASE_NAME},Catalog=AwsDataCatalog

そしてWorkGroupをスタック再デプロイにより再度削除してみます。WorkGroupのリソース定義を削除した下記のテンプレートを使用します。

template4.yaml

AWSTemplateFormatVersion: '2010-09-09'

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties: 
      BucketName: !Sub test2-${AWS::AccountId}-${AWS::Region}

スタックをデプロイします。結果はSuccessfullyとなりWorkGroupは削除できたように見えます。

% aws cloudformation deploy \
  --template-file template4.yaml \
  --stack-name test-athena-wg-stack-2 \
  --no-fail-on-empty-changeset

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - test-athena-wg-stack-2

get-work-groupコマンドを実行すると、WorkGrouptest-wg-2は存在しない旨のエラーとなりました。

% aws athena get-work-group \
  --work-group test-wg-2
An error occurred (InvalidRequestException) when calling the GetWorkGroup operation: WorkGroup test-wg-2 is not found.

結果として、CloudFormationでRecursiveDeleteOptionオプションありで削除した場合は、WorkGroupはスタックのリソース一覧からも、物理的なリソースとしても削除できる動作となりました。

AWS CLIでの削除

ここでは、「CloudFormationでの削除 - RecursiveDeleteOptionなしの場合」で作成したWorkGrouptest-wgを使用して確認してみます。

AWS CLIでのAthena WorkGroupsの削除にはdelete-work-groupを使用します。

RecursiveDeleteOptionなしの場合

delete-work-groupコマンドを実行してWorkGrouptest-wgを削除してみます。するとWorkGroup test-wg is not emptyというエラーとなり削除が失敗しました。

% aws athena delete-work-group \
  --work-group test-wg
An error occurred (InvalidRequestException) when calling the DeleteWorkGroup operation: WorkGroup test-wg is not empty

RecursiveDeleteOptionありの場合

次に先程と同じdelete-work-groupコマンドを--recursive-delete-optionオプションを指定して実行してみると、WorkGrouptest-wgをエラー無く削除することができました。

% aws athena delete-work-group \
  --work-group test-wg \
  --recursive-delete-option

おわりに

WorkGroups削除時のRecursiveDeleteOptionオプションによる動作について確認してみました。

RecursiveDeleteOptionを使用しない場合は、AWS CLIの場合はコマンドがエラーとなるのみのシンプルな動作となりますでが、CloudFormationの場合はなかなか不思議な動作となりました。

WorkGroups削除時に名前付きクエリやクエリ実行履歴を残す必要がない場合は、RecursiveDeleteOptionを忘れずに指定するようにしましょう。

参考

以上