

This is the new *CloudFormation Template Reference Guide*. Please update your bookmarks and links. For help getting started with CloudFormation, see the [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html).

# `Fn::ForEach`


The `Fn::ForEach` intrinsic function takes a collection and a fragment, and applies the items in the collection to the identifier in the provided fragment. `Fn::ForEach` can contain other intrinsic functions, including `Fn::ForEach` itself, and be used within the `Conditions`, `Outputs`, and `Resources` (including the resource properties) sections. It can't be used in any of the following sections, `AWSTemplateFormatVersion`, `Description`, `Metadata`, `Transform`, `Parameters`, `Mappings`, `Rules`, or `Hooks` sections.

If you use the `Fn::ForEach` intrinsic function in your template, you must also use the [`AWS::LanguageExtensions` transform](transform-aws-languageextensions.md) .

Using the `Fn::ForEach` intrinsic function does not change the quotas, which apply to the resultant template. Quotas include the maximum size of a template and the maximum number of resources in a template. For more information, see [Understand CloudFormation quotas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html) in the *AWS CloudFormation User Guide*.

## Declaration


### JSON


```
"Fn::ForEach::LoopLogicalName": [
  "Identifier",
  ["Value1","Value2"], // Collection
  {"OutputKey": {OutputValue}}
]
```

### YAML


```
'Fn::ForEach::LoopLogicalName':
    - Identifier
    - - Value1 # Collection
      - Value2
    - 'OutputKey':
        OutputValue
```

## Parameters


*Loop logical name*  
A logical ID for the loop. The name must be unique within the template and can't conflict with any logical ID values in the `Resources` section of the template. This name isn't in the transformed output. It’s used for internal reference within the CloudFormation template itself.

*Identifier*  
An identifier for the placeholder that gets replaced in the `OutputKey` and `OutputValue` parameters. All instances of `${Identifier}` or `&{Identifier}` in the `OutputKey` and `OutputValue` parameters will be replaced with the values from the `Collection` parameter.

*Collection*  
The collection of values to iterate over. This can be an array in this parameter, or it can be a [`Ref`](intrinsic-function-reference-ref.md) to a `CommaDelimitedList`. When using `&{Identifier}`, non-alphanumeric characters can be passed in the `Collection`.

