バケットポリシーの設定をミスってアクセスできずに冷や汗をかいた話

# はじめに
「**[100万人に伝えたい！失敗を乗り超えた話を共有しよう](https://qiita.com/official-events/e9f582bec72278130942)**」の参考記事として以前投稿した記事を紹介して頂いたので、イベントを盛り上げるべく別の失敗談を投稿しようと思います。

【紹介いただいた記事】
- [タイムリープして本番リリース直前のBIG-IPをぶっ壊した話](https://qiita.com/sakai00kou/items/54d31810a5bf853154a2)

実際には首の皮一枚で何とかリカバリできたので未遂で終わったものとなりますが、業務でS3バケットポリシーを設定した際、ミスってアクセスできなくなった話を共有します。

# 今回の構成概要
あるS3バケットに対して通常時はLambda等からのアクセスのみ許可して、特定の場合にのみその他のアクセスも許可するといった以下のような要件を満たすため、`Step Functions`とS3バケットのバケットポリシーで仕組みを実装しようとしていました。

```plantuml
@startuml
!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v16.0/dist
!include AWSPuml/AWSCommon.puml
!include AWSPuml/Groups/AWSCloud.puml
!include AWSPuml/Groups/Generic.puml
!include AWSPuml/Groups/StepFunctionsWorkflow.puml
!include AWSPuml/General/User.puml
!include AWSPuml/ApplicationIntegration/StepFunctions.puml
!include AWSPuml/Compute/Lambda.puml
!include AWSPuml/Storage/SimpleStorageService.puml
!include AWSPuml/AWSSimplified.puml

left to right direction
title バケットへのアクセス

skinparam shadowing false
hide stereotype
skinparam rectangle {
    BackgroundColor AWS_BG_COLOR
    BorderColor transparent
}

AWSCloudGroup(cloud){
  rectangle "$StepFunctionsIMG()\nStep Functions" as stepfunctions
  rectangle "$LambdaIMG()\nLambda" as lambda
  rectangle "$UserIMG()\nIAMユーザ" as user
  rectangle "$SimpleStorageServiceIMG()\nS3" as s3
}

stepfunctions-d->s3: S3アクセス許可
lambda-d->s3: S3アクセス許可
user~~(s3: S3アクセス拒否
@enduml
```

該当のS3バケットへは`AdministratorAccess`権限を持ったユーザからもアクセスさせたくなかったため、以下のような明示的なDenyルールを設定して、除外ルールとして特定のIAMロールからのアクセスのみ許可、それ以外からのアクセスは拒否という設定を行っていました。

```json:バケットポリシーサンプル
{
  "Comment": "A description of my state machine",
  "StartAt": "PutBucketPolicy",
  "States": {
    "PutBucketPolicy": {
      "Type": "Task",
      "Parameters": {
        "Bucket": "[S3バケット名]",
        "Policy": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "DenyBucketPolicy",
              "Effect": "Deny",
              "Principal": {
                "AWS": "*"
              },
              "Action": "s3:*",
              "Resource": [
                "[S3バケットARN]/*",
                "[S3バケットARN]"
              ],
              "Condition": {
                "StringNotLike": {
                  "aws:userId": [
                    "[IAMロールのロールID1]:*",      ←アクセス許可するロールIDを指定
                    "[IAMロールのロールID2]:*"       ←アクセス許可するロールIDを指定
                  ]
                }
              }
            }
          ]
        }
      },
      "Resource": "arn:aws:states:::aws-sdk:s3:putBucketPolicy",
      "End": true
    }
  }
}
```

また、`Step Functions`では、S3バケットポリシーを書き換えるワークフローを作成しており、実行することで予め用意している切替用のバケットポリシーに切り替えるようにしていました。

```plantuml
@startuml
!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v16.0/dist
!include AWSPuml/AWSCommon.puml
!include AWSPuml/Groups/AWSCloud.puml
!include AWSPuml/Groups/Generic.puml
!include AWSPuml/Groups/StepFunctionsWorkflow.puml
!include AWSPuml/ApplicationIntegration/StepFunctions.puml
!include AWSPuml/SecurityIdentityCompliance/IdentityAccessManagementPermissions.puml
!include AWSPuml/Storage/SimpleStorageService.puml
!include AWSPuml/AWSSimplified.puml

left to right direction
title StepFunctionsによるバケットポリシー切替

skinparam shadowing false
hide stereotype
skinparam rectangle {
    BackgroundColor AWS_BG_COLOR
    BorderColor transparent
}

AWSCloudGroup(cloud){
  rectangle "<font color=white>right" as right {
    rectangle "$StepFunctionsIMG()\nStep Functions" as stepfunctions
    StepFunctionsWorkflowGroup(sfn) {
      rectangle "$IdentityAccessManagementPermissionsIMG()\nPutBucketPolicy実行ワークフロー" as bucketpolicy
    }
    rectangle "$SimpleStorageServiceIMG()\nS3" as s3
  }
}

stepfunctions-d->bucketpolicy: ステートマシン実行
bucketpolicy-d->s3: PubBucketPolicyによるバケットポリシー切替
@enduml
```

# 何が起こったのか
特定IAMロールからのアクセスのみ許可するような設定は今までやったことがなかったので、自分の環境で軽く確認してからお客様の機能検証用の環境に対して設定。

検証のためひとまず自分が使っているIAMロールは許可していたため、アクセスできることを確認・・・するつもりでしたが自分のIAMロールのロールIDが誤っており、`AdministratorAccess`権限を持ったユーザでも該当S3バケットに対してまったくアクセスできなくなってしまいました。


# アクセスできなくなったS3バケットのバケットポリシー修正方法
なにか元に戻したりする方法がないか調べてみたところ、IAMの権限ではどうしようもなく、rootでログインして削除するしかないと判明。

- [アクセス不能になったS3バケットのバケットポリシーを削除する方法](https://dev.classmethod.jp/articles/delete-access-denied-bucket-policy/)

作業していた環境はお客様環境で、自分ではrootアクセスはできないのでこれは詰んだ・・・か？

# どうやって解決したか
自分が使っているIAMロールの指定は誤っていましたが、予め作成していた`StepFunctions`で付与しているIAMロールのロールIDは合っていました！

そのため、ドキドキしながら該当のS3バケットポリシーを削除するワークフローを作成して実行することで無事アクセスできるようになりました！

いやぁ、間一髪でした。

# おわりに
今回の場合は実運用が行われている環境ではなく、機能検証用の環境であり、アクセスできなくなったとしてもユーザ影響等はないので、最悪お客様にごめんなさいしてrootで作業を行ってもらえばすむ話ではあったのですが、お客様にご迷惑をかけてしまうといった点は変わらないため肝が冷えました。

権限周りは失敗すると影響が大きくなるので、権限周りを設定する際にはセーフティゾーンを設け、きちんと確認してから導入するようにしましょう。