How do I pass a list of strings as a parameter in CloudFormation?

29,591

Solution 1

Because the return value of !Split is A list of string values. I would do it in the following way:

[...]
    Resource: !Split [",", !Ref S3Buckets]
[...]

Solution 2

As @MaiKaY points out, the flaw in @Liam Mayfair's code is that Fn::Split is preceded by - which results in a list containing a single element which is a list. The fixed code would look like

...
            Resource:
              Fn::Split:
                - ","
                - !Ref S3Buckets

On a more general note, you must make sure to use a Parameter type of String not CommaDelimitedList when using Fn::Split as it won't split a CommaDelimitedList.

  • If you use CommaDelimitedList with Fn::Split you'll get the error Template error: every Fn::Split object requires two parameters, (1) a string delimiter and (2) a string to be split or a function that returns a string to be split
  • If you use CommaDelimitedList with no Fn::Split you'll get the error Syntax errors in policy
Share:
29,591
Liam Mayfair
Author by

Liam Mayfair

Updated on July 09, 2022

Comments

  • Liam Mayfair
    Liam Mayfair almost 2 years

    I've got a nested CloudFormation template which accepts a number of parameters from its root template to configure it. At the moment I'm only passing simple string parameters but now I need to pass a list of S3 bucket ARNs onto the child template.

    ChildLambdaStack:
      Type: AWS::CloudFormation::Stack
      Properties:
        Parameters:
          AwsRegion: !Ref AwsRegion
          Environment: !Ref Environment
          Product: !Ref Product
          S3Buckets: "arn:aws:s3:::bucket1,arn:aws:s3:::bucket2"
        TemplateURL: "https://s3.amazonaws.com/child-template.yml"
    

    And then in the child template I have this

    AWSTemplateFormatVersion: "2010-09-09"
    Description: "Child Lambda"
    
    Parameters:
      AwsRegion:
        Type: String
      Environment:
        Type: String
      Product:
        Type: String
      S3Buckets:
        Type: String
    
    Resources:
      DeployerPolicy:
        Type: AWS::IAM::ManagedPolicy
        Properties:
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:PutObject
                  - s3:GetObject
                  - s3:DeleteObject
                  - s3:CreateBucket
                  - s3:DeleteBucket
                  - s3:ListBucket
                  - s3:PutBucketNotification
                Resource:
                  - Fn::Split:
                    - ","
                    - !Ref S3Buckets
    

    My idea is that that list of S3 bucket ARNs that I'm inputting is expanded in the child template like this

    Resource:
      - arn:aws:s3:::bucket1
      - arn:aws:s3:::bucket2
    

    But when I run the template in, it just errors out

    Syntax errors in policy. (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument)
    

    I've tried other variations like using a CommaDelimitedList parameter type, but none work. Is there a simple way to pass in a list of strings as a parameter?