In the previous post failed bootstrapping: Error: CDK the stack named CDKToolkit failed creation, I covered the Bootstrap error. This time, it’s about a deploy
error.
When running deploy with AWS CDK, I encountered the error CDK fail: Bucket named <bucketName> exists, but not in account <AWS::AccountId>. Wrong account?
. This error was really troublesome and wasted a lot of my time, so here are my notes on how to handle it.
First, where does this error occur? After CDK creates the template locally, it uploads the template to S3, and the error happens at this stage. So, it’s likely that the error is related to the aws cloudformation package
command. You can check this by looking at CloudFormation from the console, but in my case, the stack didn’t even exist.
The error message is:
The bucket exists, but is it in the wrong account?
Since the AWS CLI command worked fine, I didn’t think it was an account issue. I suspected permissions, so I did some research.
Others have encountered similar errors, so I thought it might be a permissions issue. Some people tried changing S3 bucket policies or redeploying, but before doing that, there’s something you should check (those methods can work, but they’re not the correct solution—they just loosen permissions).
Check if you’ve previously deployed CDK in the same account. If so, check the IAM roles.
Look for roles with cdk
in the name. You’ll probably find roles with the default qualifier string hnb659fds
in the name.
Then, check the activity. Is there any history of these being used, even if you don’t remember running them?
That’s right. When you run the cdk bootstrap
command, you can specify --qualifier <random string>
, but if these are not functioning at deploy time, the default hnb659fds
is used!!!
Digging a little deeper:
These roles are created when you run the cdk bootstrap
command. You can guess from the name, but they’re roles for running CloudFormation created by CDK. Try running cdk bootstrap --show-template > bootstrap-template.yaml
to see what policies are attached.
The error happens at the stage where the template is uploaded to S3, so the file-publishing-role
is suspicious. Let’s check it.
# 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}
There’s nothing missing in Resource
or Action
. If there’s anything, it’s probably just PolicyName
…
The solution is actually simple: you need to specify the qualifier
when running cdk deploy
as well. If you don’t, the default one will be used.
You can do this by using the class DefaultStackSynthesizer. It would look something like this:
new Stack(app, Stack, {
env: {region: config.region},
description: config.stackDesc,
tags: config.tags,
synthesizer: new DefaultStackSynthesizer({
fileAssetsBucketName: バケット名,
qualifier: 'ランダムな文字列'
})
});
Now, try running the deploy again. It should be successful.