*Output key*  
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.  
The `&{}` syntax allows non-alphanumeric characters in the `Collection` to be used in `OutputKey` parameter. For an example of this, see [Passing non-alphanumeric characters within the `Collection` for `Fn::ForEach`](intrinsic-function-reference-foreach-example-resource.md#intrinsic-function-reference-foreach-example-non-alphanumeric).

*Output value*  
The value that's replicated in the transformed template for each item in the `Collection` parameter. For example, if `Fn::ForEach` is used in the `Resources` section of the template, this is the template fragment that's repeated to configure each resource.

## Return value


An expanded object that contains the object fragment repeated once for each item in the collection, where the identifier in the fragment is replaced with the item from the collection.

## Supported functions


You can use the following functions within `Fn::ForEach`.
+ Condition functions:
  + [`Fn::And`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-and)
  + [`Fn::Equals`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-equals)
  + [`Fn::If`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-if)
  + [`Fn::Not`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-not)
  + [`Fn::Or`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-or)
+ [`Fn::Base64`](intrinsic-function-reference-base64.md)
+ [`Fn::FindInMap`](intrinsic-function-reference-findinmap.md)
+ [`Fn::GetAtt`](intrinsic-function-reference-getatt.md)
+ [`Fn::GetAZs`](intrinsic-function-reference-getavailabilityzones.md)
+ [`Fn::ImportValue`](intrinsic-function-reference-importvalue.md)
+ [`Fn::Join`](intrinsic-function-reference-join.md)
+ [`Fn::Length`](intrinsic-function-reference-length.md)
+ [`Fn::Transform`](intrinsic-function-reference-transform.md)
+ [`Fn::Select`](intrinsic-function-reference-select.md)
+ [`Fn::Sub`](intrinsic-function-reference-sub.md)
+ [`Fn::ToJsonString`](intrinsic-function-reference-ToJsonString.md)
+ [`Ref`](intrinsic-function-reference-ref.md)

## Examples


You can find examples for the `Conditions`, `Outputs`, and `Resources` sections in [Examples](intrinsic-function-reference-foreach-examples.md).

# Examples


**Topics**
+ [

# Examples of `Fn::ForEach` in the `Resources` section
](intrinsic-function-reference-foreach-example-resource.md)
+ [

# Examples of `Fn::ForEach` in the `Outputs` section
](intrinsic-function-reference-foreach-example-outputs.md)
+ [

# Examples of `Fn::ForEach` in the `Conditions` section
](intrinsic-function-reference-foreach-example-conditions.md)

# Examples of `Fn::ForEach` in the `Resources` section
`Resources` section

These examples demonstrate using the `Fn::ForEach` intrinsic function in the `Resources` section. For more information about this section, see [Resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html) in the *AWS CloudFormation User Guide*.

**Topics**
+ [

## Replicate an Amazon SNS resource
](#intrinsic-function-reference-foreach-example-replicate-resource)
+ [

## Replicate an Amazon DynamoDB resource
](#intrinsic-function-reference-foreach-example-replicate-ddb-resource)
+ [

## Replicate multiple resources
](#intrinsic-function-reference-foreach-example-replicate-multiple-resources)
+ [

## Replicate multiple resources using a nested `Fn::ForEach` loops
](#intrinsic-function-reference-foreach-example-nested-loop-resources)
+ [

## Reference replicated properties for an Amazon EC2 resource
](#intrinsic-function-reference-foreach-example-reference-replicated-resource)
+ [

## Replicate properties for an Amazon EC2 resource
](#intrinsic-function-reference-foreach-example-replicate-resource-properties)
+ [

## Passing non-alphanumeric characters within the `Collection` for `Fn::ForEach`
](#intrinsic-function-reference-foreach-example-non-alphanumeric)

## Replicate an Amazon SNS resource


This example snippet returns a list of four Amazon SNS topics, with the logical ID corresponding to the items in the collection (`Success`, `Failure`, `Timeout`, `Unknown`), with a matching `TopicName` and `FifoTopic` set to `true`.

**Note**  
For templates that need to work with both FIFO and standard topics, you can use the `DisplayName` property instead of `TopicName`. This allows CloudFormation to automatically generate topic names with the appropriate `.fifo` suffix when `FifoTopic` is `true`. Simply replace `TopicName` with `DisplayName: !Ref TopicName` in the `Properties` section.

### JSON


```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Transform": "AWS::LanguageExtensions",
    "Resources": {
        "Fn::ForEach::Topics": [
            "TopicName",
            ["Success", "Failure", "Timeout", "Unknown"],
            {
                "SnsTopic${TopicName}": {
                    "Type": "AWS::SNS::Topic",
                    "Properties": {
                        "TopicName": {"Fn::Sub": "${TopicName}.fifo"},
                        "FifoTopic": true
                    }
                }
            }
        ]
    }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  'Fn::ForEach::Topics':
    - TopicName
    - [Success, Failure, Timeout, Unknown]
    - 'SnsTopic${TopicName}':
        Type: AWS::SNS::Topic
        Properties:
          TopicName: !Sub '${TopicName}.fifo'
          FifoTopic: true
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  SnsTopicSuccess:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: Success.fifo
      FifoTopic: true
  SnsTopicFailure:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: Failure.fifo
      FifoTopic: true
  SnsTopicTimeout:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: Timeout.fifo
      FifoTopic: true
  SnsTopicUnknown:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: Unknown.fifo
      FifoTopic: true
```

## Replicate an Amazon DynamoDB resource


This example snippet creates four [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html) resources with names such as `Points`, `Score`, etc.

### JSON


```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Transform": "AWS::LanguageExtensions",
    "Resources": {
        "Fn::ForEach::Tables": [
            "TableName",
            ["Points", "Score", "Name", "Leaderboard"],
            {
                "DynamoDB${TableName}": {
                    "Type": "AWS::DynamoDB::Table",
                    "Properties": {
                        "TableName": {
                            "Ref": "TableName"
                        },
                        "AttributeDefinitions": [
                            {
                                "AttributeName": "id",
                                "AttributeType": "S"
                            }
                        ],
                        "KeySchema": [
                            {
                                "AttributeName": "id",
                                "KeyType": "HASH"
                            }
                        ],
                        "ProvisionedThroughput": {
                            "ReadCapacityUnits": "5",
                            "WriteCapacityUnits": "5"
                        }
                    }
                }
            }
        ]
    }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  'Fn::ForEach::Tables':
    - TableName
    - [Points, Score, Name, Leaderboard]
    - 'DynamoDB${TableName}':
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: !Ref TableName
          AttributeDefinitions:
            - AttributeName: id
              AttributeType: S
          KeySchema:
            - AttributeName: id
              KeyType: HASH
          ProvisionedThroughput:
            ReadCapacityUnits: '5'
            WriteCapacityUnits: '5'
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  DynamoDBPoints:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Points
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: '5'
        WriteCapacityUnits: '5'
  DynamoDBScore:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Score
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: '5'
        WriteCapacityUnits: '5'
  DynamoDBName:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Name
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: '5'
        WriteCapacityUnits: '5'
  DynamoDBLeaderboard:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Leaderboard
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: '5'
        WriteCapacityUnits: '5'
```

## Replicate multiple resources


This example creates multiple instances of [AWS::EC2::NatGateway](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-natgateway.html) and [AWS::EC2::EIP](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-eip.html) using a naming convention of `"{ResourceType}${Identifier}"`. You can declare multiple resource types under one `Fn::ForEach` loop to take advantage of a single identifier.

Unique values for each element in the collection are defined within the `Mappings` section, where the [`Fn::FindInMap`](intrinsic-function-reference-findinmap.md) intrinsic function is used to reference the corresponding value. If `Fn::FindInMap` is unable to find the corresponding identifier, the `Condition` property will not be set resolving to `!Ref AWS:::NoValue`.

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Conditions": {
    "TwoNatGateways": {"Fn::Equals": [{"Ref": "AWS::Region"}, "us-east-1"]},
    "ThreeNatGateways": {"Fn::Equals": [{"Ref": "AWS::Region"}, "us-west-2"]}
  },
  "Mappings": {
    "NatGateway": {
      "Condition": {
        "B": "TwoNatGateways",
        "C": "ThreeNatGateways"
      }
    }
  },
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {"CidrBlock": "10.0.0.0/16"}
    },
    "PublicSubnetA": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "CidrBlock": "10.0.1.0/24",
        "AvailabilityZone": {"Fn::Select": [0, {"Fn::GetAZs": ""}]}
      }
    },
    "PublicSubnetB": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "CidrBlock": "10.0.2.0/24",
        "AvailabilityZone": {"Fn::Select": [1, {"Fn::GetAZs": ""}]}
      }
    },
    "PublicSubnetC": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {"Ref": "VPC"},
        "CidrBlock": "10.0.3.0/24",
        "AvailabilityZone": {"Fn::Select": [2, {"Fn::GetAZs": ""}]}
      }
    },
    "Fn::ForEach::NatGatewayAndEIP": [
      "Identifier",
      [ "A", "B", "C" ],
      {
        "NatGateway${Identifier}": {
          "Type": "AWS::EC2::NatGateway",
          "Properties": {
            "AllocationId": {"Fn::GetAtt": [{"Fn::Sub": "NatGatewayAttachment${Identifier}"}, "AllocationId"]},
            "SubnetId": {"Ref": {"Fn::Sub": "PublicSubnet${Identifier}"}}
          },
          "Condition": {"Fn::FindInMap": ["NatGateway", "Condition", {"Ref": "Identifier"}, {"DefaultValue": {"Ref": "AWS::NoValue"}}]}
        },
        "NatGatewayAttachment${Identifier}": {
          "Type": "AWS::EC2::EIP",
          "Properties": {
            "Domain": "vpc"
          },
          "Condition": {"Fn::FindInMap": ["NatGateway", "Condition", {"Ref": "Identifier"}, {"DefaultValue": {"Ref": "AWS::NoValue"}}]}
        }
      }
    ]
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Conditions:
  TwoNatGateways: !Equals [!Ref "AWS::Region", "us-east-1"]
  ThreeNatGateways: !Equals [!Ref "AWS::Region", "us-west-2"]
