【问题标题】:Using SNS as a Target to Trigger Lambda Function使用 SNS 作为目标触发 Lambda 函数
【发布时间】:2020-01-21 22:02:27
【问题描述】:

我的 Lambda 函数 100% 工作,我设置了 Cloudwatch 规则并将 Target 直接连接到 Lambda,一切正常。 我的经理希望我更改 Cloudwatch 中的 Target 并将其设置为 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

【问题讨论】:

    标签: amazon-ec2 aws-lambda amazon-sns amazon-cloudwatch


    【解决方案1】:

    假设权限缺失导致调用失败。

    您需要明确授予 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
    

    my-function -> lambda 函数的名称

    my-topic -> SNS 主题的名称

    参考:https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 2017-12-01
      • 2017-05-01
      • 2020-09-11
      • 2018-07-31
      相关资源
      最近更新 更多