Search code examples
aws-lambdaaws-cloudformationamazon-sns

Cannot setup aws SNS trigger Lambda function


I used this template to create a cloudformation stack

Description: App Store Env

Parameters:
  SourceAccountId:
    Description: source S3 bucket owner account ID
    Type: String

  SourceS3Bucket:
    Description: source S3 bucket
    Type: String

  AipEnv:
    Description: AIP environment
    Type: String
    Default: preprod

  ServiceName:
    Description: Service Name
    Type: String

  ServiceVersion:
    Description: Service Version
    Type: String

  DescriptionTag:
    Description: Service description
    Type: String
    Default: ""

  LambdaRoleName:
    Description: Lambda role name
    Type: String
    Default: Nucleus-Renegade-Lambda

Mappings:
  EnvironmentMap:
    dev:
      ApplicationId: {some_value}
      BillingTag: AppStore-Services
      CostCenterTag: 
      TeamBucket: {some_value}
      TeamDataBucket: {some_value}
      AccountId: {some_value}
      SecurityGroups:
        - {some_value}
        - {some_value}
      Subnets:
        - {some_value}
        - {some_value}

    preprod:
      ApplicationId: {some_value}
      BillingTag: AppStore-Services
      CostCenterTag: {some_value}
      TeamBucket: {some_value}
      TeamDataBucket: {some_value}
      AccountId: {some_value}
      SecurityGroups:
        - {some_value}
      Subnets:
        - {some_value}
        - {some_value}

    prod:
      ApplicationId: {some_value}
      BillingTag: AppStore-Services
      CostCenterTag: {some_value}
      TeamBucket: {some_value}
      TeamDataBucket: {some_value}
      AccountId: {some_value}

Resources:

  S3SyncLambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Handler: app.lambda_handler
      MemorySize: 512
      Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/${LambdaRoleName}"
      Code:
        S3Bucket: !FindInMap
          - EnvironmentMap
          - !Ref AipEnv
          - TeamBucket
        S3Key: !Sub >-
          ${ServiceName}/lambda/s3sync/${ServiceVersion}/lambda-function.zip
      FunctionName: !Sub >-
          aip-s3sync-${AipEnv}-${ServiceName}-${ServiceVersion}
      Runtime: python3.9
      Timeout: 300
      Environment:
        Variables:
          TEAM_BUCKET: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - TeamBucket
      Tags:
        - Key: Billing
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - BillingTag
        - Key: COST_CENTER
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - CostCenterTag
        - Key: APP_ID
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - ApplicationId
        - Key: Description
          Value: !Ref DescriptionTag

  AdtTopic:
    Type: 'AWS::SNS::Topic'
    Properties:
      TopicName: !Sub "aip-${AipEnv}-${ServiceName}-NewAdtSNS"
      KmsMasterKeyId: alias/SNS
      Tags:
        - Key: Billing
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - BillingTag
        - Key: COST_CENTER
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - CostCenterTag
        - Key: APP_ID
          Value: !FindInMap
            - EnvironmentMap
            - !Ref AipEnv
            - ApplicationId
        - Key: Description
          Value: !Ref DescriptionTag

  AdtTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      PolicyDocument:
        Id: AdtTopicPolicy
        Version: '2012-10-17'
        Statement:
          - Sid: Allow-S3-id
            Effect: Allow
            Principal:
              Service: s3.amazonaws.com
            Action: sns:Publish
            Resource: !Ref AdtTopic
            Condition:
                StringEquals:
                  aws:SourceAccount: !Ref SourceAccountId
                ArnLike:
                  aws:SourceArn: !Sub "arn:aws:s3:*:*:${SourceS3Bucket}"
      Topics:
        - !Ref AdtTopic

  InvokeLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref S3SyncLambdaFunction
      Principal: sns.amazonaws.com
      SourceArn: !Ref AdtTopic

However, after the stack is created, I checked lambda function trigger and found:

SNS: 
A subscription for {lambda_function_arn} on the topic {sns_topic} could not be found.

Do not know which part in template is wrong. I use InvokeLambdaPermission to configure sns trigger to lambda function. Can anyone help me on this issue?

Regards, Arthur


Solution

  • You have to define AWS::SNS::Subscription which is going to subscribe your lambda to a given sns topic.