使用无服务器使用电子邮件协议和电子邮件地址端点创建SNS主题

时间:2019-02-27 18:28:32

标签: python aws-lambda amazon-sns serverless-framework serverless

使用serverless创建Lambda函数,我正在尝试使用电子邮件协议创建SNS主题。然后,我想将该arn作为ENV变量传递给lambda函数。除了在创建过程中附加主题以起作用之外,我找不到任何文档。任何帮助/示例都表示赞赏(我在python中工作)。

为详细说明,下面将创建一个附加了sns主题的函数。

functions:
  dispatcher:
    handler: dispatcher.dispatch
    events:
      - sns: dispatch

希望做一些“事情”(这不起作用,只是一个例子):

events:
  sns:
    topicName: thing
    subscription: 
      - endPoint: "myemail@thing.com"
      - protocol: "email"

functions:
  dispatcher:
    handler: dispatcher.dispatch
    environment:
      SNS_TOPIC: {Ref: ThingSnsTopic}

理想情况下,将在函数外部创建sns部分,并且我可以引用sns arn并将其用作环境变量

2 个答案:

答案 0 :(得分:0)

使用无服务器时,可以在.yml文件中使用环境变量,如下所示:

myProperty: ${env:MY_ENV_VAR}

如果要将其绑定到SNS,您的.yml文件应类似于:

service: my-service


provider:
  name: aws
  runtime: python3.6


functions:
  hello:
    handler: handler.hello

   events:
     - sns: ${env:MY_ENV_VAR}

现在,如果您想从Lambda函数中访问环境变量,则将取决于您使用哪种语言进行编码,但是由于您使用的是Python,因此它类似于: / p>

import os

print("environment variable: " + os.environ['MY_ENV_VAR'])

EDIT :在OP发表评论后,我认为我完全理解了这个问题:

ARN是可预测的值。它们几乎是您的地区/用户ID /主题名称的串联,例如:

arn:aws:sns:us-east-1:00000000:aaa

如果为Serverless.yml提供环境变量,例如:

provider:
 name: aws
 stage: ${opt:stage, 'dev'}
 environment:
  MY_SECRET: ${env:MY_ENV_VAR}

然后,您可以根据可预测的订阅的ARN +您定义的环境变量,以编程方式create a Subscription进入该主题。

另一种选择是在.yml文件中定义Outputs部分,然后使用CloudFormation Event触发Lambda,该Lambda将基于输出的ARN以编程方式创建订阅

答案 1 :(得分:0)

我在资源部分创建SNS主题和订阅,然后在lambda角色中添加一个策略,该策略可以分配给lambda函数,例如

Resources:  
  # SNS Topic Resources for email notification
  uploadProgressNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      DisplayName: "The notification topic for upload progress"
      TopicName: ${self:custom.uploadProgressNotificationTopicName}

  # SNS email subscription for upload completion
  emailToSNSUploadProgressNotificationTopicSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Endpoint: "$subscription_email_here"
      Protocol: "email"
      TopicArn: ${self:custom.uploadProgressNotificationTopicArn}

然后您的lambda角色资源如下所示(我个人将SNS和lambda角色资源分为不同的Yaml)

  Resources: 
    # Upload lambda roles
      UploadLambdaRole:
        Type: AWS::IAM::Role
        Properties:
          RoleName: ${self:custom.uploadLambdaRoleName}
          AssumeRolePolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Principal:
                  Service: lambda.amazonaws.com
                Action:
                  - sts:AssumeRole
          Policies:
            - PolicyName: AccessUploadProgressNotificationSNSTopic
                PolicyDocument:
                  Statement:
                    - Effect: Allow
                      Action:
                        - "sns:*"
                      Resource: "${self:custom.uploadProgressNotificationTopicArn}"

最后,您可以在如下所示的lambda函数中使用此lambda角色

upload:
  handler: src/handler/upload-handler
  role: UploadLambdaRole
  ...

因此,此功能的作用是您的lambda可以将消息发送到您的SNS主题,而SNS会将消息转发到您的电子邮件。