- Newest
- Most votes
- Most comments
Based on my research into this issue, there's a fundamental limitation with using Fn::ForEach for generating SIDs dynamically within policy documents. The core problem stems from how Fn::ForEach requires a unique OutputKey parameter.
According to the AWS CloudFormation documentation for Fn::ForEach parameters: "The key in the transformed template. ${Identifier} or &{Identifier} must be included within the OutputKey parameter. For example, if Fn::ForEach is used in the Resources section of the template, this is the logical ID of each resource."
This is a known limitation that has been documented in GitHub issue #1864 regarding ForEach functionality with IAM Role policies.
There are ongoing discussions about enhancing Fn::ForEach functionality, as documented in GitHub issue #118. Until these enhancements are implemented, this limitation remains a constraint when working with ForEach in policy documents.
The issue you're encountering is related to how the Fn::ForEach function works with IAM policy statements. The Sid (Statement ID) is an optional identifier for policy statements that must be unique within a JSON policy.
For your use case, you need to modify your approach since the third parameter of Fn::ForEach requires both an output key and output value, but IAM policy statements in the Statement array are just values (list items) without associated keys.
Here's a corrected approach to dynamically generate policy statements with unique Sids:
PolicyDocument: Version: "2012-10-17" Statement: - Sid: StaticS3List Effect: Allow Action: s3:ListBucket Resource: arn:aws:s3:::example-bucket - Fn::ForEach::DynamicSids: - TestId - - abc - def - ghi - DummyKey${}: Sid: !Sub "${TestId}-${DynamicSids}" Effect: Allow Action: Get Resource: "*"
In this approach:
- I've added a dummy key prefix (
DummyKey${}) that will be discarded when CloudFormation processes the template - The value is a complete policy statement object with the Sid that incorporates both the TestId and the current item from your list
- The list now contains multiple items (abc, def, ghi) to demonstrate iteration
When processed, this will generate multiple statement objects in the array, each with a unique Sid like "TestId-abc", "TestId-def", etc.
Remember that the Sid element supports ASCII uppercase letters (A-Z), lowercase letters (a-z), and numbers (0-9), and must be unique within your policy.
Sources
IAM JSON policy elements: Sid - AWS Identity and Access Management
Community | Learn AWS IAM By Writing Your First Policies for Groups and Users
answered a year ago

Thanks for sharing. Have you executed this? When i tried your recommendation, its failing with "failed with '' within the outputkey is not an identifier
ODummyKey${}: this is not being ignore unfortunately. If you have tried this in your environment, can you please share screenshot. Appreciate it.