简体   繁体   English

使用 cloudformation 创建时,sns 无法触发 lambda

[英]sns unable to trigger lambda when created using cloudformation

I have gone through many blogs but none of them solves my issue.我浏览了很多博客,但没有一个能解决我的问题。 SNS created by cloudformation is unable to trigger the lambda created by the same cloudformation, I see the trigger as sns in lambda but it didn't trigger it, below is the code. cloudformation创建的SNS无法触发同一个cloudformation创建的lambda,我看到触发是lambda中的sns但是没有触发,下面是代码。

Tried all solution suggested like using only SourceArn in lambda permission instead of SourceAccountId and all尝试了所有建议的解决方案,例如在 lambda 权限中仅使用 SourceArn 而不是 SourceAccountId 和所有

LambdaBasicExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: "LambdaBasicExecutionRole"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies: 
        - 
          PolicyName: "LambdaPolicyEC2KeyPair"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: 
                  - "kms:ListGrants"
                  - "kms:CreateGrant"
                  - "kms:Encrypt"
                  - "kms:Decrypt"
                Resource: "arn:aws:kms:*:*:*"
              - 
                Effect: "Allow"
                Action: 
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                Resource: "arn:aws:logs:*:*:*"
              - 
                Effect: "Allow"
                Action: "ec2:CreateKeyPair"
                Resource: "*"
              - 
                Effect: "Allow"
                Action: "ssm:PutParameter"
                Resource: "*"

  LambdaFunctionEC2KeyPair:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: LambdaFunctionEC2KeyPair
      Description: "Lambda Function to create EC2 KeyPair and storing it's private key securely to paramater store"
      Handler: index.handler
      Runtime: python3.6
      Role: !GetAtt LambdaBasicExecutionRole.Arn
      Code:
        ZipFile: |
          import boto3, os, botocore, cfnresponse

          client = boto3.client('ec2')
          ssm = boto3.client("ssm")

          def handler(event, context):
            ###############################
            # Variable Defination from CF #
            ###############################

            IIS = ['service', 'engine', 'micro']

            namespace = "IIS"
            keyid = os.environ['kmsid']
            env = os.environ['env']

            for iis_tier in IIS:
              keyname = 'IIS-EC2-KeyPair-'+iis_tier+'-'+env
              try:
                response = client.create_key_pair(
                  KeyName=keyname
                )

              except botocore.exceptions.ClientError as e:
                if e.response['Error']['Code'] == 'InvalidKeyPair':
                  print ("Invalid Key Pair Duplicate Error")
                  continue
                else:
                  continue

              try:
                ssm_response = ssm.put_parameter(
                  Name=f"/{namespace}/{env}/EC2-KeyPair/{iis_tier}",
                  Value=response['KeyMaterial'],
                  Type="SecureString",
                  KeyId=keyid,
                  Description='Private key for '+iis_tier+' '+env+' EC2 instance for ssh connection, one would need it for making ssh connection with the instance for administrative purposes'
                )
              except botocore.exceptions.ClientError as e:
                if e.response['Error']['Code'] == 'AccessDeniedException':
                  print ("Access Denied Error")
                  continue
                else:
                  continue
            cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, physicalResourceId )
            return



      Environment:
        Variables: 
          env: !Ref Environment
          kmsid: !Ref kmsKeyIIS
    DependsOn: LambdaBasicExecutionRole


  EC2KeyPair:
    Type: Custom::EC2KeyPairResource
    Properties:
      ServiceToken: !GetAtt LambdaFunctionEC2KeyPair.Arn

It appears that you are wanting to trigger an AWS Lambda function when the CloudFormation stack deploys.您似乎希望在部署 CloudFormation 堆栈时触发 AWS Lambda function。

You can do this with an AWS Lambda-backed Custom Resource .您可以使用AWS Lambda 支持的自定义资源来执行此操作。

The template should include:模板应包括:

  • The Lambda function Lambda function
  • A Custom:: entry to trigger your Lambda function A Custom:: entry 触发你的 Lambda function

The Lambda function will need to signal back when it is complete. Lambda function 完成后需要发回信号。 There is a cfn-response Module provided to assist with this.提供了一个cfn-response 模块来帮助解决这个问题。 It is available for Node.js and Python.它适用于 Node.js 和 Python。

Here is a basic CloudFormation template that deploys and runs a Custom Resource:这是部署和运行自定义资源的基本 CloudFormation 模板:

AWSTemplateFormatVersion: 2010-09-09

Resources:

  LambdaBasicExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: MyLambdaRole
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          -
            Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  LambdaFunctionTest:
    Type: AWS::Lambda::Function
    DependsOn: LambdaBasicExecutionRole
    Properties:
      FunctionName: LambdaFunctionTest
      Description: Lambda Function to test that Custom Resource works
      Handler: index.handler
      Runtime: python3.6
      Role: !GetAtt LambdaBasicExecutionRole.Arn
      Code:
        ZipFile: |
          import boto3
          import cfnresponse

          def handler(event, context):
            print('This is in the handler')

            responseData = {}
            cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
            return

  CustomFunctionTest:
    Type: Custom::CustomFunctionTest
    Properties:
      ServiceToken: !GetAtt LambdaFunctionTest.Arn

I have AWS::Serverless::Function and there's Events attribute in the its properties.我有AWS::Serverless::Function并且其属性中有Events属性。 If you had that, then your configuration would be something like this:如果你有,那么你的配置将是这样的:

LambdaFunctionEC2KeyPair:
  Type: AWS::Lambda::Function
  Properties:
    FunctionName: LambdaFunctionEC2KeyPair
    Description: "Lambda Function to create EC2 KeyPair and storing it's private key securely to paramater store"
    Handler: index.handler
    Runtime: python3.6
    Role: !GetAtt LambdaBasicExecutionRole.Arn
    Code:
      ZipFile: |
        My code


    Environment:
      Variables: 
        env: !Ref Environment
        kmsid: !Ref kmsKeyIIS
    Events:
      SNSTopicMessage:
        Type: SNS
        Properties:
          Topic:
            Fn::Join:
              - ':'
              - - arn
                - Ref: AWS::Partition
                - sns
                - Ref: AWS::Region
                - Ref: AWS::AccountId
                - SNSTopicLambdaInvoke
  DependsOn: LambdaBasicExecutionRole

I am checking about your use case having AWS::Lambda::Function .我正在检查您的用例是否具有AWS::Lambda::Function

You can check this example .你可以检查这个例子

About the difference between a Serverless Function, and a Lambda Function you can check in this answer: What is the difference between a Serverless Function, and a Lambda Function About the difference between a Serverless Function, and a Lambda Function you can check in this answer: What is the difference between a Serverless Function, and a Lambda Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM