Amazon ec2 以SNS为目标触发Lambda函数

Amazon ec2 以SNS为目标触发Lambda函数,amazon-ec2,aws-lambda,amazon-sns,amazon-cloudwatch,Amazon Ec2,Aws Lambda,Amazon Sns,Amazon Cloudwatch,我有一个Lambda函数正在100%工作,我设置了我的Cloudwatch规则,并将目标直接连接到Lambda,一切正常。 我的经理希望我在Cloudwatch中更改目标并将其设置为SNS,然后在Lambda中将SNS用作触发器。 我已经做了必要的事情,现在我的Lambda函数不再工作了 import os, json, boto3 def validate_instance(rec_event): sns_msg = json.loads(rec_event['Records'][0

我有一个Lambda函数正在100%工作,我设置了我的Cloudwatch规则,并将目标直接连接到Lambda,一切正常。 我的经理希望我在Cloudwatch中更改目标并将其设置为SNS,然后在Lambda中将SNS用作触发器。 我已经做了必要的事情,现在我的Lambda函数不再工作了

import os, json, boto3

def validate_instance(rec_event):
    sns_msg = json.loads(rec_event['Records'][0]['Sns']['Message'])

    account_id = sns_msg['account']
    event_region = sns_msg['region']

    assumedRoleObject = sts_client.assume_role(
        RoleArn="arn:aws:iam::{}:role/{}".format(account_id, 'VSC-Admin-Account-Lambda-Execution-Role'),
        RoleSessionName="AssumeRoleSession1"
    )

    credentials = assumedRoleObject['Credentials']
    print(credentials)

    ec2_client = boto3.client('ec2', event_region, aws_access_key_id=credentials['AccessKeyId'],
                              aws_secret_access_key=credentials['SecretAccessKey'],
                              aws_session_token=credentials['SessionToken'],
                              )

def lambda_handler(event, context):
    ip_permissions=[]
    print("The event log is " + str(event))
    # Ensure that we have an event name to evaluate.
    if 'detail' not in event or ('detail' in event and 'eventName' not in event['detail']):
        return {"Result": "Failure", "Message": "Lambda not triggered by an event"}
    elif event['detail']['eventName'] == 'AuthorizeSecurityGroupIngress':
        items_ip_permissions = event['detail']['requestParameters']['ipPermissions']['items']
        security_group_id=event['detail']['requestParameters']['groupId']
        print("The total items are " + str(items_ip_permissions))
        for item in items_ip_permissions:
            s = [val['cidrIp'] for val in item['ipRanges']['items']]
            print("The value of ipranges are " + str(s))
            if ((item['fromPort'] == 22 and item['toPort'] == 22) or (item['fromPort'] == 143 and item['toPort'] == 143) or (item['fromPort'] == 3389 and item['toPort'] == 3389)) and ('0.0.0.0/0' in [val['cidrIp'] for val in item['ipRanges']['items']]):
                print("Revoking the security rule for the item" + str(item))
                ip_permissions.append(item)
        result = revoke_security_group_ingress(security_group_id,ip_permissions)
    else:
        return 

def revoke_security_group_ingress(security_group_id,ip_permissions):
    print("The security group id is " + str(security_group_id))
    print("The ip_permissions value to be revoked is " + str(ip_permissions))
    ip_permissions_new=normalize_paramter_names(ip_permissions)
    response = boto3.client('ec2').revoke_security_group_ingress(GroupId=security_group_id,IpPermissions=ip_permissions_new)
    print("The response of the revoke is " + str(response))

def normalize_paramter_names(ip_items):
    # Start building the permissions items list.
    new_ip_items = []

    # First, build the basic parameter list.
    for ip_item in ip_items:

    new_ip_item = {
        "IpProtocol": ip_item['ipProtocol'],
        "FromPort": ip_item['fromPort'],
        "ToPort": ip_item['toPort']
    }

    # CidrIp or CidrIpv6 (IPv4 or IPv6)?
    if 'ipv6Ranges' in ip_item and ip_item['ipv6Ranges']:
        # This is an IPv6 permission range, so change the key names.
        ipv_range_list_name = 'ipv6Ranges'
        ipv_address_value = 'cidrIpv6'
        ipv_range_list_name_capitalized = 'Ipv6Ranges'
        ipv_address_value_capitalized = 'CidrIpv6'
    else:
        ipv_range_list_name = 'ipRanges'
        ipv_address_value = 'cidrIp'
        ipv_range_list_name_capitalized = 'IpRanges'
        ipv_address_value_capitalized = 'CidrIp'

    ip_ranges = []

    # Next, build the IP permission list.
    for item in ip_item[ipv_range_list_name]['items']:
        ip_ranges.append(
            {ipv_address_value_capitalized: item[ipv_address_value]}
        )

    new_ip_item[ipv_range_list_name_capitalized] = ip_ranges

    new_ip_items.append(new_ip_item)

    return new_ip_items

假设权限丢失导致调用失败

您需要显式授予SNS调用Lambda函数的权限

下面是CLI

aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns-my-topic \
--principal sns.amazonaws.com --source-arn arn:aws:sns:us-east-2:123456789012:my-topic
我的函数->lambda函数的名称

我的主题->SNS主题的名称

参考: