我有用 Python 编写的 SAM Lambda,我正在使用 Cloudfront 和 API Gateway 公开端点以触发 lambda,并且我有一个安全问题需要修复:
CloudFront distributions should have a default root object configured
所以我想向云端添加一个默认根对象,并且我需要一些帮助来配置它。
我尝试将默认根对象添加到 s3 存储桶,还尝试将其添加到项目中的根,但它对我不起作用。
这是我的模板:
AWSTemplateFormatVersion: "2010-09-09"
Transform:
- AWS::Serverless-2016-10-31
Parameters:
EnvironmentName:
Description: An environment name that will be prefixed to resource names e.g. dev,test for feature branch use dev1,dev2...
Type: String
Stage:
Type: String
Description: The name for a project pipeline stage, such as Staging or Prod, for which resources are provisioned and deployed.
Default: Stage
AllowedValues:
- Prod
- Stage
ApiKey:
Description: A unique key that you can distribute to clients such as CloudFront who are executing API Gateway
Type: String
Default: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
NoEcho: true
ServiceName:
Description: Service name
Type: String
Default: work-item-creation
LambdaFunc:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub "${EnvironmentName}-cw-${ServiceName}-lambda"
Description: Work Item Creation Lambda
Handler: app.lambda_handler
Runtime: python3.9
MemorySize: 128
Timeout: 30
CodeUri: lambda_func/
Role: !GetAtt
- LambdaExecutionRole
- Arn
Environment:
Variables:
PAT: "{{resolve:secretsmanager:secrets:SecretString:AZURE_PAT}}"
Events:
CreateWorkItem:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /create-work-item
Method: post
Stage: !Ref Stage
Auth:
ApiKeyRequired: true
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${EnvironmentName}-cw-${ServiceName}-lambda-execution-role"
Description: Creating service role in IAM for AWS Lambda
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Path: /service-role/
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
Policies:
- PolicyName: "s3-policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- s3:ListBucket
Resource:
- !Sub 'arn:aws:s3:::artifacts-us-east-1'
Tags:
- Key: Environment
Value: !Ref EnvironmentName
- Key: Service
Value: !Ref ServiceName
ApiGatewayKey:
Type: "AWS::ApiGateway::ApiKey"
DependsOn:
- LambdaFunc
Properties:
Name: !Sub "${EnvironmentName}-cw-${ServiceName}-api-gateway-key"
Description: Work Item Creation API Key
Enabled: true
StageKeys:
- RestApiId: !Ref ServerlessRestApi
StageName: !Ref Stage
Value: !Ref ApiKey
Tags:
- Key: Environment
Value: !Ref EnvironmentName
- Key: Service
Value: !Ref ServiceName
ApiKeyUsagePlan:
Type: "AWS::ApiGateway::UsagePlan"
DependsOn:
- LambdaFunc
- ApiGatewayKey
Properties:
UsagePlanName: !Sub "${EnvironmentName}-cw-${ServiceName}-api-key-usage-plan"
Description: Work Item Creation API Key usage plan
ApiStages:
- ApiId: !Ref ServerlessRestApi
Stage: !Ref Stage
Tags:
- Key: Environment
Value: !Ref EnvironmentName
- Key: Service
Value: !Ref ServiceName
LinkUsagePlanApiKey:
Type: "AWS::ApiGateway::UsagePlanKey"
Properties:
KeyId: !Ref ApiGatewayKey
KeyType: API_KEY
UsagePlanId: !Ref ApiKeyUsagePlan
CloudFront:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
IPV6Enabled: true
HttpVersion: http2
Comment: !Sub "Work Item Creation CloudFront, Environment: ${EnvironmentName}"
Aliases:
- !Join [
".",
[
!Ref ServiceName,
!Sub "{{resolve:ssm:/${EnvironmentName}/aws/route53/domain-name:1}}",
],
]
ViewerCertificate:
AcmCertificateArn: !Sub "{{resolve:ssm:/${EnvironmentName}/aws/acm/ssl-certificate-id:1}}"
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2021
Origins:
- Id: APIGOrigin
DomainName: !Sub ${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com
OriginPath: !Sub /${Stage}
CustomOriginConfig:
HTTPSPort: 443
OriginProtocolPolicy: https-only
OriginCustomHeaders:
- HeaderName: x-api-key
HeaderValue: !Ref ApiKey
- Id: S3Origin
DomainName: artifacts-us-east-1.s3.amazonaws.com
CustomOriginConfig:
HTTPSPort: 443
OriginProtocolPolicy: https-only
DefaultRootObject: default.html
DefaultCacheBehavior:
AllowedMethods:
["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
CachedMethods: ["GET", "HEAD", "OPTIONS"]
ForwardedValues:
Headers:
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Authorization
# - Host APIG needs to use SNI
QueryString: true
TargetOriginId: APIGOrigin
ViewerProtocolPolicy: https-only
Compress: true
DefaultTTL: 0
CustomErrorResponses:
- ErrorCachingMinTTL: 0
ErrorCode: 400
- ErrorCachingMinTTL: 1
ErrorCode: 403
- ErrorCachingMinTTL: 5
ErrorCode: 500
Tags:
- Key: Environment
Value: !Ref EnvironmentName
- Key: Service
Value: !Ref ServiceName
RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneId: !Sub "{{resolve:ssm:/${EnvironmentName}/aws/route53/internal-public-hosted-zone-id:1}}"
RecordSets:
- Name:
!Join [
".",
[
!Ref ServiceName,
!Sub "{{resolve:ssm:/${EnvironmentName}/aws/route53/domain-name:1}}",
],
]
Type: A
AliasTarget:
HostedZoneId: XXXXXXXXX # hosted zone ID of CloudFront
DNSName: !GetAtt CloudFront.DomainName
Outputs:
WorkItemCreationEndPoint:
Description: Work Item Creation Rest API endpoint
Value: !Ref RecordSetGroup
我需要在哪里以及如何配置默认根对象?我尝试在名为
artifact-us-east-1
的存储桶中设置 html,但它似乎不起作用。
另外,我尝试将其添加到根位置的项目中。
我已经想出来了,它比我想象的要容易。 您需要使用 api 网关响应定义从 lambda 返回 html。例如:
html_response = {
"statusCode": "404",
"body": {},
"headers": {
'Content-Type': 'text/html',
}
}
然后在 template.yaml 文件中添加另一个路径 /index.html 并启用默认根对象。 实际上,当设置默认根对象时,路由到根/aws默认路由到/index.html。