Athenaでクエリ実行時にテーブルが存在しているにも関わらずTABLE_NOT_FOUNDとなる

2024.03.04

初めに

先日StepFunctionsからAthenaのクエリを実行していましたがその際実行結果を確認したところ以下のようなエラーが出力され実行に失敗していました。

        "Status": {
            "State": "FAILED",
            "StateChangeReason": "TABLE_NOT_FOUND: line 1:36: Table 'awsdatacatalog.sftp-connector-sample-db.sample_table' does not exist",
            "SubmissionDateTime": "2024-03-04T16:28:33.868000+09:00",
            "CompletionDateTime": "2024-03-04T16:28:34.341000+09:00",
            "AthenaError": {
                "ErrorCategory": 2,
                "ErrorType": 1301,
                "Retryable": false,
                "ErrorMessage": "TABLE_NOT_FOUND: line 1:36: Table 'awsdatacatalog.sftp-connector-sample-db.sample_table' does not exist"
            }
        }

最初はテーブル名の指定の誤りかと思いましたがマネジメントコンソール上から確認する限り該当のテーブルに対してクエリが成功しており、
実際にAPI経由で実行結果を得る限りも指定は同等となっており少し原因特定に時間がかかったのでその備忘録となります。

なおこちらの記事は以下の検証の際に行ったトラブルシュート(というよりはデバッグ)作業となります。

原因

glue:GetTableの権限が必要でしたがこちらの権限が不足していたことが原因となりました。

データベースに対するアクセス権限(glue:GetDatabase)不足する際には明確に権限が不足している旨のエラーが出ますがテーブルの場合はその旨が表示されないようです。

詳細

目的としてはStepFunctions経由でAthenaに対してStartQueryExecutionを行うにあたり最終的には以下のような権限をIAMロールに指定しましたが、
当初はこのうちathena:StartQueryExecutionの付与しておりました。

- Effect: Allow
  Action: 
    - athena:StartQueryExecution
  Resource:
    - !Sub arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/${WorkGroup}
