AWSTemplateFormatVersion: '2010-09-09' Description: 'S3 Bucket for FRED ML Reports and Visualizations' Parameters: BucketName: Type: String Default: fredmlv1 Description: Name of the S3 bucket for storing reports Resources: # S3 Bucket for Reports FredMLBucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName VersioningConfiguration: Status: Enabled PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true LifecycleConfiguration: Rules: - Id: DeleteOldReports Status: Enabled ExpirationInDays: 1095 # 3 years NoncurrentVersionExpirationInDays: 30 AbortIncompleteMultipartUpload: DaysAfterInitiation: 7 CorsConfiguration: CorsRules: - AllowedHeaders: ['*'] AllowedMethods: [GET, PUT, POST, DELETE] AllowedOrigins: ['*'] MaxAge: 3000 # Bucket Policy BucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: !Ref FredMLBucket PolicyDocument: Version: '2012-10-17' Statement: - Sid: DenyUnencryptedObjectUploads Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Sub '${FredMLBucket}/*' Condition: StringNotEquals: s3:x-amz-server-side-encryption: AES256 - Sid: DenyIncorrectEncryptionHeader Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Sub '${FredMLBucket}/*' Condition: StringNotEquals: s3:x-amz-server-side-encryption: AES256 - Sid: DenyUnencryptedObjectUploads Effect: Deny Principal: '*' Action: s3:PutObject Resource: !Sub '${FredMLBucket}/*' Condition: Null: s3:x-amz-server-side-encryption: 'true' # CloudWatch Log Group for S3 Access Logs S3AccessLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub '/aws/s3/${BucketName}' RetentionInDays: 30 Outputs: BucketName: Description: Name of the S3 bucket Value: !Ref FredMLBucket Export: Name: !Sub '${AWS::StackName}-BucketName' BucketArn: Description: ARN of the S3 bucket Value: !GetAtt FredMLBucket.Arn Export: Name: !Sub '${AWS::StackName}-BucketArn'