--- AWSTemplateFormatVersion: 2010-09-09 Description: Stack for Firehose DeliveryStream S3 Destination. Parameters: WAFLogS3Bucket: Type: String PrimaryRegion: Type: String Default: us-east-1 KMSAliasName: Type: String Default: WAFLogs Conditions: OnlyPrimaryRegion: !Equals [!Ref "AWS::Region",!Ref "PrimaryRegion"] Resources: WAFDeliveryLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: /aws/kinesisfirehose KmsKeyId: !GetAtt KMSKey.Arn RetentionInDays: 365 WAFDeliveryLogStream: DependsOn: WAFDeliveryLogGroup Type: AWS::Logs::LogStream Properties: LogGroupName: /aws/kinesisfirehose LogStreamName: !Ref WAFDeliverystream WAFDeliverystream: Type: AWS::KinesisFirehose::DeliveryStream Metadata: cfn_nag: rules_to_suppress: - id: W88 reason: "There is no Delivery Stream, these are from FMS, not applicable" Properties: DeliveryStreamName: !Sub "aws-waf-logs-delivery-${AWS::Region}" DeliveryStreamEncryptionConfigurationInput: KeyARN: !GetAtt KMSKey.Arn KeyType: CUSTOMER_MANAGED_CMK ExtendedS3DestinationConfiguration: BucketARN: !Sub "arn:aws:s3:::${WAFLogS3Bucket}" CloudWatchLoggingOptions: Enabled: true LogGroupName: /aws/kinesisfirehose LogStreamName: !Sub "aws-waf-logs-delivery-fms-${AWS::Region}" BufferingHints: IntervalInSeconds: 60 SizeInMBs: 50 CompressionFormat: UNCOMPRESSED EncryptionConfiguration: KMSEncryptionConfig: AWSKMSKeyARN: !Sub "arn:aws:kms:${PrimaryRegion}:${AWS::AccountId}:alias/${KMSAliasName}" Prefix: !Sub 'firehose/${AWS::Region}/' RoleARN: !GetAtt WAFdeliveryRole.Arn KMSKey: Type: AWS::KMS::Key Properties: Description: CloudWatch Log Encryption Key EnableKeyRotation: true PendingWindowInDays: 20 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: '*' - Sid: Allow administration of the key Effect: Allow Principal: Service: !Sub "logs.${AWS::Region}.amazonaws.com" Action: - kms:Encrypt - kms:Decrypt - kms:ReEncrypt* - kms:GenerateDataKey - kms:Describe* Resource: '*' Condition: ArnEquals: "kms:EncryptionContext:aws:logs:arn": !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/kinesisfirehose" WAFdeliveryRole: Type: AWS::IAM::Role Metadata: cfn_nag: rules_to_suppress: - id: W28 reason: "Role name to be referenced from other stacks, replace if ever required would not break things" Properties: RoleName: !Sub "KinesisFirehoseWafDeliveryRole-${AWS::Region}" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: "" Effect: Allow Principal: Service: firehose.amazonaws.com Action: "sts:AssumeRole" Condition: StringEquals: "sts:ExternalId": !Ref "AWS::AccountId" WAFdeliveryPolicy: Type: AWS::IAM::Policy Properties: PolicyName: !Sub 'firehose_delivery_policy-${AWS::Region}' PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "s3:AbortMultipartUpload" - "s3:GetBucketLocation" - "s3:GetObject" - "s3:ListBucket" - "s3:ListBucketMultipartUploads" - "s3:PutObject" Resource: - !Sub "arn:aws:s3:::${WAFLogS3Bucket}" - !Sub "arn:aws:s3:::${WAFLogS3Bucket}/*" - Effect: Allow Action: - "kinesis:DescribeStream" - "kinesis:GetShardIterator" - "kinesis:GetRecords" - "kinesis:ListShards" Resource: !GetAtt WAFDeliverystream.Arn - Effect: Allow Action: - "kms:Decrypt" - "kms:GenerateDataKey" Resource: - arn:aws:kms:region:account-id:key/key-id Condition: StringEquals: kms:ViaService: s3.region.amazonaws.com StringLike: kms:EncryptionContext:aws:s3:arn: arn:aws:s3:::bucket-name/prefix* - Effect: Allow Action: - "logs:PutLogEvents" Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/kinesisfirehose:log-stream:aws-waf-logs-delivery-${AWS::AccountId}-${AWS::Region}" - Effect: Allow Action: - "logs:PutLogEvents" Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/kinesisfirehose:log-stream:aws-waf-logs-delivery-${AWS::AccountId}-${AWS::Region}" - Effect: Allow Action: - "s3:AbortMultipartUpload" - "s3:GetBucketLocation" - "s3:GetObject" - "s3:ListBucket" - "s3:ListBucketMultipartUploads" - "s3:PutObject" - "s3:PutObjectAcl" - "s3:GetBucketLocation" - "s3:ListBucket" - "s3:ListBucketMultipartUploads" Resource: - !Sub "arn:aws:s3:::${WAFLogS3Bucket}" - !Sub "arn:aws:s3:::${WAFLogS3Bucket}/*" - Effect: Allow Action: - "kms:Encrypt" - "kms:Decrypt" - "kms:GenerateDataKey" - "kms:DescribeKey" Resource: - !Sub "arn:aws:kms:us-east-1:${AWS::AccountId}:key/*" Condition: ForAnyValue:StringEquals: kms:ResourceAliases: alias/WAFLogs - Effect: Allow Action: - "kms:Encrypt" - "kms:Decrypt" - "kms:GenerateDataKey" - "kms:DescribeKey" Resource: - !GetAtt KMSKey.Arn Roles: - !Ref WAFdeliveryRole