Mappings:
  NatGateway:
    Condition:
      B: TwoNatGateways
      C: ThreeNatGateways
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs ""]
  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs ""]
  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [2, !GetAZs ""]
  Fn::ForEach::NatGatewayAndEIP:
    - Identifier
    - - A
      - B
      - C
    - NatGateway${Identifier}:
        Type: AWS::EC2::NatGateway
        Properties:
          AllocationId: !GetAtt
            - !Sub NatGatewayAttachment${Identifier}
            - AllocationId
          SubnetId: !Ref
            Fn::Sub: PublicSubnet${Identifier}
        Condition: !FindInMap
          - NatGateway
          - Condition
          - !Ref Identifier
          - DefaultValue: !Ref AWS::NoValue
      NatGatewayAttachment${Identifier}:
        Type: AWS::EC2::EIP
        Properties:
          Domain: vpc
        Condition: !FindInMap
          - NatGateway
          - Condition
          - !Ref Identifier
          - DefaultValue: !Ref AWS::NoValue
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Conditions:
  TwoNatGateways: !Equals [!Ref "AWS::Region", "us-east-1"]
  ThreeNatGateways: !Equals [!Ref "AWS::Region", "us-west-2"]
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs ""]
  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs ""]
  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [2, !GetAZs ""]
  NatGatewayA:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt
        - NatGatewayAttachmentA
        - AllocationId
      SubnetId: !Ref PublicSubnetA
  NatGatewayB:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt
        - NatGatewayAttachmentB
        - AllocationId
      SubnetId: !Ref PublicSubnetB
    Condition: TwoNatGateways
  NatGatewayC:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt
        - NatGatewayAttachmentC
        - AllocationId
      SubnetId: !Ref PublicSubnetC
    Condition: ThreeNatGateways
  NatGatewayAttachmentA:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
  NatGatewayAttachmentB:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
    Condition: TwoNatGateways
  NatGatewayAttachmentC:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
    Condition: ThreeNatGateways
