Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 542
Liam Mayfair Avatar asked Aug 30 '18 11:08

Liam Mayfair


People also ask

How do you set parameters in CloudFormation?

General requirements for parameters Each parameter must be given a logical name (also called logical ID), which must be alphanumeric and unique among all logical names within the template. Each parameter must be assigned a parameter type that is supported by AWS CloudFormation.

How do I beat CommaDelimitedList?

You can't pass values of type CommaDelimitedList to a nested stack. Instead, use the Fn::Join intrinsic function in your parent stack to convert type CommaDelimitedList to type String.

What are parameters which are predefined by CloudFormation called?

Pseudo parameters are parameters that are predefined by AWS CloudFormation. You don't declare them in your template. Use them the same way as you would a parameter, as the argument for the Ref function.

How do I pass UserData in CloudFormation?

2 Answers. Show activity on this post. Inside your template, use a CloudFormation parameter for the instance userdata: { "Parameters": { "UserData": { "Type": "String" } }, "Resources": { "Instance": { "Type" : "AWS::EC2::Instance", "Properties" : { "UserData" : { "Ref" : "UserData" }, ... } }, ... } }

How do I pass multiple values for individual parameters in CloudFormation?

You can pass multiple values for individual parameters in an AWS CloudFormation template in the following ways: Use AWS-specific parameter types to select values from a pre-populated list of existing AWS values from an AWS account

How to get the parameter type in AWS CloudFormation?

However, they can view information about each parameter, such as the parameter type, by using the aws cloudformation get-template-summary command or GetTemplateSummary API. You can use the CommaDelimitedList parameter type to specify multiple string values in a single parameter.

What is allowedvalues in CloudFormation?

AllowedValues: another property that provides a control mechanism for inputs in a parameter. You could use this to control the EC2 instance type and sizes in a template. Outside of the custom parameters you define, there are several built-in parameter types included in CloudFormation.

How to pass commadelimitedlist parameters to nested stacks in AWS CloudFormation?

I want to pass CommaDelimitedList parameters to nested stacks in AWS CloudFormation. You can't pass values of type CommaDelimitedList to a nested stack. Instead, use the Fn::Join intrinsic function in your parent stack to convert type CommaDelimitedList to type String.


2 Answers

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

[...]
    Resource: !Split [",", !Ref S3Buckets]
[...]
like image 191
MaiKaY Avatar answered Oct 13 '22 00:10

MaiKaY


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
like image 20
gene_wood Avatar answered Oct 12 '22 23:10

gene_wood