在 AWS 中从 Lambda 启动 shell 脚本

Posted

技术标签:

【中文标题】在 AWS 中从 Lambda 启动 shell 脚本【英文标题】:Launch a shell script from Lambda in AWS 【发布时间】:2016-05-10 01:37:13 【问题描述】:

如果我有一个位于 EC2 实例中的 bash 脚本,是否有 lambda 可以触发它的方法?

lambda 的触发器来自 RDS。因此 mysql 中的表被更新并且该表中的特定列被更新为“就绪”,Lambda 必须以“就绪”状态提取该行的 ID 并将该 ID 发送到 bash 脚本。

【问题讨论】:

我添加了我对解决方案的看法。如果您更新了有关您的 RDS 实例类型的更多信息,我可以使代码示例更加详细 【参考方案1】:

让我们假设一些事情。首先,您知道如何使用 sns 设置“触发器”(请参阅​​here)以及如何将 lambda 脚本挂在所述触发器上。其次,您对 python 有一点了解(Lambda 的语法产品有 Node、Java 和 Python),因为这个示例将使用 Python。此外,我不会介绍如何使用 mysql 查询数据库。您没有提及您的 RDS 实例是 MySQL、Postgress 还是其他实例。最后,您需要了解如何通过 IAM 角色和策略允许跨 AWS 资源的权限。

以下脚本将至少概述向您的实例触发脚本的方法(您必须弄清楚如何查询相关信息或将该信息传递到 SNS 主题),然后在您指定的实例。

import boto3
def lambda_handler(event, context):
     #query RDS to get ID or get from SNS topic
     id = *queryresult*
     command = 'sh /path/to/scriptoninstance' + id
     ssm = boto3.client('ssm')
     ssmresponse = ssm.send_command(InstanceIds=['i-instanceid'], DocumentName='AWS-RunShellScript', Parameters=  'commands': [command]  ) 

我可能会为 RDS 行设置两个标志。一个说“准备好”,一个说“已确定”。因此 SNS 主题触发 lambda 脚本,lambda 脚本查找 'ready' = true 和 'identified' = false 的行,将 'identified' 更改为 true(以确保其他可能同时运行的 lambda 脚本不会运行拿起它),然后触发脚本。如果脚本未成功运行,请将 'identified' 改回 false 以确保您的数据保持有效。

【讨论】:

【参考方案2】:

使用Amazon EC2 Simple Systems Manager,您可以配置 SSM 文档以在实例上运行脚本,并向该脚本传递参数。 Lambda 实例需要运行 SSM 发送命令,通过实例 ID 定位实例。

示例 SSM 文档: run_my_example.json:


  "schemaVersion": "1.2",
  "description": "Run shell script to launch.",
  "parameters": 
         "taskId":
            "type":"String",
            "default":"",
            "description":"(Required) the Id of the task to run",
            "maxChars":16
        
  ,
  "runtimeConfig": 
    "aws:runShellScript": 
      "properties": [
        
          "id": "0.aws:runShellScript",
          "runCommand": ["run_my_example.sh"]
        
      ]
    
  

上面的SSM文档接受taskId作为参数。

将此文档保存为 JSON 文件,并使用 AWS CLI 调用 create-document:

aws ssm create-document --content file:///tmp/run_my_example.json --name  "run_my_example"

您可以致电describe-document查看SSM文档的描述:

aws ssm describe-document --name "run_my_example"

您可以指定taskId参数并使用带有send-command的文档名称运行命令

aws ssm send-command --instance-ids i-12345678 --document-name "run_my_example" --parameters --taskid=123456

注意事项

实例必须运行latest version of the SSM agent。

您需要在 Lambda 脚本中有一些逻辑来识别服务器 EG 的实例 ID,以查找特定标记实例的实例 ID。

【讨论】:

【参考方案3】:

需要考虑的事情很少,其中之一是:

安全。截至今天,lambda 无法在 VPC 中运行。这意味着您的 EC2 必须拥有一个完全开放的入站安全组。

我建议看一下消息队列(比如 SQS )。这会解决很多头痛的问题。

这就是它可能的工作方式:

拉姆达。获取消息;发送到 SQS EC2。获得触发 N 分钟的 Cron 作业。从sqs拉消息;处理消息。

【讨论】:

【参考方案4】:

我认为您可以使用新的EC2 Run Command 功能来完成此操作。

【讨论】:

以上是关于在 AWS 中从 Lambda 启动 shell 脚本的主要内容,如果未能解决你的问题,请参考以下文章

在 aws lambda 中在 python 中从 ANSI 转换为 UTF-8

在不同账户的 Lambda 中从 AWS Athena 查询 S3 文件时访问被拒绝

在 AWS Lambda 函数中从 S3 获取对象并发送到 Api Gateway

使用特定选项或环境变量在 AWS lambda 中启动 NodeJS 运行时

使用特定选项或环境变量在AWS lambda中启动NodeJS运行时

在ubuntu / Linux中从Shell脚本(启动)运行GamingAnywhere