Я работаю над созданием приложения для заметок (api + веб-сайт) на одном пользовательском домене (например: mysub.domain.com). Я бы хотел, чтобы
- API-шлюз для всех моих Lambdas был доступен через путь / api /
- Остальные мои пути для домен обслуживает веб-сайт s3 stati c
В настоящее время
- Моя конечная точка лямбды работает на https://mysub.domain.com/api/notes (SSL уже работает и в консоли AWS)
- через BasePathMapping (см. Yaml ниже)
- уже добавил запись CNAME для моего субдомена, указывающую на конечная точка Cloudfront, созданная с помощью
$ sam deploy
Parameters:
DomainName:
Type: String
Default: mysub.nydomain.com
Resources:
####### DOMAIN - START ######
AppDomainName:
Type: AWS::ApiGateway::DomainName
Properties:
CertificateArn: arn:aws:acm:us-east-1:123456789012:certificate/1b23c456-7890-1b2b-a345-a6bb4a7fa89c
DomainName: !Ref DomainName
APIBasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
BasePath: 'api'
DomainName: !Ref AppDomainName
RestApiId: !Ref ServerlessRestApi
Stage: !Ref ServerlessRestApiProdStage
####### LAMBDA - START ######
NotesFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: notes/
Handler: app.lambdaHandler
Runtime: nodejs12.x
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref NotesTable
Events:
Notes:
Type: Api
Properties:
Path: /notes
Method: post
####### TABLES - START ######
NotesTable:
Type: AWS::DynamoDB::Table
Properties:
...
Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
NotesApi:
Description: "API Gateway endpoint URL for Prod stage for Notes function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/bt-device-history/"
NotesFunction:
Description: "Hello World Lambda Function ARN"
Value: "DeviceHistoryFunction"
NotesFunctionIamRole:
Description: "Implicit IAM Role created for NotesFunction"
Value: !GetAtt NotesFunctionRole.Arn
Когда я добавляю следующее (корзина s3 и распределение Cloudfront) в раздел Ресурсы моего шаблона SAM YAML
WebsiteBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref 'DomainName'
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: 404.html
DeletionPolicy: Retain
WebsiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref 'WebsiteBucket'
PolicyDocument:
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action: s3:GetObject
Resource: !Join ['', ['arn:aws:s3:::', !Ref 'WebsiteBucket', /*]]
WebsiteCloudfront:
Type: AWS::CloudFront::Distribution
DependsOn:
- WebsiteBucket
Properties:
DistributionConfig:
Comment: Cloudfront Distribution pointing to S3 bucket
Origins:
- DomainName: !Select [2, !Split ["/", !GetAtt WebsiteBucket.WebsiteURL]]
Id: S3Origin
CustomOriginConfig:
HTTPPort: '80'
HTTPSPort: '443'
OriginProtocolPolicy: http-only
Enabled: true
HttpVersion: 'http2'
DefaultRootObject: index.html
Aliases:
- !Ref 'DomainName'
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
Compress: true
TargetOriginId: S3Origin
ForwardedValues:
QueryString: true
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_All
ViewerCertificate:
AcmCertificateArn: arn:aws:acm:us-east-1:123456789012:certificate/1bf2c345--6789-0b1b-a123-a4bb5a6fa44c
SslSupportMethod: sni-only
WebsiteDNSName:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: !Join ['', [!Ref 'DomainName', .]]
RecordSets:
- Name: !Ref 'DomainName'
Type: A
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt [WebsiteCloudfront, DomainName]
Я получаю следующую ошибку в $sam deploy
AWS::CloudFront::Distribution WebsiteCloudfront One or more of the CNAMEs you provided are already associated with a
different resource. (Service: AmazonCloudFront; Status Code: 409; Error
Code: CNAMEAlreadyExists; Request ID:
e044dd29-4550-4f86-be44-22bbf7c34b16)
AWS::CloudFormation::Stack note-app The following resource(s) failed to create: [WebsiteCloudfront].
Как можно использовать один пользовательский домен для моего веб-сайта stati c и API, используя модель шаблона SAM?