是否可以从 EventBridge 事件数据中提取 "instanceId",并将其用作目标值?

Is it possible to extract "instanceId" from EventBridge event data, and use it as Target Value?

我能够将 AutoScaling 事件设置为 EventBridge 中的规则以触发 SSM 命令,但我注意到,使用我选择的目标值,事件将传递到我所有活动的 EC2 实例。我的目标键是那些实例共享的标签,所以我的错误现在是有道理的。

我是 EventBridge 的新手,所以我想知道是否有 一种方法可以实际 定位 触发 AutoScaling 事件的实例(如提取事件数据中存在的“InstanceId”并将其用作我的新目标值)。我看到了 Input Transformer,但我认为它只是转换事件数据以传递给目标。

谢谢!

编辑 - 帮助 Lambda + SSM RunCommand 的 js 代码

我意识到我可以通过将 EventBridge 设置为调用 Lambda 函数而不是直接调用 SSM RunCommand 来实现此目的。谁能帮助 javaScript 代码在事件数据 (event.detail.EC2InstanceId) 中指定的 ec2 实例上调用 shell 命令?网上好像找不到相关的最新的基础模板,对js或者lambda也不够熟悉。任何帮助是极大的赞赏!谢谢

事件数据样本,根据aws docs

{
  "version": "0",
  "id": "12345678-1234-1234-1234-123456789012",
  "detail-type": "EC2 Instance Launch Successful",
  "source": "aws.autoscaling",
  "account": "123456789012",
  "time": "yyyy-mm-ddThh:mm:ssZ",
  "region": "us-west-2",
  "resources": [
      "auto-scaling-group-arn",
      "instance-arn"
  ],
  "detail": {
      "StatusCode": "InProgress",
      "Description": "Launching a new EC2 instance: i-12345678",
      "AutoScalingGroupName": "my-auto-scaling-group",
      "ActivityId": "87654321-4321-4321-4321-210987654321",
      "Details": {
          "Availability Zone": "us-west-2b",
          "Subnet ID": "subnet-12345678"
      },
      "RequestId": "12345678-1234-1234-1234-123456789012",
      "StatusMessage": "",
      "EndTime": "yyyy-mm-ddThh:mm:ssZ",
      "EC2InstanceId": "i-1234567890abcdef0",
      "StartTime": "yyyy-mm-ddThh:mm:ssZ",
      "Cause": "description-text"
  }
}

编辑 2 - 到目前为止我的 Lambda 代码

'use strict'

const ssm = new (require('aws-sdk/clients/ssm'))()

exports.handler = async (event) => {
    const instanceId = event.detail.EC2InstanceId
    var params = {
        DocumentName: "AWS-RunShellScript",
        InstanceIds: [ instanceId ],
        TimeoutSeconds: 30,
        Parameters: {
          commands: ["/path/to/my/ec2/script.sh"],
          workingDirectory: [],
          executionTimeout: ["15"]
        }
    };

    const data = await ssm.sendCommand(params).promise()
    const response = {
        statusCode: 200,
        body: "Run Command success",
    };
    return response;
}

是的,但是通过 Lambda

EventBridge -> Lambda(使用 SSM api) -> EC2

谢谢@Sándor Bakos 帮助我!!我的 JavaScript 由于某种原因最终无法正常工作,所以我最终只在评论中使用了部分 python 代码 linked

1。添加 ssm:SendCommand 权限:

在函数创建期间让 Lambda 创建基本角色后,我添加了一个内联策略以允许 Systems Manager 的 SendCommand。这需要访问您的 documents/*instances/*managed-instances/*

2。代码 - python 3.9

import boto3
import botocore
import time

def lambda_handler(event=None, context=None):
    try:
        client = boto3.client('ssm')
    
        instance_id = event['detail']['EC2InstanceId']
        command = '/path/to/my/script.sh'
        
        client.send_command(
            InstanceIds = [ instance_id ],
            DocumentName = 'AWS-RunShellScript',
            Parameters = {
                'commands': [ command ],
                'executionTimeout': [ '60' ]
            }
        )