# The name of your project service: **project** # Plugins for additional Serverless functionality plugins: - serverless-s3-deploy - serverless-plugin-scripts # Configuration for AWS provider: name: aws runtime: nodejs8.10 profile: serverless # Some future functionality requires us to use us-east-1 at this time region: us-east-1 # Custom configuration options custom: # This enables us to use the default stage definition, but override it from the command line stage: ${opt:stage, self:provider.stage} # This enables us to prepend the stage name for non-production environments domain: fulldomain: prod: ${self:custom.domain.domain} other: ${self:custom.stage}.${self:custom.domain.domain} domain: **domain** domainname: ${self:custom.domain.fulldomain.${self:custom.stage}, self:custom.domain.fulldomain.other} cacheControlMaxAgeHTMLByStage: # HTML Cache time for production environment prod: 3600 # HTML Cache time for other environments other: 0 cacheControlMaxAgeHTML: ${self:custom.domain.cacheControlMaxAgeHTMLByStage.${self:custom.stage}, self:custom.domain.cacheControlMaxAgeHTMLByStage.other} sslCertificateARN: **ARN** assets: targets: # Configuration for HTML files (overriding the default cache control age) - bucket: Ref: WebsiteS3Bucket files: - source: ./public/ headers: CacheControl: max-age=${self:custom.domain.cacheControlMaxAgeHTML} empty: true globs: - '**/*.html' # Configuration for all assets - bucket: Ref: WebsiteS3Bucket files: - source: ./public/ empty: true globs: - '**/*.js' - '**/*.css' - '**/*.jpg' - '**/*.png' - '**/*.gif' scripts: hooks: # Run these commands when creating the deployment artifacts package:createDeploymentArtifacts: > hexo clean && hexo generate # Run these commands after infrastructure changes have been completed deploy:finalize: > sls s3deploy -s ${self:custom.stage} # AWS Region to S3 website hostname mapping s3DNSName: us-east-2: s3-website.us-east-2.amazonaws.com us-east-1: s3-website-us-east-1.amazonaws.com us-west-1: s3-website-us-west-1.amazonaws.com us-west-2: s3-website-us-west-2.amazonaws.com ap-south-1: s3-website.ap-south-1.amazonaws.com ap-northeast-3: s3-website.ap-northeast-3.amazonaws.com ap-northeast-2: s3-website.ap-northeast-2.amazonaws.com ap-southeast-1: s3-website-ap-southeast-1.amazonaws.com ap-southeast-2: s3-website-ap-southeast-2.amazonaws.com ap-northeast-1: s3-website-ap-northeast-1.amazonaws.com ca-central-1: s3-website.ca-central-1.amazonaws.com eu-central-1: s3-website.eu-central-1.amazonaws.com eu-west-1: s3-website-eu-west-1.amazonaws.com eu-west-2: s3-website.eu-west-2.amazonaws.com eu-west-3: s3-website.eu-west-3.amazonaws.com eu-north-1: s3-website.eu-north-1.amazonaws.com sa-east-1: s3-website-sa-east-1.amazonaws.com # Define the resources we will need to host the site resources: Resources: # Set-up an S3 bucket to store the site WebsiteS3Bucket: Type: AWS::S3::Bucket Properties: AccessControl: PublicRead WebsiteConfiguration: IndexDocument: index.html ErrorDocument: error.html BucketName: ${self:custom.domain.domainname} # Set-up a policy on the bucket so it can be used as a website WebsiteBucketPolicy: Type: AWS::S3::BucketPolicy Properties: PolicyDocument: Id: Fn::Join: - "" - - ${self:service.name} - BucketPolicy Statement: - Sid: PublicReadForGetBucketObjects Effect: Allow Principal: '*' Action: 's3:GetObject' Resource: Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: WebsiteS3Bucket - /* Bucket: Ref: WebsiteS3Bucket # Configure CloudFront to get all content from S3 WebsiteCloudFrontDistribution: Type: 'AWS::CloudFront::Distribution' Properties: DistributionConfig: Aliases: - ${self:custom.domain.domainname} - www.${self:custom.domain.domainname} CustomErrorResponses: - ErrorCode: '404' ResponsePagePath: "/error.html" ResponseCode: '200' ErrorCachingMinTTL: '30' DefaultCacheBehavior: Compress: true ForwardedValues: QueryString: false Cookies: Forward: all SmoothStreaming: false TargetOriginId: defaultOrigin ViewerProtocolPolicy: redirect-to-https DefaultRootObject: index.html Enabled: true Origins: - DomainName: ${self:custom.domain.domainname}.${self:custom.s3DNSName.${self:provider.region}} Id: defaultOrigin CustomOriginConfig: HTTPPort: 80 HTTPSPort: 443 OriginProtocolPolicy: http-only PriceClass: PriceClass_All ViewerCertificate: AcmCertificateArn: ${self:custom.domain.sslCertificateARN} SslSupportMethod: sni-only # DNS Record for the domain WebsiteDNSRecord: Type: "AWS::Route53::RecordSet" Properties: AliasTarget: DNSName: Fn::GetAtt: - WebsiteCloudFrontDistribution - DomainName HostedZoneId: Z2FDTNDATAQYW2 HostedZoneName: ${self:custom.domain.domain}. Name: ${self:custom.domain.domainname} Type: 'A' # DNS Record for www.domain WebsiteWWWDNSRecord: Type: "AWS::Route53::RecordSet" Properties: AliasTarget: DNSName: Fn::GetAtt: - WebsiteCloudFrontDistribution - DomainName HostedZoneId: Z2FDTNDATAQYW2 HostedZoneName: ${self:custom.domain.domain}. Name: www.${self:custom.domain.domainname} Type: 'A' Outputs: WebsiteURL: Value: Fn::GetAtt: - WebsiteS3Bucket - WebsiteURL Description: URL for my website hosted on S3 S3BucketSecureURL: Value: Fn::Join: - '' - - 'https://' - Fn::GetAtt: - WebsiteS3Bucket - DomainName Description: Secure URL of S3 bucket to hold website content