Data platform (producer)¶
Encrypted storage that publishes where it is. The patterns are explained on the encrypted storage and publishing pages.
def build() -> cfn.Template:
params = cfn.Params()
stage = params.string("Stage", default="dev", allowed_values=["dev", "test", "prod"])
deploy_role = params.string("DeployRoleArn", description="The role that deploys this stack: it must keep bucket access")
tags = cfn.tags(Stage=stage)
return {
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": params.declarations(),
"Resources": cfn.combine(
encryption_key("Data", alias="data-platform", tags=tags),
secure_bucket(
"Data",
key_arn=get_att("DataKey", "Arn"),
allowed_principals=[deploy_role, sub("arn:${AWS::Partition}:iam::${AWS::AccountId}:role/data-platform-*")],
archive_after_days=90,
tags=tags,
),
{
"EventsTable": dynamodb_table("pk", "sk", tags=tags),
"ConfigTable": dynamodb_table("id", tags=tags),
},
publish(PREFIX, {"key-arn": get_att("DataKey", "Arn"), "bucket-arn": get_att("DataBucket", "Arn")}),
),
}
Rendered YAML¶
Committed as data-platform.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Stage:
Type: String
Default: dev
AllowedValues:
- dev
- test
- prod
DeployRoleArn:
Type: String
Description: 'The role that deploys this stack: it must keep bucket access'
Resources:
DataKey:
Type: AWS::KMS::Key
Properties:
Description: Data encryption key
EnableKeyRotation: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: EnableIamPolicies
Effect: Allow
Principal:
AWS: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root
Action: kms:*
Resource: '*'
Tags:
- Key: Stage
Value: !Ref Stage
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
DataKeyAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: alias/data-platform
TargetKeyId: !Ref DataKey
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
DataBucket:
Type: AWS::S3::Bucket
Properties:
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
KMSMasterKeyID: !GetAtt DataKey.Arn
BucketKeyEnabled: true
LifecycleConfiguration:
Rules:
- Id: archive
Status: Enabled
Transitions:
- StorageClass: GLACIER
TransitionInDays: 90
Tags:
- Key: Stage
Value: !Ref Stage
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
DataBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref DataBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: DenyInsecureTransport
Effect: Deny
Principal: '*'
Action: s3:*
Resource:
- !GetAtt DataBucket.Arn
- !Join
- ''
- - !GetAtt DataBucket.Arn
- /*
Condition:
Bool:
aws:SecureTransport: 'false'
- Sid: DenyEveryoneElse
Effect: Deny
Principal: '*'
Action: s3:*
Resource:
- !GetAtt DataBucket.Arn
- !Join
- ''
- - !GetAtt DataBucket.Arn
- /*
Condition:
StringNotLike:
aws:PrincipalArn:
- !Ref DeployRoleArn
- !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/data-platform-*
EventsTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
- AttributeName: sk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
BillingMode: PAY_PER_REQUEST
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
DeletionProtectionEnabled: true
Tags:
- Key: Stage
Value: !Ref Stage
ConfigTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
BillingMode: PAY_PER_REQUEST
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
DeletionProtectionEnabled: true
Tags:
- Key: Stage
Value: !Ref Stage
KeyArnParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: /data-platform/storage/key-arn
Value: !GetAtt DataKey.Arn
BucketArnParameter:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: /data-platform/storage/bucket-arn
Value: !GetAtt DataBucket.Arn