使用Boto3传入UserData启动EC2实例后无法从S3桶下载文件求助
问题根因及解决方案
核心问题1:Python进程模块加载时序问题
你当前的启动脚本是单Python脚本,执行顺序为先通过os.system安装boto3依赖,再执行import boto3。脚本作为UserData运行时,Python进程在启动阶段就加载了系统模块路径索引,刚通过pip安装的boto3不会被已经启动的Python进程识别,导致导入失败后续S3操作无法执行。你手动运行脚本时,UserData已经提前完成了boto3安装,新启动的Python进程可以正常识别已安装的模块,所以运行正常。
解决方法:
将启动脚本拆分为Shell前置依赖安装 + 独立Python脚本执行S3操作的结构,修改后的启动脚本如下:
#!/bin/bash # 前置依赖安装 sudo yum install -y python-pip sudo pip install boto3 sudo yum -y update sudo yum install -y httpd sudo service httpd start # 编写独立S3下载Python脚本 cat > /tmp/s3_download.py << EOF import boto3 import os access_id_key = '替换为你的AccessKey' secret_access_key = '替换为你的SecretKey' session_token_key = '替换为你的SessionToken' s3 = boto3.resource('s3', aws_access_key_id = access_id_key, aws_secret_access_key = secret_access_key, aws_session_token = session_token_key ) my_bucket = s3.Bucket('cs351-lab2') s3client = boto3.client('s3', aws_access_key_id = access_id_key, aws_secret_access_key = secret_access_key, aws_session_token = session_token_key ) # 切换到你需要的文件存放目录,比如网站根目录 os.chdir('/var/www/html') for file_object in my_bucket.objects.all(): print(file_object.key,type(file_object.key)) s3client.download_file('cs351-lab2',file_object.key,file_object.key) EOF # 执行Python脚本,同时输出日志方便排查 python /tmp/s3_download.py >> /var/log/s3_download.log 2>&1
问题2:拼写错误修正
你原脚本中创建S3 Resource的代码存在变量名拼写错误:aws_secret_access_key = secret_acces_key,变量secret_acces_key少了一个s,请修正为secret_access_key,避免参数传递错误。
问题3:工作目录问题
UserData脚本默认执行的工作目录是系统根目录/,你直接下载文件到当前路径的话,文件会存放在根目录下,不会出现在预期的/var/www/html目录中,下载前添加os.chdir('/var/www/html')切换到目标目录即可。
排查建议
如果修改后仍有问题,可以登录实例查看/var/log/s3_download.log日志,根据具体报错信息进一步定位问题。
内容的提问来源于stack exchange,提问作者Ankith Adudodla
相关产品推荐
相关产品推荐

