AWSTemplateFormatVersion: 2010-09-09 Description: 'This template creates a Kinesis Firehose Delivery Stream for Lambda@Edge logs and a test distribution with a Lambda@Edge function' Parameters: KinesisBufferIntervalSeconds: Default: 60 Description: The frequency of data delivery to Amazon S3 is determined by the Amazon S3 Buffer size and Buffer interval value that you configured for your delivery stream. Kinesis Data Firehose buffers incoming data before delivering it to Amazon S3. You can configure the values for Amazon S3 Buffer size (1-128 MB) or Buffer interval (60 – 900 seconds), and the condition satisfied first triggers data delivery to Amazon S3 Type: Number MinValue: 60 MaxValue: 900 KinesisBufferSizeMB: Default: 3 Description: The frequency of data delivery to Amazon S3 is determined by the Amazon S3 Buffer size and Buffer interval value that you configured for your delivery stream. Kinesis Data Firehose buffers incoming data before delivering it to Amazon S3. You can configure the values for Amazon S3 Buffer size (1-128 MB) or Buffer interval (60 – 900 seconds), and the condition satisfied first triggers data delivery to Amazon S3 Type: Number MinValue: 1 MaxValue: 128 CreateTestDistribution: Description: Create a test distribution with Lambda@Edge viewer request function that you can use to test log aggregation. PLEASE NOTE - You must be in US-EAST-1 to deploy this resource. Default: 'Yes' Type: String AllowedValues: - 'Yes' - 'No' Conditions: IsIAD: !Equals [ !Ref 'AWS::Region', 'us-east-1' ] CreateTestResources: !And - !Equals [ !Ref CreateTestDistribution, 'Yes' ] - !Condition IsIAD Resources: s3Bucket: Type: AWS::S3::Bucket deliveryRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: firehose.amazonaws.com Action: 'sts:AssumeRole' Policies: - PolicyName: !Join - '' - - 'kinesis_delivery_' - !Ref AWS::StackName PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 's3:AbortMultipartUpload' - 's3:GetBucketLocation' - 's3:GetObject' - 's3:ListBucket' - 's3:ListBucketMultipartUploads' - 's3:PutObject' Resource: - !Join - '' - - 'arn:aws:s3:::' - !Ref s3Bucket - !Join - '' - - 'arn:aws:s3:::' - !Ref s3Bucket - '*' firehoseDeliveryStream: Type: AWS::KinesisFirehose::DeliveryStream Properties: DeliveryStreamName: !Join - '' - - 'cf-lambda-edge-logs-' - !Ref AWS::StackName ExtendedS3DestinationConfiguration: BucketARN: !Join - '' - - 'arn:aws:s3:::' - !Ref s3Bucket BufferingHints: IntervalInSeconds: !Ref KinesisBufferIntervalSeconds SizeInMBs: !Ref KinesisBufferSizeMB CompressionFormat: UNCOMPRESSED Prefix: firehose/ RoleARN: !GetAtt deliveryRole.Arn cloudwatchRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - logs.us-east-1.amazonaws.com - logs.us-west-2.amazonaws.com - logs.us-east-2.amazonaws.com - logs.eu-central-1.amazonaws.com - logs.eu-west-2.amazonaws.com - logs.ap-south-1.amazonaws.com - logs.ap-southeast-1.amazonaws.com - logs.ap-southeast-2.amazonaws.com - logs.ap-northeast-1.amazonaws.com - logs.ap-northeast-2.amazonaws.com - logs.sa-east-1.amazonaws.com Action: 'sts:AssumeRole' cloudwatchPolicy: Type: AWS::IAM::Policy Properties: PolicyName: !Join - '' - - 'cloudwatch_sub_filter_' - !Ref AWS::StackName PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'firehose:*' Resource: !GetAtt firehoseDeliveryStream.Arn - Effect: Allow Action: 'iam:PassRole' Resource: !GetAtt cloudwatchRole.Arn Roles: - Ref: cloudwatchRole testDistribution: Type: AWS::CloudFront::Distribution Condition: CreateTestResources Properties: DistributionConfig: Comment: 'Lambda@Edge log aggregation test distribution' DefaultCacheBehavior: Compress: true ForwardedValues: QueryString: false TargetOriginId: the-origin ViewerProtocolPolicy: redirect-to-https LambdaFunctionAssociations: - EventType: viewer-request LambdaFunctionARN: !Ref lambdaEdgeFunctionVersion DefaultRootObject: index.html Enabled: true HttpVersion: http2 Origins: - DomainName: 'aws.amazon.com' Id: the-origin CustomOriginConfig: OriginProtocolPolicy: 'https-only' lambdaEdgeFunction: Type: AWS::Lambda::Function Condition: CreateTestResources Properties: FunctionName: !Join - '' - - 'GenerateViewerResponse-' - !Ref AWS::StackName Description: > Lambda function to generate a response displaying request headers. Code: ZipFile: !Sub | exports.handler= (event, context, callback) => { const requestHeaders = event.Records[0].cf.request.headers; console.log("Request Processed In:" + process.env.AWS_REGION); var str = ``; for (var key in requestHeaders) { if (requestHeaders.hasOwnProperty(key)) { str += ""; } } str+= "

Header

Value

"+key + "" + requestHeaders[key][0].value + "
"; var content = `

Lambda@Edge Lab

Lamdba@Edge Log Aggregator Blog
Response sent by Lambda@Edge in ` + process.env.AWS_REGION + `
` + str + `
`; const response = { status: '200', statusDescription: 'OK', headers: { 'cache-control': [{ key: 'Cache-Control', value: 'max-age=100' }], 'content-type': [{ key: 'Content-Type', value: 'text/html' }], 'content-encoding': [{ key: 'Content-Encoding', value: 'UTF-8' }], }, body: content, }; callback(null, response); }; Handler: index.handler Role: Fn::GetAtt: - "lambdaExecutionRole" - "Arn" Runtime: nodejs8.10 lambdaEdgeFunctionVersion: Type: AWS::Lambda::Version Condition: CreateTestResources Properties: FunctionName: !Ref lambdaEdgeFunction Description: !Sub "Version 1" lambdaExecutionRole: Type: AWS::IAM::Role Condition: CreateTestResources Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - edgelambda.amazonaws.com - lambda.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: !Join - '' - - 'lambda_basic_execution_' - !Ref AWS::StackName PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: 'arn:aws:logs:*:*:*' Outputs: S3BucketDomainName: Description: 'S3 bucket domain name' Value: !GetAtt s3Bucket.DomainName KinesisFireHoseDeliveryStreamArn: Description: 'Kinesis Delivery Stream' Value: !GetAtt firehoseDeliveryStream.Arn CloudWatchRole: Description: 'CloudWatch role for subscription filters' Value: !GetAtt cloudwatchRole.Arn CloudFrontTestDistribution: Condition: CreateTestResources Description: 'CloudFront Distribution for testing' Value: !GetAtt testDistribution.DomainName LambdaEdgeFunction: Condition: CreateTestResources Description: 'Lambda@Edge viewer request function' Value: !GetAtt lambdaEdgeFunction.Arn