- Effect: Allow
  Action: 
    - glue:GetDatabase
    - glue:GetTable
  Resource:
    - !Sub arn:aws:glue:ap-northeast-1:${AWS::AccountId}:catalog
    - !Sub arn:aws:glue:ap-northeast-1:${AWS::AccountId}:database/${Database}
    - !Sub arn:aws:glue:ap-northeast-1:${AWS::AccountId}:table/${Database}/*

この場合はデータベースに対するアクセス権限が明確的にエラーとして出力されます。

  "QueryExecution": {
      "QueryExecutionId": "xxxxxxxx",
      "Query": "SELECT Count(id) as DataCount FROM sample_table",
      "StatementType": "DML",
      "ResultConfiguration": {
          "OutputLocation": "s3://sftp-connector-file-destination-xxxxxxxx/summary/xxxxxxxx.csv",
          "EncryptionConfiguration": {
              "EncryptionOption": "SSE_S3"
          }
      },
      "ResultReuseConfiguration": {
          "ResultReuseByAgeConfiguration": {
              "Enabled": false
          }
      },
      "QueryExecutionContext": {
          "Database": "sftp-connector-sample-db",
          "Catalog": "awsdatacatalog"
      },
      "Status": {
          "State": "FAILED",
          "StateChangeReason": "Insufficient permissions to execute the query. User: arn:aws:sts::xxxxxxxx:assumed-role/sftp-connector-event-resu-CompleteEventReceiverRole-xxxxxxxx is not authorized to perform: glue:GetDatabase on resource: arn:aws:glue:ap-northeast-1:xxxxxxxx:catalog because no identity-based policy allows the glue:GetDatabase action ",
          "SubmissionDateTime": "2024-03-04T16:23:51.085000+09:00",
          "CompletionDateTime": "2024-03-04T16:23:51.577000+09:00",
          "AthenaError": {
              "ErrorCategory": 2,
              "ErrorType": 1500,
              "Retryable": false,
              "ErrorMessage": "User: arn:aws:sts::xxxxxxxx:assumed-role/sftp-connector-event-resu-CompleteEventReceiverRole-xxxxxxxx is not authorized to perform: glue:GetDatabase on resource: arn:aws:glue:ap-northeast-1:xxxxxxxx:catalog because no identity-based policy allows the glue:GetDatabase action (Service: AWSGlue; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxxx; Proxy: null)"
          }
      }
  }

表示に従いcatalogのみにGetDatabaseの権限を与えるとデータベースの取得権限のエラーが出ますのでこちらもResourceに追加しておきます。

        "Status": {
            "State": "FAILED",
            "StateChangeReason": "Insufficient permissions to execute the query. User: arn:aws:sts::xxxxxx:assumed-role/sftp-connector-event-resu-CompleteEventReceiverRole-xxxxxx is not authorized to perform: glue:GetDatabase on resource: arn:aws:glue:ap-northeast-1:xxxxxx:database/sftp-connector-sample-db because no identity-based policy allows the glue:GetDatabase action ",
            "SubmissionDateTime": "2024-03-04T17:11:34.086000+09:00",
            "CompletionDateTime": "2024-03-04T17:11:34.531000+09:00",
            "AthenaError": {
                "ErrorCategory": 2,
                "ErrorType": 1500,
                "Retryable": false,
                "ErrorMessage": "User: arn:aws:sts::xxxxxx:assumed-role/sftp-connector-event-resu-CompleteEventReceiverRole-xxxxxx is not authorized to perform: glue:GetDatabase on resource: arn:aws:glue:ap-northeast-1:xxxxxx:database/sftp-connector-sample-db because no identity-based policy allows the glue:GetDatabase action (Service: AWSGlue; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxx; Proxy: null)"
            }
        }

表示に従いathena:GetDatabaseの権限を与えたところ今度はテーブルが見つからない旨のエラーが発生しました。

        "Status": {
            "State": "FAILED",
            "StateChangeReason": "TABLE_NOT_FOUND: line 1:36: Table 'awsdatacatalog.sftp-connector-sample-db.sample_table' does not exist",
            "SubmissionDateTime": "2024-03-04T16:28:33.868000+09:00",
            "CompletionDateTime": "2024-03-04T16:28:34.341000+09:00",
            "AthenaError": {
                "ErrorCategory": 2,
                "ErrorType": 1301,
                "Retryable": false,
                "ErrorMessage": "TABLE_NOT_FOUND: line 1:36: Table 'awsdatacatalog.sftp-connector-sample-db.sample_table' does not exist"
            }
        }

マネジメントコンソールのクエリエディタで同等のクエリを実行したところ問題なく成功しております。

念の為GetQueryExecutionでマネジメントコンソールから実行したクエリの結果を確認しましたがデータベースやカタログの指定に差異はありません。

    "QueryExecution": {
        "QueryExecutionId": "xxxxxx",
        "Query": "SELECT Count(id) as DataCountFromConsole FROM sample_table",
        "StatementType": "DML",
        "ResultConfiguration": {
            "OutputLocation": "s3://sftp-connector-file-destination-xxxxxx/summary/xxxxxx.csv",
            "EncryptionConfiguration": {
                "EncryptionOption": "SSE_S3"
            }
        },
        "ResultReuseConfiguration": {
            "ResultReuseByAgeConfiguration": {
                "Enabled": false
            }
        },
        "QueryExecutionContext": {
            "Database": "sftp-connector-sample-db",
            "Catalog": "awsdatacatalog"
        },
        "Status": {
            "State": "SUCCEEDED",
            "SubmissionDateTime": "2024-03-04T16:31:33.030000+09:00",
            "CompletionDateTime": "2024-03-04T16:31:33.650000+09:00"
        },
    ...
    }

もしやと思い最初に記載したポリシーのようにglue:GetTableの権限を追加したところStepFunction側からでも問題なく実行できるようになりました。

終わりに

AWSでは権限不足となると比較的~~is not authorized to perform: glue:GetDatabase on resource:~~~のような決まり文句が出てくるので初歩的ながら基本的な権限不足の部分を見落としてした事案でした。

一覧取得操作でで閲覧が許可されていないリソースが特にエラーが出ず許可されているリソースのみが出るように、必ずしも思っているエラーメッセージに出るとは限りませんので思い込みで外しているような現象も一度確認してみるようにしましょう。