AWSTemplateFormatVersion: 2010-09-09 Description: KMS and S3 for the secondary/backup region Metadata: {} Parameters: pReplicaDestRegionKmsStackName: Type: String Default: replication-region-kms pFrameworkPrefix: Type: String #AWS::SSM::Parameter::Value #Default: '/account/framework-prefix' Description: Framework prefix from SSM pOrganizationName: Type: String #::SSM::Parameter::Value #Default: '/account/organization-name' Description: Organization name from SSM pEnvironment: Type: String #AWS::SSM::Parameter::Value #Default: '/account/environment' Description: Environment from SSM pLogsRetentionInDays: Type: String pReplicaDestRegion: Type: String ########################################################## # Resources ########################################################## Resources: ########################################################## # Log # S3 Bucket policy ###### rLogBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: rLogS3Bucket Properties: Bucket: !Ref rLogS3Bucket PolicyDocument: Statement: - Action: - 's3:*' Sid: 'AllowSSLRequestsOnly' Effect: Deny Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rLogS3Bucket - /* - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rLogS3Bucket Principal: "*" Condition: Bool: 'aws:SecureTransport': "false" rLogS3Bucket: Type: 'AWS::S3::Bucket' DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: BucketName: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-log" AccessControl: "LogDeliveryWrite" PublicAccessBlockConfiguration: BlockPublicAcls: true IgnorePublicAcls: true BlockPublicPolicy: true RestrictPublicBuckets: true BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: 'AES256' # S3 Access log buckets only support AES256 encryption IntelligentTieringConfigurations: - Id: IntelligentTieringRule Status: Enabled Tierings: - AccessTier: ARCHIVE_ACCESS Days: 90 - AccessTier: DEEP_ARCHIVE_ACCESS Days: 180 VersioningConfiguration: Status: Enabled ########################################################### # Raw Replica # S3 Bucket policy ###### rRawBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: rRawReplicaS3Bucket Properties: Bucket: !Ref rRawReplicaS3Bucket PolicyDocument: Statement: - Action: - 's3:*' Sid: 'AllowSSLRequestsOnly' Effect: Deny Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rRawReplicaS3Bucket - /* - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rRawReplicaS3Bucket Principal: "*" Condition: Bool: 'aws:SecureTransport': "false" - Action: - 's3:PutObject' Sid: 'RequireKMSEncryption' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rRawReplicaS3Bucket - /* Condition: StringNotLikeIfExists: s3:x-amz-server-side-encryption-aws-kms-key-id: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyArn" - Action: - 's3:PutObject' Sid: 'DenySSE-S3' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rRawReplicaS3Bucket - /* Condition: StringEquals: s3:x-amz-server-side-encryption: "AES256" rRawReplicaS3Bucket: Type: 'AWS::S3::Bucket' DependsOn: rLogS3Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: BucketName: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-raw" AccessControl: BucketOwnerFullControl PublicAccessBlockConfiguration: BlockPublicAcls: true IgnorePublicAcls: true BlockPublicPolicy: true RestrictPublicBuckets: true LoggingConfiguration: DestinationBucketName: !Ref rLogS3Bucket LogFilePrefix: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-raw-logs/" BucketEncryption: ServerSideEncryptionConfiguration: - BucketKeyEnabled: True ServerSideEncryptionByDefault: KMSMasterKeyID: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyId" SSEAlgorithm: 'aws:kms' LifecycleConfiguration: Rules: - Id: S3StandardIA Status: Enabled Transitions: - TransitionInDays: 1 StorageClass: INTELLIGENT_TIERING VersioningConfiguration: Status: Enabled # ########################################################## # # Normalized Replica # S3 Bucket policy ###### rNormalizedBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: rNormalizedReplicaS3Bucket Properties: Bucket: !Ref rNormalizedReplicaS3Bucket PolicyDocument: Statement: - Action: - 's3:*' Sid: 'AllowSSLRequestsOnly' Effect: Deny Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rNormalizedReplicaS3Bucket - /* - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rNormalizedReplicaS3Bucket Principal: "*" Condition: Bool: 'aws:SecureTransport': "false" - Action: - 's3:PutObject' Sid: 'RequireKMSEncryption' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rNormalizedReplicaS3Bucket - /* Condition: StringNotLikeIfExists: s3:x-amz-server-side-encryption-aws-kms-key-id: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyArn" - Action: - 's3:PutObject' Sid: 'DenySSE-S3' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rNormalizedReplicaS3Bucket - /* Condition: StringEquals: s3:x-amz-server-side-encryption: "AES256" rNormalizedReplicaS3Bucket: Type: 'AWS::S3::Bucket' DeletionPolicy: Retain DependsOn: rLogS3Bucket UpdateReplacePolicy: Retain Properties: BucketName: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-normalized" AccessControl: BucketOwnerFullControl PublicAccessBlockConfiguration: BlockPublicAcls: true IgnorePublicAcls: true BlockPublicPolicy: true RestrictPublicBuckets: true LoggingConfiguration: DestinationBucketName: !Ref rLogS3Bucket LogFilePrefix: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-normalized-logs/" BucketEncryption: ServerSideEncryptionConfiguration: - BucketKeyEnabled: True ServerSideEncryptionByDefault: KMSMasterKeyID: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyId" SSEAlgorithm: 'aws:kms' LifecycleConfiguration: Rules: - Id: IntelligentTiering Status: Enabled Transitions: - TransitionInDays: 1 StorageClass: INTELLIGENT_TIERING VersioningConfiguration: Status: Enabled # ########################################################## # # Curated Replica # S3 Bucket policy ###### rCuratedBucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: rCuratedReplicaS3Bucket Properties: Bucket: !Ref rCuratedReplicaS3Bucket PolicyDocument: Statement: - Action: - 's3:*' Sid: 'AllowSSLRequestsOnly' Effect: Deny Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rCuratedReplicaS3Bucket - /* - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rCuratedReplicaS3Bucket Principal: "*" Condition: Bool: 'aws:SecureTransport': "false" - Action: - 's3:PutObject' Sid: 'RequireKMSEncryption' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rCuratedReplicaS3Bucket - /* Condition: StringNotLikeIfExists: s3:x-amz-server-side-encryption-aws-kms-key-id: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyArn" - Action: - 's3:PutObject' Sid: 'DenySSE-S3' Effect: Deny Principal: "*" Resource: - 'Fn::Join': - '' - - 'arn:aws:s3:::' - Ref: rCuratedReplicaS3Bucket - /* Condition: StringEquals: s3:x-amz-server-side-encryption: "AES256" rCuratedReplicaS3Bucket: Type: 'AWS::S3::Bucket' DeletionPolicy: Retain DependsOn: rLogS3Bucket UpdateReplacePolicy: Retain Properties: BucketName: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-curated" AccessControl: BucketOwnerFullControl PublicAccessBlockConfiguration: BlockPublicAcls: true IgnorePublicAcls: true BlockPublicPolicy: true RestrictPublicBuckets: true LoggingConfiguration: DestinationBucketName: !Ref rLogS3Bucket LogFilePrefix: !Sub "${pOrganizationName}-${pFrameworkPrefix}-${AWS::Region}-${AWS::AccountId}-${pEnvironment}-replica-curated-logs/" BucketEncryption: ServerSideEncryptionConfiguration: - BucketKeyEnabled: True ServerSideEncryptionByDefault: KMSMasterKeyID: !ImportValue 'Fn::Sub': "${pFrameworkPrefix}-${pReplicaDestRegionKmsStackName}-KeyId" SSEAlgorithm: 'aws:kms' LifecycleConfiguration: Rules: - Id: IntelligentTiering Status: Enabled Transitions: - TransitionInDays: 1 StorageClass: INTELLIGENT_TIERING VersioningConfiguration: Status: Enabled