shou2017.com
JP / EN

CDK fail: Bucket named bucketName exists, but not in account AccountId Wrong account?

Tue Mar 28, 2023
Sat Aug 10, 2024

前回のfailed bootstrapping: Error: CDK the stack named CDKToolkit failed creationでBootstrapのエラーに対処しましたが、今回はdeploy編です。

AWS CDKでdeployを実行したときにCDK fail: Bucket named <bucketName> exists, but not in account <AWS::AccountId> Wrong account?というエラーに遭遇しました。このエラーが実に厄介で僕もだいぶ時間を潰したので対処法をメモしておきます。

まず、どの部分でエラーになっているのかというとローカルでcdkがテンプレートを作成した後、テンプレートをs3にアップするのですがこの部分でエラーが発生しています。なので、CloudFormationのaws cloudformation packageコマンドの実行でエラーになっている可能性が高いと考えました。実際、コンソールからCloudFormationを確認するとわかるのですが、そもそもスタックが存在していないことが確認できました。

エラーメッセージは

バケットはあるけどアカウントが間違ってない?

と表示されるのですが、aws cliコマンドは正常なのでアカウントが間違っているとは考えにくく、おそらく権限まわりかと思って、色々ググりました。

Obscure error message ‘Bucket named ‘bucket-name’ exists, but not in account [object Object]. Wrong account?’

他にも同じようなエラーに遭遇した人もいたので権限回りかと思って、S3のバケットポリシーなんかをいじったりして、デプロイした人もいるようですが、これをやる前に確認して欲しいことがあります(この方法でもデプロイはできるのですが、正しい対処法ではないです。単に権限をやたら緩くしただけです)。

前に同じアカウント環境でCDKをデプロイしていないかということです。しているということならIAMのロール確認しましょう。

ロール名にcdkの名前がついているロールを探してください。恐らくデフォルトのQualifierのランダムな文字列hnb659fdsがロール名のものがあると思います。

そして、アクティビティを確認してみてください。実行した覚えがないのに動かしている履歴がありませんか?

そうです。cdk bootstrapコマンドを実行した時に--qualifier <ランダムな文字列>を指定したはずなのに、これらがデプロイ時に機能しておらず、デフォルトのhnb659fdsが動いているのです!!!

もうちょっと深掘りしてみますと。

このロールはcdk bootstrapコマンドを実行した時に作られたロールです。名前からなんとなく推測できると思いますが、cdkで作られたCloudFormationを実行するためのロールです。試しにcdk bootstrap --show-template > bootstrap-template.yamlでどのようなポリシーがついているの見てみます。

s3にテンプレートをアップする段階のエラーなので、file-publishing-roleと怪しそうなので、これにします。

# bootstrap-template.yaml
FilePublishingRoleDefaultPolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyDocument:
      Statement:
        - Action:
            - s3:GetObject*
            - s3:GetBucket*
            - s3:GetEncryptionConfiguration
            - s3:List*
            - s3:DeleteObject*
            - s3:PutObject*
            - s3:Abort*
          Resource:
            - Fn::Sub: ${StagingBucket.Arn}
            - Fn::Sub: ${StagingBucket.Arn}/*
          Effect: Allow
        - Action:
            - kms:Decrypt
            - kms:DescribeKey
            - kms:Encrypt
            - kms:ReEncrypt*
            - kms:GenerateDataKey*
          Effect: Allow
          Resource:
            Fn::If:
              - CreateNewKey
              - Fn::Sub: ${FileAssetsBucketEncryptionKey.Arn}
              - Fn::Sub: arn:${AWS::Partition}:kms:${AWS::Region}:${AWS::AccountId}:key/${FileAssetsBucketKmsKeyId}
      Version: "2012-10-17"
    Roles:
      - Ref: FilePublishingRole
    PolicyName:
      Fn::Sub: cdk-${Qualifier}-file-publishing-role-default-policy-${AWS::AccountId}-${AWS::Region}

ResourceActionにも欠けているところは見当たりません。あるとしたらPolicyNameくらい、、、

解消法としては実は単純で、cdk deploy時のにもqualifierを指定する必要があります。しないとデフォルトが動くので。

指定する方法はclass DefaultStackSynthesizerを使えばできます。こんな感じで。

new Stack(app, Stack, {
  env: {region: config.region},
  description: config.stackDesc,
  tags: config.tags,
  synthesizer: new DefaultStackSynthesizer({
    fileAssetsBucketName: バケット名,
    qualifier: 'ランダムな文字列'
  })
});

これでもう一度、デプロイを実行してみてください。成功するはずです。

See Also