AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: Amazon IVS Clip Manisfest Globals: Function: Runtime: nodejs16.x Timeout: 40 MemorySize: 128 Environment: Variables: STORAGE_IVSRECORDINGS_BUCKETNAME: !Ref IVSRecordingBucket CLOUDFRONT_DOMAIN_NAME: !Sub "https://${CloudfrontDistribution.DomainName}" ACCOUNT_ID: !Ref AWS::AccountId Resources: # Post create clips API ClipManifestLambda: Type: 'AWS::Serverless::Function' Properties: Handler: index.handler CodeUri: lambdas/clipmanifest Policies: - S3CrudPolicy: BucketName: !Ref IVSRecordingBucket Events: Api1: Type: Api Properties: Path: /clipmanifest Method: POST # Get recordings API GetRecordingsLambda: Type: 'AWS::Serverless::Function' Properties: Handler: index.handler CodeUri: lambdas/getrecordings Policies: - S3ReadPolicy: BucketName: !Ref IVSRecordingBucket Events: Api1: Type: Api Properties: Path: /getrecordings Method: GET # Get clips API GetClipsLambda: Type: 'AWS::Serverless::Function' Properties: Handler: index.handler CodeUri: lambdas/getclips Policies: - S3ReadPolicy: BucketName: !Ref IVSRecordingBucket Events: Api1: Type: Api Properties: Path: /getclips Method: GET ## CloudFront Block CloudFrontOriginAccessIdentity: Type: 'AWS::CloudFront::CloudFrontOriginAccessIdentity' Properties: CloudFrontOriginAccessIdentityConfig: Comment: 'Serverless website OA' CloudfrontDistribution: Type: "AWS::CloudFront::Distribution" Properties: DistributionConfig: Comment: "Cloudfront distribution for IVS Manifest Clip" DefaultRootObject: "index.html" Enabled: true HttpVersion: http2 # List of origins that Cloudfront will connect to Origins: - Id: s3-website DomainName: !GetAtt IVSRecordingBucket.DomainName S3OriginConfig: # Restricting Bucket access through an origin access identity OriginAccessIdentity: Fn::Sub: 'origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}' # To connect the CDN to the origins you need to specify behaviours DefaultCacheBehavior: # Compress resources automatically ( gzip ) Compress: 'true' AllowedMethods: - HEAD - GET - OPTIONS ForwardedValues: QueryString: false Headers: ["Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"] TargetOriginId: s3-website ViewerProtocolPolicy : redirect-to-https ## Create S3 Bucket IVSRecordingBucket: Type: AWS::S3::Bucket Properties: # Change bucket name if you want to have a custom name BucketName: !Sub "my-new-ivs-recording-bucket-${AWS::AccountId}" ## add account is !GetAtt AWS::AccountId CorsConfiguration: CorsRules : [ { "AllowedMethods": [ "GET", "HEAD" ], "AllowedOrigins": [ "*" ], "AllowedHeaders": [ "*" ], "MaxAge" : 3000 } ] # S3 Bucket Policy IVSRecordingBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref IVSRecordingBucket PolicyDocument: # Restricting access to cloudfront only. Statement: - Effect: Allow Action: 's3:GetObject' Resource: - !Sub "arn:aws:s3:::${IVSRecordingBucket}/*" Principal: AWS: !Sub "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}" Outputs: ApiURLGetRecordings: Description: "API endpoint get recordings available" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/getrecordings/" ApiURLGetClips: Description: "API endpoint get clips available" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/getclips/" ApiURLCreateClip: Description: "API endpoint post create clips" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/clipmanifest/" RecordConfigurationBucket: Description: "Recoding Bucket Name" Value: !Ref IVSRecordingBucket CloudfrontDistribution: Description: "Amazon CloudFront Domain Name" Value: !Sub "https://${CloudfrontDistribution.DomainName}"