我正在尝试编写一个 ec2 用户数据脚本,该脚本将从私有 s3 存储桶中提取文件。ec2 实例位于多个区域,我认为这消除了使用存储桶策略来限制对 VPC 的访问的可能性(这在我的原型中运行良好,但在第二个区域中出现故障)。
根据这里和其他地方的建议,似乎应该有效的方法是为 ec2 实例提供可以访问该 s3 存储桶的 IAM 角色。事实上,这对我来说似乎几乎有效。但是,只是在用户数据脚本运行时不起作用。
我的用户数据脚本有一个 while 循环,用于检查我尝试从 s3 下载的文件是否存在,并会在 5 分钟内不断重试。如果我在该窗口期间手动登录并在该 5 分钟窗口期间手动运行确切的 aws 命令,则用户数据脚本会按预期成功,但它永远不会自行成功。
apt install -y python-minimal
apt install -y unzip
wget "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip"
unzip awscli-bundle.zip
./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
mkdir -p /opt/myapp
cd /opt/myapp
n=0
while [ ! -f app.tar.gz ]; do
aws s3 cp --region us-west-1 "s3://bucket_name/app.tar.gz" app.tar.gz
n=$[$n+1]
[ $n -ge 60 ] && break
sleep 5
done
tar -zxf app.tar.gz
./bin/startapp
这是我的用户数据脚本的精简版本。如果我能够登录并手动运行相同的 aws 命令,我相信 IAM 角色一定是正确的;但我不明白还有什么可能出错。当从用户数据脚本运行 aws 命令时,错误为:致命错误:“调用 HeadObject 操作时发生错误 (403):禁止”
答案1
我最终解决了这个问题,但从我发布的内容中无法看出问题所在。我将用户数据脚本提炼成可以在此处发布的内容,但实际上要长得多。未发布的关键部分是,最终由此过程启动的应用程序需要访问亚马逊的 SES。当我发布这个问题时,这些环境变量位于脚本的顶部,S3 调用正在使用它们而不是分配的角色。一旦我将环境变量移动到应用程序启动之前(重要的是,在 S3 下载命令之后),用户数据脚本就会按预期工作。
值得注意的重要部分是,尽管 IAM 角色已分配给实例,并且 AWS CLI 将自动使用这些凭证,但这些凭证的使用方式与用户凭证一样,可用于调用 S3 等。这意味着设置其他凭证将绝对覆盖角色中的凭证。在深入研究这个问题之前,我的印象是,当请求在 AWS 内部时,S3 服务可能有一种方法可以验证调用者和调用者的角色。