how to use !Sub for array of arn in cloudformation

I have function defined like this:

Type: AWS::Serverless::Function
Properties:
  FunctionName: !Join
    - "-"
    - - !Ref NamePrefix
      - !FindInMap [ NameMap, SEND-SES-EMAIL-FUNCTION, NAME ]
      - !Ref NamePostfix
  Description: "Lambda function to send email with CSV file through SES"
  CodeUri: source/resources/sendSESEmailFunction
  Handler: sendSESEmail.lambda_handler
  Policies:
    - AWSLambdaBasicExecutionRole
    - Version: 2012-10-17
      Statement:
        - Sid: SESPermissions
          Effect: Allow
          Action:
            - 'ses:SendEmail'
          Resource:
            - !Sub
            - 'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${SenderEmail}'
            - SenderEmail: !Ref SenderSESEmail
              SESAccountID: !Ref SESAccountID
            - !Sub
            - 'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${ReceiverEmail}'
            - ReceiverEmail: 'testing'
              SESAccountID: !Ref SESAccountID

My goal is to use !Sub on multiple ARN’s under Resource of Lambda policy but this is throwing error like this: Syntax errors in policy. (Service:
AmazonIdentityManagement; Status Code: 400; Error Code:
MalformedPolicyDocument

>Solution :

If you look at your policy, Resource takes a list of resource ARNs which you’re creating with Fn::Sub. But SenderEmail and ReceiverEmail are defined as separate items in the list of Resource not within the !Sub to which they apply.

The correct structure would be:

              Resource:
                - !Sub 
                  - 'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${SenderEmail}'
                  - SenderEmail: !Ref SenderSESEmail
                    SESAccountID: !Ref SESAccountID
                - !Sub
                  -'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${ReceiverEmail}'
                  - ReceiverEmail: 'testing'

I’ve always found the !Sub syntax confusing. This is the alternative which makes the structure more clear:

              Resource:
                - Fn::Sub: 
                  - 'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${SenderEmail}'
                  - SenderEmail: !Ref SenderSESEmail
                    SESAccountID: !Ref SESAccountID
                - Fn::Sub:
                  -'arn:aws:ses:${AWS::Region}:${SESAccountID}:identity/${ReceiverEmail}'
                  - ReceiverEmail: 'testing'

Leave a Reply