```

## Replicate multiple resources using a nested `Fn::ForEach` loops


This example uses nested `Fn::ForEach` loops to map three resources ( [AWS::EC2::NetworkAcl](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-natgateway.html), [AWS::EC2::Subnet](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnet.html), and [AWS::EC2::SubnetNetworkAclAssociation](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-subnetnetworkaclassociation.html)) with each other.

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Resources": {
    "VPC": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.0.0.0/16",
        "EnableDnsSupport": "true",
        "EnableDnsHostnames": "true"
      }
    },
    "Fn::ForEach::SubnetResources": [
      "Prefix",
      [
        "Transit",
        "Public"
      ],
      {
        "Nacl${Prefix}Subnet": {
          "Type": "AWS::EC2::NetworkAcl",
          "Properties": {
            "VpcId": {
              "Ref": "VPC"
            }
          }
        },
        "Fn::ForEach::LoopInner": [
          "Suffix",
          [
            "A",
            "B",
            "C"
          ],
          {
            "${Prefix}Subnet${Suffix}": {
              "Type": "AWS::EC2::Subnet",
              "Properties": {
                "VpcId": {
                  "Ref": "VPC"
                }
              }
            },
            "Nacl${Prefix}Subnet${Suffix}Association": {
              "Type": "AWS::EC2::SubnetNetworkAclAssociation",
              "Properties": {
                "SubnetId": {
                  "Ref": {
                    "Fn::Sub": "${Prefix}Subnet${Suffix}"
                  }
                },
                "NetworkAclId": {
                  "Ref": {
                    "Fn::Sub": "Nacl${Prefix}Subnet"
                  }
                }
              }
            }
          }
        ]
      }
    ]
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
  'Fn::ForEach::SubnetResources':
  - Prefix
  - [Transit, Public]
  - 'Nacl${Prefix}Subnet':
      Type: AWS::EC2::NetworkAcl
      Properties:
        VpcId: !Ref 'VPC'
    'Fn::ForEach::LoopInner':
    - Suffix
    - [A, B, C]
    - '${Prefix}Subnet${Suffix}':
        Type: AWS::EC2::Subnet
        Properties:
          VpcId: !Ref 'VPC'
      'Nacl${Prefix}Subnet${Suffix}Association':
        Type: AWS::EC2::SubnetNetworkAclAssociation
        Properties:
          SubnetId: !Ref
            'Fn::Sub': '${Prefix}Subnet${Suffix}'
          NetworkAclId: !Ref
            'Fn::Sub': 'Nacl${Prefix}Subnet'
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
  NaclTransitSubnet:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId: !Ref VPC
  TransitSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclTransitSubnetAAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref TransitSubnetA
      NetworkAclId: !Ref NaclTransitSubnet
  TransitSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclTransitSubnetBAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref TransitSubnetB
      NetworkAclId: !Ref NaclTransitSubnet
  TransitSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclTransitSubnetCAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref TransitSubnetC
      NetworkAclId: !Ref NaclTransitSubnet
  NaclPublicSubnet:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId: !Ref VPC
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclPublicSubnetAAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      NetworkAclId: !Ref NaclPublicSubnet
  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclPublicSubnetBAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      NetworkAclId: !Ref NaclPublicSubnet
  PublicSubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
  NaclPublicSubnetCAssociation:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref PublicSubnetC
      NetworkAclId: !Ref NaclPublicSubnet
```

## Reference replicated properties for an Amazon EC2 resource


