ECS 上的 Flask 应用程序从 s3 存储桶中提取图像

ECS 上的 Flask 应用程序从 s3 存储桶中提取图像

我有一个 Flask 应用程序,我想从 s3 存储桶中提取图像来显示。

我如何实现凭证部分?我的意思是:

我是否可以使用带有 aws 凭证的 boto3 从存储桶中提取图像?

我可以使用没有 aws 凭证的 boto3 并将角色附加到 ECS 吗?这样它就可以在没有凭证的情况下提取图像?

目前我想要实现的是将应用程序放入 CodePipeline 到 ECS,并且我想将图像更新到 s3 存储桶,因此 ECS 上的 flask 应用程序会在 s3 存储桶上显示新图像。

我对凭证等的最佳实践是什么感到困惑。

答案1

始终使用 IAM 角色并且绝不要在生产中使用任何显式访问/密钥。阅读更多关于EC2 实例角色这里,同样适用于ECS IAM 角色

在您的 ECS 案例中您应该:

  1. 创建 IAM 角色具有s3:GetObject来自 S3 存储桶的权限。
  2. 该 IAM 角色作为您的 ECS 任务TaskRole
  3. 如果您使用的是 ECS Fargate 而不是基于 EC2 的 ECS,那么您还需要ExecutionRole这实际上赋予了 Fargate 启动任务的权限。

CloudFormation 模板它会是这样的:

Parameters:
  S3BucketName:
    Type: String

Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      NetworkMode: awsvpc
      TaskRoleArn: !Ref TaskRole
      ExecutionRoleArn: !Ref ExecutionRole
      RequiresCompatibilities:
      - FARGATE
      Cpu: ...
      Memory: ...
      ContainerDefinitions:
      - ...


  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [ ecs-tasks.amazonaws.com ]
          Action:
          - sts:AssumeRole
      Path: /
      Policies:
      - PolicyName: TaskAccess
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Action:
            - s3:GetObject
            Effect: Allow
            Resource:
            - !Sub "arn:aws:s3:::${S3BucketName}/*"

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [ ecs-tasks.amazonaws.com ]
          Action: 
          - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

然而通常没有意义下载 公开图片从 S3 到你的 Flask web 应用程序。相反,民众在 S3 中并使用 直接从您的 HTML 中引用它们<img src="https://your-bucket-name.s3.amazonaws.com/whatever/image.jpg"/>

如果图像不公开你仍然不应该将它们下载到 Flask,而是创建预签名 URL提供对 S3 中文件的限时访问。再次直接链接到 S3 位置,而无需先将文件从 S3 下载到 Flask。

希望有帮助:)

相关内容