如何在Lambda触发EC2启动后执行实例内的Shell命令?
解决EC2实例启动后自动运行Shell命令的问题
你的现有Lambda代码仅能启动EC2实例,但没有实现启动后执行Shell命令的逻辑。以下是两种可靠的解决方案:
方案一:利用EC2用户数据(User Data)
EC2用户数据是实例启动时会执行的脚本,适合需要在实例启动阶段自动运行的命令。
注意事项
- 默认情况下,用户数据仅在实例首次启动时执行一次;如果需要在每次停止后启动时都执行,需修改实例内的
/etc/cloud/cloud.cfg配置,将preserve_hostname设为false,并确保cloud-init的runcmd或bootcmd配置正确。 - 若要给已有的实例添加/更新用户数据,可通过Lambda调用
modify_instance_attribute接口修改,再启动实例。
修改后的Lambda代码示例
import boto3 import base64 region = 'us-east-1' instances = ['i-079e6065f959e151a'] # 要执行的Shell命令 user_data = """#!/bin/bash echo "Hello from user data" >> /tmp/startup.log # 这里添加你的其他Shell命令 """ # 对用户数据进行base64编码(EC2用户数据要求格式) encoded_user_data = base64.b64encode(user_data.encode()).decode() def lambda_handler(event, context): ec2 = boto3.client('ec2', region_name=region) # 更新实例的用户数据 ec2.modify_instance_attribute( InstanceId=instances[0], Attribute='userData', Value=encoded_user_data ) # 启动实例 ec2.start_instances(InstanceIds=instances)
方案二:使用AWS SSM Run Command(更灵活)
通过Systems Manager的Run Command,可在实例启动并在线后,远程发送Shell命令执行,不受首次启动限制,适合动态执行命令的场景。
前置条件
- 给EC2实例附加包含
AmazonSSMManagedInstanceCore权限的IAM角色,确保实例能连接SSM服务。 - 实例需已安装SSM代理(Amazon Linux 2/Amazon Linux默认预装,其他系统需手动安装)。
- Lambda执行角色需添加
ssm:SendCommand、ec2:DescribeInstances、ssm:DescribeInstanceInformation权限。
修改后的Lambda代码示例
import boto3 import time region = 'us-east-1' instances = ['i-079e6065f959e151a'] ssm = boto3.client('ssm', region_name=region) ec2 = boto3.client('ec2', region_name=region) def lambda_handler(event, context): # 启动EC2实例 ec2.start_instances(InstanceIds=instances) # 等待实例进入running状态且SSM在线 while True: instance_status = ec2.describe_instances(InstanceIds=instances)['Reservations'][0]['Instances'][0]['State']['Name'] # 检查SSM是否能识别实例 ssm_response = ssm.describe_instance_information( Filters=[{'Key': 'InstanceIds', 'Values': instances}] ) if instance_status == 'running' and len(ssm_response['InstanceInformationList']) > 0: break time.sleep(10) # 发送Shell命令 response = ssm.send_command( InstanceIds=instances, DocumentName='AWS-RunShellScript', Parameters={'commands': [ 'echo "Command executed via SSM" >> /tmp/ssm.log', # 添加你的其他Shell命令 ]} ) print(f"Command sent successfully, Command ID: {response['Command']['CommandId']}")
验证命令执行结果
可通过SSM控制台的“Run Command”页面查看命令执行状态,或在实例内查看指定日志文件确认命令是否运行。
内容的提问来源于stack exchange,提问作者Natasha Sakai
相关产品推荐
相关产品推荐

