前回の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コマンドは正常なのでアカウントが間違っているとは考えにくく、おそらく権限まわりかと思って、色々ググりました。
他にも同じようなエラーに遭遇した人もいたので権限回りかと思って、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}
Resource
もAction
にも欠けているところは見当たりません。あるとしたら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: 'ランダムな文字列'
})
});
これでもう一度、デプロイを実行してみてください。成功するはずです。