This example uses the `Fn::ForEach` intrinsic function to reference replicated [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) resources.

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Mappings": {
    "Instances": {
      "InstanceType": {
        "B": "m5.4xlarge",
        "C": "c5.2xlarge"
      },
      "ImageId": {"A": "ami-id1"}
    }
  },
  "Resources": {
    "Fn::ForEach::Instances": [
      "Identifier",
      [
        "A",
        "B",
        "C"
      ],
      {
        "Instance${Identifier}": {
          "Type": "AWS::EC2::Instance",
          "Properties": {
            "InstanceType": {"Fn::FindInMap": ["Instances", "InstanceType", {"Ref": "Identifier"}, {"DefaultValue": "m5.xlarge"}]},
            "ImageId": {"Fn::FindInMap": ["Instances", "ImageId", {"Ref": "Identifier"}, {"DefaultValue": "ami-id-default"}]}
          }
        }
      }
    ]
  },
  "Outputs": {
    "SecondInstanceId": {
      "Description": "Instance Id for InstanceB",
      "Value": {"Ref": "InstanceB"}
    },
    "SecondPrivateIp": {
      "Description": "Private IP for InstanceB",
      "Value": {
        "Fn::GetAtt": [
          "InstanceB",
          "PrivateIp"
        ]
      }
    }
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Mappings:
  Instances:
    InstanceType:
      B: m5.4xlarge
      C: c5.2xlarge
    ImageId:
      A: ami-id1
Resources:
  'Fn::ForEach::Instances':
  - Identifier
  - [A, B, C]
  - 'Instance${Identifier}':
      Type: AWS::EC2::Instance
      Properties:
        InstanceType: !FindInMap [Instances, InstanceType, !Ref 'Identifier', {DefaultValue: m5.xlarge}]
        ImageId: !FindInMap [Instances, ImageId, !Ref 'Identifier', {DefaultValue: ami-id-default}]
Outputs:
  SecondInstanceId:
    Description: Instance Id for InstanceB
    Value: !Ref 'InstanceB'
  SecondPrivateIp:
    Description: Private IP for InstanceB
    Value: !GetAtt [InstanceB, PrivateIp]
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  InstanceA:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: m5.xlarge
      ImageId: ami-id1
  InstanceB:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: m5.4xlarge
      ImageId: ami-id-default
  InstanceC:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: c5.2xlarge
      ImageId: ami-id-default
Outputs:
  SecondInstanceId:
    Description: Instance Id for InstanceB
    Value: !Ref InstanceB
  SecondPrivateIp:
    Description: Private IP for InstanceB
    Value: !GetAtt [InstanceB, PrivateIp]
```

## Replicate properties for an Amazon EC2 resource


This example uses the `Fn::ForEach` intrinsic function to repeat some properties like `ImageId`, `InstanceType`, and `AvailabilityZone` to an [AWS::EC2::Instance](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-ec2-instance.html) resource.

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Mappings": {
    "InstanceA": {
      "Properties": {
        "ImageId": "ami-id1",
        "InstanceType": "m5.xlarge"
      }
    },
    "InstanceB": {
      "Properties": {
        "ImageId": "ami-id2"
      }
    },
    "InstanceC": {
      "Properties": {
        "ImageId": "ami-id3",
        "InstanceType": "m5.2xlarge",
        "AvailabilityZone": "us-east-1a"
      }
    }
  },
  "Resources": {
    "Fn::ForEach::Instances": [
      "InstanceLogicalId",
      [ "InstanceA", "InstanceB", "InstanceC" ],
      {
        "${InstanceLogicalId}": {
          "Type": "AWS::EC2::Instance",
          "Properties": {
            "DisableApiTermination": true,
            "UserData": {
              "Fn::Base64": {
                "Fn::Join": [
                  "",
                  [
                    "#!/bin/bash\n",
                    "yum update -y\n",
                    "yum install -y httpd.x86_64\n",
                    "systemctl start httpd.service\n",
                    "systemctl enable httpd.service\n",
                    "echo \"Hello World from $(hostname -f)\" > /var/www/html/index.html\n"
                  ]
                ]
              }
            },
            "Fn::ForEach::Properties": [
              "PropertyName",
              [ "ImageId", "InstanceType", "AvailabilityZone" ],
              {
                "${PropertyName}": {
                  "Fn::FindInMap": [
                    { "Ref": "InstanceLogicalId" },
                    "Properties",
                    { "Ref": "PropertyName"},
                    {
                      "DefaultValue": { "Ref": "AWS::NoValue" }
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    ]
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Mappings:
  InstanceA:
    Properties:
      ImageId: ami-id1
      InstanceType: m5.xlarge
  InstanceB:
    Properties:
      ImageId: ami-id2
  InstanceC:
    Properties:
      ImageId: ami-id3
      InstanceType: m5.2xlarge
      AvailabilityZone: us-east-1a
Resources:
  'Fn::ForEach::Instances':
  - InstanceLogicalId
  - [InstanceA, InstanceB, InstanceC]
  - '${InstanceLogicalId}':
      Type: AWS::EC2::Instance
      Properties:
        DisableApiTermination: true
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd.x86_64
            systemctl start httpd.service
            systemctl enable httpd.service
            echo "Hello World from $(hostname -f)" > /var/www/html/index.html
        'Fn::ForEach::Properties':
          - PropertyName
          - [ImageId, InstanceType, AvailabilityZone]
          - '${PropertyName}':
             'Fn::FindInMap':
               - Ref: 'InstanceLogicalId'
               - Properties
               - Ref: 'PropertyName'
               - {DefaultValue: !Ref 'AWS::NoValue'}
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  InstanceA:
    Type: AWS::EC2::Instance
    Properties:
      DisableApiTermination: true
      UserData:
        Fn::Base64: 
          !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd.x86_64
            systemctl start httpd.service
            systemctl enable httpd.service
            echo "Hello World from $(hostname -f)" > /var/www/html/index.html
      ImageId: ami-id1
      InstanceType: m5.xlarge
  InstanceB:
    Type: AWS::EC2::Instance
    Properties:
      DisableApiTermination: true
      UserData:
        Fn::Base64: 
          !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd.x86_64
            systemctl start httpd.service
            systemctl enable httpd.service
            echo "Hello World from $(hostname -f)" > /var/www/html/index.html
      ImageId: ami-id2
  InstanceC:
    Type: AWS::EC2::Instance
    Properties:
      DisableApiTermination: true
      UserData:
        Fn::Base64: 
          !Sub |
            #!/bin/bash
            yum update -y
            yum install -y httpd.x86_64
            systemctl start httpd.service
            systemctl enable httpd.service
            echo "Hello World from $(hostname -f)" > /var/www/html/index.html
      ImageId: ami-id3
      InstanceType: m5.2xlarge
      AvailabilityZone: us-east-1a
```

## Passing non-alphanumeric characters within the `Collection` for `Fn::ForEach`


This example uses the `&{}` syntax, which allows the non-alphanumeric characters (`.` and `/`) in the IP addresses to be passed within the `Collection`.

### JSON


```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Transform": "AWS::LanguageExtensions",
    "Parameters": {
        "IpAddresses": {
            "Type": "CommaDelimitedList",
            "Default": "10.0.2.0/24,10.0.3.0/24,10.0.4.0/24"
        }
    },
    "Resources": {
        "VPC": {
            "Type": "AWS::EC2::VPC",
            "Properties": {
                "CidrBlock": "10.0.0.0/16",
                "EnableDnsSupport": "true",
                "EnableDnsHostnames": "true"
            }
        },
        "Fn::ForEach::Subnets": [
            "CIDR",
            {
                "Ref": "IpAddresses"
            },
            {
                "Subnet&{CIDR}": {
                    "Type": "AWS::EC2::Subnet",
                    "Properties": {
                        "VpcId": {
                            "Ref": "VPC"
                        },
                        "CidrBlock": {
                            "Ref": "CIDR"
                        }
                    }
                }
            }
        ]
    }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Parameters:
  IpAddresses:
    Type: CommaDelimitedList
    Default: '10.0.2.0/24,10.0.3.0/24,10.0.4.0/24'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
  'Fn::ForEach::Subnets':
    - CIDR
    - !Ref IpAddresses
    - 'Subnet&{CIDR}':
        Type: AWS::EC2::Subnet
        Properties:
          VpcId: !Ref VPC
          CidrBlock: !Ref CIDR
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Parameters:
  IpAddresses:
    Type: CommaDelimitedList
    Default: '10.0.2.0/24,10.0.3.0/24,10.0.4.0/24'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
  Subnet1002024:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
  Subnet1003024:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
  Subnet1004024:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.4.0/24
```

# Examples of `Fn::ForEach` in the `Outputs` section
Outputs section

These examples demonstrate using the `Fn::ForEach` intrinsic function in the `Outputs` section. For more information about this section, see [Outputs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) in the *AWS CloudFormation User Guide*.

**Topics**
+ [

## Reference replicated `AWS::S3::Bucket` resources
](#intrinsic-function-reference-foreach-example-replicate-outputs)
+ [

## Reference replicated `AWS::EC2::Instance` resources
](#intrinsic-function-reference-foreach-example-replicate-conditions)

## Reference replicated `AWS::S3::Bucket` resources


This example uses nested `Fn::ForEach` loops in the `Outputs` section to reduce the template length.

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Resources": {
    "Fn::ForEach::Buckets": [
      "Identifier",
      [ "A", "B", "C" ],
      {
        "S3Bucket${Identifier}": {
          "Type": "AWS::S3::Bucket",
          "Properties": {
            "AccessControl": "PublicRead",
            "MetricsConfigurations": [
              {
                "Id": {"Fn::Sub": "EntireBucket${Identifier}"}
              }
            ],
            "WebsiteConfiguration": {
              "IndexDocument": "index.html",
              "ErrorDocument": "error.html",
              "RoutingRules": [
                {
                  "RoutingRuleCondition": {
                    "HttpErrorCodeReturnedEquals": "404",
                    "KeyPrefixEquals": "out1/"
                  },
                  "RedirectRule": {
                    "HostName": "ec2-11-22-333-44.compute-1.amazonaws.com",
                    "ReplaceKeyPrefixWith": "report-404/"
                  }
                }
              ]
            }
          },
          "DeletionPolicy": "Retain",
          "UpdateReplacePolicy": "Retain"
        }
      }
    ]
  },
  "Outputs": {
    "Fn::ForEach::BucketOutputs": [
      "Identifier",
      [ "A", "B", "C" ],
      {
        "Fn::ForEach::GetAttLoop": [
          "Property",
          [ "Arn", "DomainName", "WebsiteURL" ],
          {
            "S3Bucket${Identifier}${Property}": {
              "Value": {"Fn::GetAtt": [{"Fn::Sub": "S3Bucket${Identifier}"}, {"Ref": "Property"}]}
            }
          }
        ]
      }
    ]
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  'Fn::ForEach::Buckets':
    - Identifier
    - [A, B, C]
    - 'S3Bucket${Identifier}':
        Type: AWS::S3::Bucket
        Properties:
          AccessControl: PublicRead
          MetricsConfigurations:
            - Id: !Sub 'EntireBucket${Identifier}'
          WebsiteConfiguration:
            IndexDocument: index.html
            ErrorDocument: error.html
            RoutingRules:
              - RoutingRuleCondition:
                  HttpErrorCodeReturnedEquals: '404'
                  KeyPrefixEquals: out1/
                RedirectRule:
                  HostName: ec2-11-22-333-44.compute-1.amazonaws.com
                  ReplaceKeyPrefixWith: report-404/
        DeletionPolicy: Retain
        UpdateReplacePolicy: Retain
Outputs:
  'Fn::ForEach::BucketOutputs':
    - Identifier
    - [A, B, C]
    - 'Fn::ForEach::GetAttLoop':
        - Property
        - [Arn, DomainName, WebsiteURL]
        - 'S3Bucket${Identifier}${Property}':
            Value: !GetAtt [!Sub 'S3Bucket${Identifier}', !Ref Property]
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  S3BucketA:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      MetricsConfigurations:
        - Id: EntireBucketA
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
        RoutingRules:
          - RoutingRuleCondition:
              HttpErrorCodeReturnedEquals: '404'
              KeyPrefixEquals: out1/
            RedirectRule:
              HostName: ec2-11-22-333-44.compute-1.amazonaws.com
              ReplaceKeyPrefixWith: report-404/
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
  S3BucketB:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      MetricsConfigurations:
        - Id: EntireBucketB
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
        RoutingRules:
          - RoutingRuleCondition:
              HttpErrorCodeReturnedEquals: '404'
              KeyPrefixEquals: out1/
            RedirectRule:
              HostName: ec2-11-22-333-44.compute-1.amazonaws.com
              ReplaceKeyPrefixWith: report-404/
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
  S3BucketC:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      MetricsConfigurations:
        - Id: EntireBucketC
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
        RoutingRules:
          - RoutingRuleCondition:
              HttpErrorCodeReturnedEquals: '404'
              KeyPrefixEquals: out1/
            RedirectRule:
              HostName: ec2-11-22-333-44.compute-1.amazonaws.com
              ReplaceKeyPrefixWith: report-404/
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
Outputs:
  S3BucketAArn:
    Value: !GetAtt [S3BucketA, Arn]
  S3BucketADomainName:
    Value: !GetAtt [S3BucketA, DomainName]
  S3BucketAWebsiteURL:
    Value: !GetAtt [S3BucketA, WebsiteURL]
  S3BucketBArn:
    Value: !GetAtt [S3BucketB, Arn]
  S3BucketBDomainName:
    Value: !GetAtt [S3BucketB, DomainName]
  S3BucketBWebsiteURL:
    Value: !GetAtt [S3BucketB, WebsiteURL]
  S3BucketCArn:
    Value: !GetAtt [S3BucketC, Arn]
  S3BucketCDomainName:
    Value: !GetAtt [S3BucketC, DomainName]
  S3BucketCWebsiteURL:
    Value: !GetAtt [S3BucketC, WebsiteURL]
```

## Reference replicated `AWS::EC2::Instance` resources


This example references replicated resources in the `Resources` section using the generated logical IDs. 

### JSON


```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::LanguageExtensions",
  "Mappings": {
    "Instances": {
      "InstanceType": {
        "B": "m5.4xlarge",
        "C": "c5.2xlarge"
      },
      "ImageId": {"A": "ami-id1"}
    }
  },
  "Resources": {
    "Fn::ForEach::Instances": [
      "Identifier",
      [ "A", "B", "C" ],
      {
        "Instance${Identifier}": {
          "Type": "AWS::EC2::Instance",
          "Properties": {
            "InstanceType": {"Fn::FindInMap": ["Instances", "InstanceType", {"Ref": "Identifier"}, {"DefaultValue": "m5.xlarge"}]},
            "ImageId": {"Fn::FindInMap": ["Instances", "ImageId", {"Ref": "Identifier"}, {"DefaultValue": "ami-id-default"}]}
          }
        }
      }
    ]
  },
  "Outputs": {
    "SecondInstanceId": {
      "Description": "Instance Id for InstanceB",
      "Value": {"Ref": "InstanceB"}
    },
    "SecondPrivateIp": {
      "Description": "Private IP for InstanceB",
      "Value": {
        "Fn::GetAtt": [
          "InstanceB",
          "PrivateIp"
        ]
      }
    }
  }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Mappings:
  Instances:
    InstanceType:
      B: m5.4xlarge
      C: c5.2xlarge
    ImageId:
      A: ami-id1
Resources:
  'Fn::ForEach::Instances':
    - Identifier
    - [A, B, C]
    - 'Instance${Identifier}':
        Type: AWS::EC2::Instance
        Properties:
          InstanceType: !FindInMap [Instances, InstanceType, !Ref Identifier, DefaultValue: m5.xlarge]
          ImageId: !FindInMap [Instances, ImageId, !Ref Identifier, DefaultValue: ami-id-default]
Outputs:
  SecondInstanceId:
    Description: Instance Id for InstanceB
    Value: !Ref InstanceB
  SecondPrivateIp:
    Description: Private IP for InstanceB
    Value: !GetAtt [InstanceB, PrivateIp]
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Resources:
  InstanceA:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: m5.xlarge
      ImageId: ami-id1
  InstanceB:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: m5.4xlarge
      ImageId: ami-id-default
  InstanceC:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: c5.2xlarge
      ImageId: ami-id-default
Outputs:
  SecondInstanceId:
    Description: Instance Id for InstanceB
    Value: !Ref InstanceB
  SecondPrivateIp:
    Description: Private IP for InstanceB
    Value: !GetAtt [InstanceB, PrivateIp]
```

# Examples of `Fn::ForEach` in the `Conditions` section
`Conditions` section

These examples demonstrate using the `Fn::ForEach` intrinsic function in the `Conditions` section. For more information about this section, see [Conditions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html) in the *AWS CloudFormation User Guide*.

**Important**  
`Conditions` must be the second property listed, or later. Stack creation will fail if `Conditions` is the first property listed within the template fragment parameter of `Fn::ForEach`.

```
Resources:
  'Fn::ForEach::Topics':
    - LogicalId
    - !Ref TopicList
    - '${LogicalId}':
        Condition: !Sub 'TopicCondition${LogicalId}'
        Type: AWS::SNS::Topic
        Properties:
          TopicName: !Sub 'My${LogicalId}'
```

`Conditions` must be added as the second key, or later, for stack creation to succeed: 

```
Resources:
  'Fn::ForEach::Topics':
    - LogicalId
    - !Ref TopicList
    - '${LogicalId}':
        Type: AWS::SNS::Topic
        Condition: !Sub 'TopicCondition${LogicalId}'
        Properties:
          TopicName: !Sub 'My${LogicalId}'
```

**Topics**
+ [

## Replicate a single condition
](#intrinsic-function-reference-foreach-example-replicated-single-condition)

## Replicate a single condition


This example uses the `Fn::ForEach` intrinsic function in the `Conditions` section to replicate multiple similar conditions with different properties.

### JSON


```
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Transform": "AWS::LanguageExtensions",
    "Parameters": {
        "ParamA": {
            "Type": "String",
            "AllowedValues": [
                "true",
                "false"
            ]
        },
        "ParamB": {
            "Type": "String",
            "AllowedValues": [
                "true",
                "false"
            ]
        },
        "ParamC": {
            "Type": "String",
            "AllowedValues": [
                "true",
                "false"
            ]
        },
        "ParamD": {
            "Type": "String",
            "AllowedValues": [
                "true",
                "false"
            ]
        }
    },
    "Conditions": {
        "Fn::ForEach::CheckTrue": [
            "Identifier",
            ["A", "B", "C", "D"],
            {
                "IsParam${Identifier}Enabled": {
                    "Fn::Equals": [
                        {"Ref": {"Fn::Sub": "Param${Identifier}"}},
                        "true"
                    ]
                }
            }
        ]
    },
    "Resources": {
        "WaitConditionHandle": {
            "Type": "AWS::CloudFormation::WaitConditionHandle"
        }
    }
}
```

### YAML


```
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Parameters:
  ParamA:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamB:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamC:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamD:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
Conditions:
  'Fn::ForEach::CheckTrue':
    - Identifier
    - [A, B, C, D]
    - 'IsParam${Identifier}Enabled': !Equals 
        - !Ref 
          'Fn::Sub': 'Param${Identifier}'
        - 'true'
Resources:
  WaitConditionHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
```

The transformed template will be equivalent to the following template:

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  ParamA:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamB:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamC:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
  ParamD:
    Type: String
    AllowedValues:
      - 'true'
      - 'false'
Conditions:
  IsParamAEnabled: !Equals 
    - !Ref ParamA
    - 'true'
  IsParamBEnabled: !Equals 
    - !Ref ParamB
    - 'true'
  IsParamCEnabled: !Equals 
    - !Ref ParamC
    - 'true'
  IsParamDEnabled: !Equals 
    - !Ref ParamD
    - 'true'
Resources:
  WaitConditionHandle:
    Type: AWS::CloudFormation::WaitConditionHandle
```