AWSTemplateFormatVersion: 2010-09-09 Parameters: WAFLogS3BucketPrefix: Type: String Default: central-waf-logs AWSOrgId: Type: String SourceRoleName: Type: String Default: KinesisFirehoseWafDeliveryRole S3LoggingBucketName: Type: String Default: Conditions: CreateLoggingBucket: !Equals [!Ref S3LoggingBucketName, "" ] UseInputLoggingBucket: !Not [!Equals [ !Ref S3LoggingBucketName, "" ] ] Resources: LoggingS3Bucket: Condition: CreateLoggingBucket Type: "AWS::S3::Bucket" DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: BucketName: !Sub "s3-access-logs-${AWS::AccountId}-${AWS::Region}" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 OwnershipControls: Rules: - ObjectOwnership: BucketOwnerPreferred LoggingS3BucketPolicy: Condition: CreateLoggingBucket Type: "AWS::S3::BucketPolicy" Properties: Bucket: !Ref LoggingS3Bucket PolicyDocument: Statement: - Effect: Allow Principal: Service: logging.s3.amazonaws.com Action: - s3:PutObject Resource: !Sub "${LoggingS3Bucket.Arn}/*" Condition: ArnLike: aws:SourceARN: !GetAtt WAFLogsS3Bucket.Arn StringEquals: aws:SourceAccount: !Ref "AWS::AccountId" - Effect: Deny Action: s3:* Resource: - !Sub "${LoggingS3Bucket.Arn}/*" - !GetAtt LoggingS3Bucket.Arn Condition: Bool: aws:SecureTransport: 'false' Principal: "*" WAFLogsS3Bucket: Type: "AWS::S3::Bucket" DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: BucketName: !Sub "${WAFLogS3BucketPrefix}-${AWS::AccountId}-${AWS::Region}" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: aws:kms KMSMasterKeyID: !Ref KMSKey LoggingConfiguration: DestinationBucketName: !If [ UseInputLoggingBucket, !Ref S3LoggingBucketName, !Ref "AWS::NoValue" ] DestinationBucketName: !If [ CreateLoggingBucket, !Ref LoggingS3Bucket, !Ref "AWS::NoValue" ] OwnershipControls: Rules: - ObjectOwnership: BucketOwnerPreferred WAFLogsS3BucketPolicy: Type: "AWS::S3::BucketPolicy" Properties: Bucket: !Ref WAFLogsS3Bucket PolicyDocument: Statement: - Effect: Allow Principal: AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root" Action: - s3:AbortMultipartUpload - s3:GetBucketLocation - s3:GetObject - s3:ListBucket - s3:ListBucketMultipartUploads - s3:PutObject - s3:PutObjectAcl Resource: - !Sub "${WAFLogsS3Bucket.Arn}/*" - !GetAtt WAFLogsS3Bucket.Arn Condition: ArnLike: aws:SourceArn: !Sub "arn:aws:iam::${AWS::AccountId}:role/${SourceRoleName}-*" - Effect: Deny Action: s3:* Resource: - !Sub "${WAFLogsS3Bucket.Arn}/*" - !GetAtt WAFLogsS3Bucket.Arn Condition: Bool: aws:SecureTransport: 'false' Principal: "*" KeyAlias: Type: AWS::KMS::Alias Properties: AliasName: alias/WAFLogs TargetKeyId: !Ref KMSKey KMSKey: Type: 'AWS::KMS::Key' UpdateReplacePolicy: Retain Properties: Description: WAF Log Key EnableKeyRotation: True KeyPolicy: Version: 2012-10-17 Id: key-default-1 Statement: - Sid: Enable IAM User Permissions Effect: Allow Principal: AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root' Action: 'kms:*' Resource: '*'