【问题标题】:How to trigger AWS Events Rule only when a specific file (key) gets written to an S3 Bucket如何仅在将特定文件(密钥)写入 S3 存储桶时触发 AWS 事件规则
【发布时间】:2020-02-27 02:26:21
【问题描述】:

我正在尝试创建一个 AWS 事件(在 CloudWatch 或 EventBridge 中),以在将特定文件放入 S3 存储桶时触发 AWS Step Function 的运行。我的规则事件模式如下所示:

{
  "source": [
    "aws.s3"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "s3.amazonaws.com"
    ],
    "eventName": [
      "PutObject"
    ],
    "requestParameters": {
      "bucketName": [
        "bucketname"
      ],
      "key": [
        "date={{TODAYS DATE}}/_SUCCESS"
      ]
    }
  }
}

理想情况下,我希望key 元素指向一个路径,其中TODAYS DATE 表示当前日期,_SUCCCESS 是一个空文件,一旦成功完成,我的工作就会打印到目录中(例如,如果今天是 2019 年 10 月 31 日,要检查的完整存储桶路径将是 bucketname/date=20191031/_SUCCESS)。最终目标是让 Event Rule 触发一个 Step Function,该函数控制许多其他日常作业,这些作业只有在将 _SUCCESS 文件输出到存储桶的第一个作业成功完成后才能运行。

最好我希望使用当天的当前日期对_SUCCESS 文件进行密钥检查。但是,如果没有好的方法来处理日期,如果有办法在将新目录放入存储桶时触发规则一次(例如,当目录date=XXXXXX 是创建)。每次将任何新文件放入存储桶时,我都无法激活触发器,因为初始作业将在 date=XXXXXX 目录中创建许多输出文件,这些文件用作以下作业的输入。

能够通过 AWS CloudFormation 创建此规则也将非常有帮助,因此如果 CloudFormation 有任何方法来处理这些问题,那就太好了。

提前感谢您的帮助,非常感谢。

【问题讨论】:

    标签: amazon-web-services amazon-s3 amazon-cloudformation amazon-cloudwatch aws-step-functions


    【解决方案1】:

    我不确定我是否理解您在这里想要实现的目标,但是您为什么不将 lambda 函数订阅到存储文件的存储桶(订阅它放置事件),做任何您想要的检查要在该 lambda 函数内部以编程方式执行,并且如果满足所有条件,只需从 lambda 函数中调用提到的 step 函数。

    如果不满足任何条件,则根本不启动 step 功能。

    您可以通过以下方式将 lambda 函数订阅到 S3 put 事件(通过 Web 控制台)。

    1. 转到 S3
    2. 挑你的桶
    3. 转至Properties tab
    4. 选择Events
    5. 查看PUT事件
    6. Send to 下,选择Lambda Function
    7. 选择现有的 lambda 函数(您需要创建该 lambda 函数)

    如何从 lambda 函数中访问事件的存储桶名称、对象键和时间戳等属性。 (使用 Python)

    def handler_name(event, context): 
        // get bucket name
        print(event['Records'][0]['s3']['bucket']['name'])
    
        // get object key
        print(event['Records'][0]['s3']['object']['key'])
    
        // get event timestamp
        print(event['Records'][0]['eventTime'])
    
        return 0
    

    这里有完整的event对象(即S3事件对象)供参考。

    {
      "Records": [
        {
          "eventVersion": "2.1",
          "eventSource": "aws:s3",
          "awsRegion": "us-east-2",
          "eventTime": "2019-09-03T19:37:27.192Z",
          "eventName": "ObjectCreated:Put",
          "userIdentity": {
            "principalId": "AWS:AIDAINPONIXQXHT3IKHL2"
          },
          "requestParameters": {
            "sourceIPAddress": "205.255.255.255"
          },
          "responseElements": {
            "x-amz-request-id": "D82B88E5F771F645",
            "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo="
          },
          "s3": {
            "s3SchemaVersion": "1.0",
            "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
            "bucket": {
              "name": "lambda-artifacts-deafc19498e3f2df",
              "ownerIdentity": {
                "principalId": "A3I5XTEXAMAI3E"
              },
              "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df"
            },
            "object": {
              "key": "b21b84d653bb07b05b1e6b33684dc11b",
              "size": 1305107,
              "eTag": "b21b84d653bb07b05b1e6b33684dc11b",
              "sequencer": "0C0F6F405D6ED209E1"
            }
          }
        }
    
      ]
    }
    

    如何在 Lambda 函数中执行 Step Function(使用 Python + Boto3)

    import boto3
    
    sfn_client = boto3.client('stepfunctions')
    
    def handler_name(event, context): 
    
        response = sfn_client.start_execution(
            stateMachineArn='string',
            name='string',
            input='string'
        )
    
        return 0
    

    其中stateMachineArn 是要执行的状态机的 Amazon 资源名称 (ARN),name(可选)是执行名称,input 是包含执行的 JSON 输入数据的字符串。

    【讨论】:

    • 将 lambda 函数订阅到 put 事件是什么意思?有没有办法使用类似于 CloudWatch 事件的 lambda 函数,您可以让它不断观察 S3 存储桶中的某个位置,等待在满足适当条件时触发事件?另外,您将如何编写 lambda 函数来监视 put 事件或触发 step 函数?抱歉,我对此有点陌生。
    • 是的,这一切皆有可能。检查更新的答案。
    • 非常感谢您的帮助!最后一个问题,您知道是否可以像使用 CloudFormation 那样设置事件/创建与存储桶相关联的 lambda 函数?我需要让这个过程在多个区域的多个存储桶上运行,让 CloudFormation 模板处理这个过程会更干净、更易于管理,而不必在一堆中进行大量手动编辑每次我需要更新的地方。
    • 是的,您可以通过 CF 做到这一点。 S3 存储桶有一个属性 NotificationConfiguration,您可以在该属性下指定 LambdaConfiguration - 事件类型 (PUT) 和要执行的 Lambda 函数。
    • 我无法让 AWS CloudFormation 接受我的模板来设置此触发器(请参阅我最近对主要问题的编辑)。我在Type: 行上不断收到Unrecognized resource types 错误,你知道这一行需要做什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多