aws-amplify / aws-amplify/amplify-cli
Storage deploy fails with 'Policy resource was already managed by another stack' after CFN enforcement change (Jan 2026)
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 825
- Avg merge
- 11d 23h
- Merged PRs (30d)
- 2
Description
## Description
As of January 30, 2026, CloudFormation enforces single-stack ownership of IAM inline policies. This breaks `amplify push` for Gen1 projects with **multiple environments** that share storage resources targeting the **same IAM role** (e.g., when using imported Identity Pool/auth roles).
The deploy fails with:
```
The following resource(s) failed to update: [S3AuthUploadPolicy, S3AuthPublicPolicy, S3AuthProtectedPolicy, S3AuthReadPolicy, S3AuthPrivatePolicy]
Policy resource was already managed by another stack or another resource in the current stack. Found stacks: [amplify---storage...|S3AuthPrivatePolicy]
```
## Root Cause
When `amplify env add` creates a new environment, it copies `cli-inputs.json` verbatim — including the `policyUUID` field. This UUID is generated once (in `s3-defaults.ts` via `buildShortUUID()`) when storage is first added to the project. All environments therefore produce identical policy names (e.g., `Private_policy_ad0f22e8`).
This only becomes a problem when **both** conditions are met:
1. **Same PolicyName** — guaranteed by the shared `policyUUID` across envs
2. **Same target IAM role** — occurs when environments share auth roles (e.g., imported Identity Pool with shared authenticated/unauthenticated roles, or manually configured shared roles)
In the common case where each environment has its own auth roles (the default for `amplify add auth`), the identical policy names land on *different* roles, and CFN does not conflict. This is why relatively few customers hit it — it requires a shared-role configuration.
## Affected Code
- `packages/amplify-category-storage/src/provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform.ts` (lines 115-121) — policy names use `policyUUID` without envName differentiation
- `amplify env add` clones `cli-inputs.json` (containing `policyUUID`) to new environments unchanged
## Workaround
Use `amplify override storage` in each affected environment to make policy names unique:
```typescript
// override.ts
import { AmplifyS3ResourceTemplate } from "@aws-amplify/cli-extensibility-helper";
export function override(resources: AmplifyS3ResourceTemplate) {
const envName = "YOUR_ENV_NAME"; // e.g., "dev", "prod"
resources.s3AuthPrivatePolicy.policyName += `-${envName}`;
resources.s3AuthProtectedPolicy.policyName += `-${envName}`;
resources.s3AuthPublicPolicy.policyName += `-${envName}`;
resources.s3AuthReadPolicy.policyName += `-${envName}`;
resources.s3AuthUploadPolicy.policyName += `-${envName}`;
}
```
Then run `amplify push`. Repeat for each environment with a different `envName` value.
## Suggested Fix
Append the environment name to the `policyUUID` when generating CFN parameters in `s3-stack-transform.ts`:
```typescript
// Before:
this.cfnInputParams.s3PrivatePolicy = `Private_policy_${userInput.policyUUID}`;
// After:
this.cfnInputParams.s3PrivatePolicy = `Private_policy_${userInput.policyUUID}_${envName}`;
```
This prevents new occurrences. Existing affected stacks still need the override workaround above.
## Related
- #10098 — same root cause (shared policyUUID + shared roles), different symptom (policy content overwriting rather than CFN rejection). A fix that appends envName to policy names would address both issues.
## Environment
- Amplify CLI: current (latest on `dev`)
- Trigger: CFN enforcement change Jan 30, 2026
- Frequency: Low — only affects projects with shared auth roles across environments (imported Identity Pool or manual role configuration)
Contributor guide
Assessment
This issue has not been assessed yet.