AWS 的 SAM 模板 Api 与 S3 作为 AWS 服务的网关集成
SAM Template for AWS Api Gateway Integration with S3 as AWS Service
我正在编写 SAM 模板,我想创建一个 API 网关,路径如下:-
http:///userFlights/airlines/static/images/{airlineName}.
这应该能够从 S3 存储桶下载文件。 {airlineName} 的值可能类似于 IndiGo.jpg。
我可以手动创建它。尽管如此,问题是我无法为 SAM 模板找到合适的文档。我需要使用 SAM 自动化我的 API 网关。
数值如下:-
集成类型 - AWS 服务
AWS 区域 - eu-west-3
AWS 服务 - 简单存储服务(S3
HTTP 方法 - GET
路径覆盖- airlines/static/images/{airlineName}
您必须使用 DefinitionBody in your SAM template that defines the API configuration. Check out the S3 proxy example here 的 OpenAPI 定义。我用最简单和最小的 Swagger 定义构建了一个 API,并通过 SAM 部署。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template with a S3 integration
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
DefinitionBody: {
"swagger": "2.0",
"info": {
"version": "1.0"
},
"paths": {
"/airlines/static/images/{airlineName}": {
"get": {
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response"
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200"
}
},
"credentials": "arn:aws:iam::{account-id}:role/{role-name}",
"uri": "arn:aws:apigateway:{aws-region}:s3:path/{bucket-name}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "aws"
}
}
}
}
}
这是一个完整的工作版本,包括角色。部署后,在 AWS 控制台的 API Gateway goto stages 中,单击 GET,您将看到如下内容:https://12345hhhh.execute-api.eu-west-2.amazonaws.com/dev/{folder}/{item}
将 {folder} 和 {item} 替换为您的 S3 文件夹名称和 s3 项目(对象)(不带 {})它应该获取资源
openApi swagger 文档直接从 AWS 文档中获取(为简单起见略有删减),如果您需要具有附加功能的完整版本,请点击此处:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-as-s3-proxy-export-swagger-with-extensions.html
您可能想要锁定存储桶而不是“*”,并且此示例中不包含身份验证
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template for AWS API Gateway with S3 proxy AWS integration
Resources:
# roles
s3AWSIntegrationExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
RoleName: s3AWSIntegrationExecutionRole
# policies
apiGatewayExecutionPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ${AWS::StackName}-apiGatewayExecutionPolicy
Roles:
- Ref: s3AWSIntegrationExecutionRole
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:ListBucket
Resource: '*'
-
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogStreams
- logs:PutLogEvents
Resource: '*'
# API Gateway
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
Auth:
DefaultAuthorizer:
NONE
DefinitionBody: {
"swagger": "2.0",
"info": {
"version": "2016-10-13T23:04:43Z",
"title": "MyS3"
},
"basePath": "/S3",
"schemes": [
"https"
],
"paths": {
"/{folder}/{item}": {
"get": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "item",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "folder",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
},
"headers": {
"content-type": {
"type": "string"
},
"Content-Type": {
"type": "string"
}
}
},
"400": {
"description": "400 response"
},
"500": {
"description": "500 response"
}
},
"security": [
{
"sigv4": []
}
],
"x-amazon-apigateway-integration": {
"credentials": !GetAtt s3AWSIntegrationExecutionRole.Arn,
"responses": {
"4\d{2}": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.content-type": "integration.response.header.content-type",
"method.response.header.Content-Type": "integration.response.header.Content-Type"
}
},
"5\d{2}": {
"statusCode": "500"
}
},
"requestParameters": {
"integration.request.path.object": "method.request.path.item",
"integration.request.path.bucket": "method.request.path.folder"
},
"uri": "arn:aws:apigateway:eu-west-2:s3:path/{bucket}/{object}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "aws"
}
}
}
}
}
我正在编写 SAM 模板,我想创建一个 API 网关,路径如下:-
http:///userFlights/airlines/static/images/{airlineName}.
这应该能够从 S3 存储桶下载文件。 {airlineName} 的值可能类似于 IndiGo.jpg。
我可以手动创建它。尽管如此,问题是我无法为 SAM 模板找到合适的文档。我需要使用 SAM 自动化我的 API 网关。
数值如下:- 集成类型 - AWS 服务
AWS 区域 - eu-west-3
AWS 服务 - 简单存储服务(S3
HTTP 方法 - GET
路径覆盖- airlines/static/images/{airlineName}
您必须使用 DefinitionBody in your SAM template that defines the API configuration. Check out the S3 proxy example here 的 OpenAPI 定义。我用最简单和最小的 Swagger 定义构建了一个 API,并通过 SAM 部署。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template with a S3 integration
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
DefinitionBody: {
"swagger": "2.0",
"info": {
"version": "1.0"
},
"paths": {
"/airlines/static/images/{airlineName}": {
"get": {
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "200 response"
}
},
"x-amazon-apigateway-integration": {
"responses": {
"default": {
"statusCode": "200"
}
},
"credentials": "arn:aws:iam::{account-id}:role/{role-name}",
"uri": "arn:aws:apigateway:{aws-region}:s3:path/{bucket-name}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "aws"
}
}
}
}
}
这是一个完整的工作版本,包括角色。部署后,在 AWS 控制台的 API Gateway goto stages 中,单击 GET,您将看到如下内容:https://12345hhhh.execute-api.eu-west-2.amazonaws.com/dev/{folder}/{item}
将 {folder} 和 {item} 替换为您的 S3 文件夹名称和 s3 项目(对象)(不带 {})它应该获取资源
openApi swagger 文档直接从 AWS 文档中获取(为简单起见略有删减),如果您需要具有附加功能的完整版本,请点击此处:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-as-s3-proxy-export-swagger-with-extensions.html
您可能想要锁定存储桶而不是“*”,并且此示例中不包含身份验证
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS SAM template for AWS API Gateway with S3 proxy AWS integration
Resources:
# roles
s3AWSIntegrationExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service:
- apigateway.amazonaws.com
RoleName: s3AWSIntegrationExecutionRole
# policies
apiGatewayExecutionPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ${AWS::StackName}-apiGatewayExecutionPolicy
Roles:
- Ref: s3AWSIntegrationExecutionRole
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:ListBucket
Resource: '*'
-
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:DescribeLogStreams
- logs:PutLogEvents
Resource: '*'
# API Gateway
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
Auth:
DefaultAuthorizer:
NONE
DefinitionBody: {
"swagger": "2.0",
"info": {
"version": "2016-10-13T23:04:43Z",
"title": "MyS3"
},
"basePath": "/S3",
"schemes": [
"https"
],
"paths": {
"/{folder}/{item}": {
"get": {
"produces": [
"application/json"
],
"parameters": [
{
"name": "item",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "folder",
"in": "path",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "200 response",
"schema": {
"$ref": "#/definitions/Empty"
},
"headers": {
"content-type": {
"type": "string"
},
"Content-Type": {
"type": "string"
}
}
},
"400": {
"description": "400 response"
},
"500": {
"description": "500 response"
}
},
"security": [
{
"sigv4": []
}
],
"x-amazon-apigateway-integration": {
"credentials": !GetAtt s3AWSIntegrationExecutionRole.Arn,
"responses": {
"4\d{2}": {
"statusCode": "400"
},
"default": {
"statusCode": "200",
"responseParameters": {
"method.response.header.content-type": "integration.response.header.content-type",
"method.response.header.Content-Type": "integration.response.header.Content-Type"
}
},
"5\d{2}": {
"statusCode": "500"
}
},
"requestParameters": {
"integration.request.path.object": "method.request.path.item",
"integration.request.path.bucket": "method.request.path.folder"
},
"uri": "arn:aws:apigateway:eu-west-2:s3:path/{bucket}/{object}",
"passthroughBehavior": "when_no_match",
"httpMethod": "GET",
"type": "aws"
}
}
}
}
}