Skip to content

(import): AssetPublishFailed prevents importing due to S3 access denial #1664

Description

@sehyun-hwang

Describe the bug

When running cdk import on a stack, the CLI completes initial steps and prompts, but fails while publishing the updated CloudFormation template asset to the CDK assets S3 bucket, reporting:

[100%] fail: Bucket named 'cdk-hnb659fds-assets-<account>-<region>' exists, but we dont have access to it.
❌ <StackName>: AssetPublishFailed: Failed to publish one or more assets.

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

The updated CloudFormation template should publish successfully to the assets S3 bucket, allowing the import to complete without access errors.

Current Behavior

After entering resource identifiers and completing prompts, publishing the template asset fails with:

[100%] fail: Bucket named 'cdk-hnb659fds-assets-<account>-<region>' exists, but we dont have access to it.
❌ <StackName> failed: AssetPublishFailed: Failed to publish one or more assets. See the error messages above for more information.
    at publishAssets (...index.js)
    at async deployStack (...index.js)
    at async ResourceImporter.importResources (...index.js)
    at async ResourceImporter.importResourcesFromMap (...index.js)
    at async CdkToolkit.import (...index.js)
    at async exec (...index.js)

Earlier steps, such as reading the template and initial publish to the same S3 bucket, succeed. Only the second publish as part of deploying the import fails.

Reproduction Steps

  1. Have a stack with importable resources with large template?
  2. Run cdk import <StackName>
  3. Complete all resource identifier prompts
  4. Observe error when publishing the template asset during deploy

Possible Solution

Following patch adds missing file publishing role when running cdk import

diff --git forkSrcPrefix/packages/@aws-cdk/toolkit-lib/lib/api/cloudformation/template-body-parameter.ts forkDstPrefix/packages/@aws-cdk/toolkit-lib/lib/api/cloudformation/template-body-parameter.ts
index 5e09f016bc9609250d50d9ac78fcf3187a9b1c42..799281f2297b994966005804e4e89c8770e87c51 100644
--- forkSrcPrefix/packages/@aws-cdk/toolkit-lib/lib/api/cloudformation/template-body-parameter.ts
+++ forkDstPrefix/packages/@aws-cdk/toolkit-lib/lib/api/cloudformation/template-body-parameter.ts
@@ -1,7 +1,8 @@
 import * as fs from 'node:fs/promises';
 import * as path from 'node:path';
 import * as util from 'node:util';
-import { type CloudFormationStackArtifact, type Environment, EnvironmentPlaceholders } from '@aws-cdk/cloud-assembly-api';
+import { AssetManifestArtifact, type CloudFormationStackArtifact, type Environment, EnvironmentPlaceholders } from '@aws-cdk/cloud-assembly-api';
+import type * as cxschema from '@aws-cdk/cloud-assembly-schema';
 import { HeadObjectCommand, S3Client } from '@aws-sdk/client-s3';
 import { getEndpointFromInstructions } from '@smithy/middleware-endpoint';
 import * as chalk from 'chalk';
@@ -84,6 +85,7 @@ export async function makeBodyParameter(
       path: templateFile,
     },
     {
+      ...templateAssetPublishingDestination(stack),
       bucketName: toolkitInfo.bucketName,
       objectKey: key,
     },
@@ -94,6 +96,30 @@ export async function makeBodyParameter(
   return { TemplateURL: templateURL };
 }
 
+function templateAssetPublishingDestination(stack: CloudFormationStackArtifact): Partial<cxschema.FileDestination> {
+  for (const artifact of stack.dependencies) {
+    if (!AssetManifestArtifact.isAssetManifestArtifact(artifact)) {
+      continue;
+    }
+
+    for (const asset of Object.values(artifact.contents.files ?? {})) {
+      if (asset.source.path !== stack.templateFile) {
+        continue;
+      }
+
+      const destination = Object.values(asset.destinations)[0];
+      return {
+        assumeRoleAdditionalOptions: destination.assumeRoleAdditionalOptions,
+        assumeRoleArn: destination.assumeRoleArn,
+        assumeRoleExternalId: destination.assumeRoleExternalId,
+        region: destination.region,
+      };
+    }
+  }
+
+  return {};
+}
+
 /**
  * Format an S3 URL in the manifest for use with CloudFormation
  *

Additional Information/Context

  • The S3 bucket exists and is accessible, as shown by the initial successful upload.
  • The problem blocks importing resources using the CLI even when permissions are sufficient for the initial steps.

CDK CLI Version

2.1128.1

Framework Version

No response

Node.js Version

v24.15.0

OS

macOS

Language

TypeScript

Language Version

TypeScript 6.0.2

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions