运行在Fargate的容器化NodeJS应用无法生成可用的AWS预签名URL
问题根因
你本地运行正常是因为用了你本地配置的高权限AWS凭证,而ECS Fargate上运行出错的核心原因是你把S3操作权限配置到了错误的IAM角色上:
你当前的S3权限绑定的是ECS任务执行角色,这个角色仅用于ECS平台层面的操作,包括拉取ECR镜像、获取SSM参数/SecretsManager密钥、推送日志到CloudWatch等,容器内运行的应用程序无法继承这个角色的权限。
容器内应用调用AWS API时,使用的是专门的ECS任务角色(Task Role),你没有给这个角色配置S3权限,自然生成的预签名URL没有上传权限,返回403。
修复步骤
- 在CloudFormation模板中新增ECS任务角色,把S3相关权限配置到该角色下:
ECSTaskRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${ContainerName}-ECSTaskRole" Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: S3AccessPolicy PolicyDocument: Version: 2012-10-17 Statement: - Resource: - !Sub arn:aws:s3:::${VideoRepoName} - !Sub arn:aws:s3:::${VideoRepoName}/* Effect: Allow Action: - s3:*
- 调整你的ECS任务定义配置:保留原来的
ExecutionRoleArn字段为你现有的ECSTaskExecutionRole,新增TaskRoleArn字段,值为上面新增的ECSTaskRole的ARN。 - 若修改后仍有问题,可排查以下项:
- 检查S3桶的桶策略,确认没有拦截ECS任务角色的访问请求
- 检查预签名URL生成逻辑,确认生成时指定的头部参数(比如Content-Type、x-amz-acl等)和上传时带的参数完全匹配,参数不一致会触发403
- 确认NodeJS项目使用的AWS SDK版本的预签名API调用逻辑正确,V2和V3版本的参数传递规则存在差异
内容的提问来源于stack exchange,提问作者Anzhari
相关产品推荐
相关产品推荐

