Skip to content

ForEach to generate SIDs dynamically within policy document

0

Here is the code snippet i would like to achieve. I want to generate sids blocks automatically based on a list. However i am getting various errors after trying multiple combinations. Key problem is foreach third param expects to have outputkey and putput value. However sid blocks in statement are just value as they are list of dicts. No key associated to them. Doea anyone have a luck on how to achieve this. Thanks in advance.

PolicyDocument: Version: "2012-10-17" Statement: - Sid: StaticS3List Effect: Allow Action: s3:ListBucket Resource: arn:aws:s3:::example-bucket

      - Fn::ForEach::DynamicSids:
        - TestId
        - - abc
        - ${}:
            - Sid: !Sub "${TestId}"
              Effect: Allow
              Action: Get
              Resource: "*"

asked a year ago168 views

2 Answers
0

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.

AWS
EXPERT

answered a year ago

-1

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:

  1. I've added a dummy key prefix (DummyKey${}) that will be discarded when CloudFormation processes the template
  2. The value is a complete policy statement object with the Sid that incorporates both the TestId and the current item from your list
  3. 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.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.