lambda 创建事件事件的权限:PutEvents

Posted

技术标签:

【中文标题】lambda 创建事件事件的权限:PutEvents【英文标题】:Permissions for lambda to create event events:PutEvents 【发布时间】:2022-01-01 02:50:40 【问题描述】:

我想要一个 lambda 创建 EventBridge 事件,但在调用 lambda 时出现此错误:

User: arn:aws:sts::120293923901:assumed-role/MyApiOrdersPostFunct-I1QOYC7P1R0Z/MyApiOrdersPostFunct-SJtAeYoiaguW is not authorized to perform: events:PutEvents on resource: arn:aws:events:eu-north-1:120293923901:event-bus/MyApiEventBus because no identity-based policy allows the events:PutEvents action

我添加了政策,但没有更改。

这里是调用事件桥的 lambda。


import  APIGatewayProxyHandler, APIGatewayProxyResult  from 'aws-lambda';
import  EventBridgeClient, PutEventsCommand  from '@aws-sdk/client-eventbridge';

const eventBridge = new EventBridgeClient( region: 'eu-north-1' );

export const post: APIGatewayProxyHandler = async (): Promise<APIGatewayProxyResult> => 
    const event = new PutEventsCommand(
        Entries: [
            EventBusName: 'MyApiEventBus',
            Source: 'MyApiEventBus.OrderCreated',
            DetailType: 'OrderCreated',
            Detail: JSON.stringify( description: 'order has been created' ),
        ]
    );
        eventBridge.send(event);

    return 
        statusCode: 200,
        body: '',
    ;
;

这是 CDK 配置。有两个策略(attachInlinePolicy、addToRolePolicy),因为我都测试了。

import 
    RestApi,
    DomainName,
    BasePathMapping,
    LambdaIntegration,
    Model,
 from '@aws-cdk/aws-apigateway';
import  EventBus, Rule  from '@aws-cdk/aws-events';
import  NodejsFunction  from '@aws-cdk/aws-lambda-nodejs';
import  Policy, PolicyStatement  from '@aws-cdk/aws-iam';

const MyApi = new RestApi(this, `RestApi`, 
  restApiName: 'My API',
  description: 'The My API',
);

// Add an Event Bus
const bus = new EventBus(this, `EventBus`, 
  eventBusName: 'MyApiEventBus',
);

// Add API endpoint
const ordersResource = MyApi.root.addResource('orders');

const ordersPostFunction = new NodejsFunction(this, `OrdersPostFunction`, 
  entry: './lambda.ts',
  handler: 'post',
);

// Allow lambda to create events
ordersPostFunction.addToRolePolicy(
  new PolicyStatement(
    actions: ['events:PutEvents'],
    resources: [bus.eventBusArn],
  ),
);

ordersPostFunction.role?.attachInlinePolicy(
  new Policy(this, `OrdersPostEventBusPolicy`, 
    statements: [
      new PolicyStatement(
        actions: ['events:PutEvents'],
        resources: [bus.eventBusArn],
      ),
    ],
  ),
);

// Role to allow for creating event (not working?)
bus.grantPutEventsTo(ordersPostFunction);

Lambda 角色文档


  "sdkResponseMetadata": null,
  "sdkHttpMetadata": null,
  "partial": false,
  "permissionsBoundary": null,
  "policies": [
    
      "arn": null,
      "document": 
        "Version": "2012-10-17",
        "Statement": [
          
            "Action": "events:PutEvents",
            "Resource": "arn:aws:events:eu-west-1:120293923901:event-bus/MyApiEventBus",
            "Effect": "Allow"
          
        ]
      ,
      "id": null,
      "name": "MyApiOrdersPostEventBusPolicyACA51C2D",
      "type": "inline"
    ,
    
      "arn": null,
      "document": 
        "Version": "2012-10-17",
        "Statement": [
          
            "Action": "events:PutEvents",
            "Resource": "arn:aws:events:eu-west-1:120293923901:event-bus/MyApiEventBus",
            "Effect": "Allow"
          
        ]
      ,
      "id": null,
      "name": "MyApiOrdersPostFunctionServiceRoleDefaultPolicyE7615F17",
      "type": "inline"
    ,
  ]

【问题讨论】:

在控制台中检查 lambda 的策略 - 它是否包含正确的语句? 您能否检查附加到 lambda 角色的策略,它们是否真的包含错误消息中列出的事件总线的 arn? 编辑并添加了 lambda 策略,而 ARN 似乎为空。 @gshpychka aws lambda get-policy 不返回事件策略 【参考方案1】:

如生成的策略所示,您的事件总线位于 eu-west-1 区域,但您正尝试从 eu-north-1 访问它。更改地区,它会工作。

【讨论】:

【参考方案2】:

EventBridgeClientsend 方法是异步的。所以应该是:

await eventBridge.send(event);

否则您不会注意到由此引发的异常。

【讨论】:

以上是关于lambda 创建事件事件的权限:PutEvents的主要内容,如果未能解决你的问题,请参考以下文章

错误创建 Lambda 事件源映射 (): InvalidParameterValueException: Unrecognized event source

Aws Lambda 收集 CloudWatch 事件

Cloudformation 模板在 S3 事件上触发 Lambda

AWS lambda无服务器`schedule`事件创建错误:LimitExceededException

schedult 上的 aws 自定义事件以触发 lambda 使用 Terraform

创建在特定事件发生时调用的自定义 appsync 解析器或 lambda 函数