Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions serverless-resource/TopcoderAcademyPostgresDB.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Resources:
TopcoderAcademyPostgresDB:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
UpdateReplacePolicy: Snapshot
Properties:
DBInstanceIdentifier: topcoder-academy-${opt:stage,'dev'}
DBName: topcoder_academy
Expand All @@ -10,5 +12,8 @@ Resources:
DBSubnetGroupName: mysql-db-subnet
AllocatedStorage: 20
Engine: postgres
PubliclyAccessible: false
# Existing unencrypted instances require a snapshot/restore replacement.
StorageEncrypted: true
MasterUsername: ${self:custom.TCA_PG_USER}
MasterUserPassword: ${self:custom.TCA_PG_PASSWORD}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function validateImageUrl(url) {
try {
new URL(url)
} catch (error) {
throw new Error(`Image URL (${url}) is not a valid URL.`)
throw new Error('Certificate image URL is not valid.')
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,75 @@ Mappings:
RoleArn: arn:aws:iam::811668436784:role/learning-paths-v5-container-role

Resources:
TCACertificateImageStoreKey:
Type: AWS::KMS::Key
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
Description: !Sub "Encrypts TCA certificate image resources for ${Stage}"
EnableKeyRotation: true
KeyPolicy:
Version: "2012-10-17"
Statement:
- Sid: EnableAccountAdministration
Effect: Allow
Principal:
AWS: !Sub "arn:${AWS::Partition}:iam::${AWS::AccountId}:root"
Action: "kms:*"
Resource: "*"
- Sid: AllowCertificateImageGenerator
Effect: Allow
Principal:
AWS: !FindInMap
- DomainMap
- !Ref ImageStoreDomain
- RoleArn
Action:
- kms:Decrypt
- kms:DescribeKey
- kms:Encrypt
- kms:GenerateDataKey*
Resource: "*"
- Sid: AllowCloudFrontSSEKMS
Effect: Allow
Principal:
Service: cloudfront.amazonaws.com
Action:
- kms:Decrypt
- kms:Encrypt
- kms:GenerateDataKey*
Resource: "*"
Condition:
StringEquals:
"AWS:SourceAccount": !Ref AWS::AccountId
ArnLike:
"AWS:SourceArn": !Sub "arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/*"
- Sid: AllowCertificateImageQueues
Effect: Allow
Principal:
Service: sqs.amazonaws.com
Action:
- kms:Decrypt
- kms:GenerateDataKey*
Resource: "*"
Condition:
StringEquals:
"AWS:SourceAccount": !Ref AWS::AccountId
ArnLike:
"AWS:SourceArn": !Sub "arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:tca-certificate-generator-sqs-*"

TCAGenerateCertificateQueueDeadLetter:
Type: AWS::SQS::Queue
DeletionPolicy: Delete
Properties:
KmsMasterKeyId: !GetAtt TCACertificateImageStoreKey.Arn
QueueName: !Sub "tca-certificate-generator-sqs-dead-letter-${Stage}"

TCAGenerateCertificateQueue:
Type: AWS::SQS::Queue
DeletionPolicy: Delete
Properties:
KmsMasterKeyId: !GetAtt TCACertificateImageStoreKey.Arn
QueueName: !Sub "tca-certificate-generator-sqs-${Stage}"
RedrivePolicy:
deadLetterTargetArn: !GetAtt TCAGenerateCertificateQueueDeadLetter.Arn
Expand All @@ -47,8 +106,32 @@ Resources:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
AccessControl: PublicRead
AccessControl: Private
BucketName: !Sub "tca-certificate-generator-s3-${Stage}"
BucketEncryption:
ServerSideEncryptionConfiguration:
- BucketKeyEnabled: true
ServerSideEncryptionByDefault:
KMSMasterKeyID: !GetAtt TCACertificateImageStoreKey.Arn
SSEAlgorithm: aws:kms
OwnershipControls:
Rules:
- ObjectOwnership: BucketOwnerPreferred
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true

TCACertificateImageStoreOriginAccessControl:
Type: AWS::CloudFront::OriginAccessControl
Properties:
OriginAccessControlConfig:
Description: Access to the private TCA certificate image bucket
Name: !Sub "tca-certificate-images-${Stage}"
OriginAccessControlOriginType: s3
SigningBehavior: always
SigningProtocol: sigv4

TCACertificateImageStoreBucketPolicy:
Type: "AWS::S3::BucketPolicy"
Expand All @@ -58,43 +141,72 @@ Resources:
Id: TCACertificateImageStoreBucketPolicy
Version: 2012-10-17
Statement:
- Sid: PublicReadForGetBucketObjects
- Sid: AllowCloudFrontReadOnly
Effect: Allow
Principal: "*"
Principal:
Service: cloudfront.amazonaws.com
Action: "s3:GetObject"
Resource: !Join
- ""
- - "arn:aws:s3:::"
- !Ref TCACertificateImageStore
- /*
Resource: !Sub "${TCACertificateImageStore.Arn}/*"
Condition:
StringEquals:
"AWS:SourceArn": !Sub "arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${TCAGenerateCertificateCdn}"
- Sid: DenyInsecureTransport
Effect: Deny
Principal: "*"
Action: "s3:*"
Resource:
- !GetAtt TCACertificateImageStore.Arn
- !Sub "${TCACertificateImageStore.Arn}/*"
Condition:
Bool:
"aws:SecureTransport": false

TCAGenerateCertificateWebAcl:
Type: AWS::WAFv2::WebACL
Properties:
DefaultAction:
Allow: {}
Description: !Sub "Protects the TCA certificate image distribution for ${Stage}"
Name: !Sub "tca-certificate-images-${Stage}"
Rules:
- Name: AWSManagedRulesCommonRuleSet
OverrideAction:
None: {}
Priority: 0
Statement:
ManagedRuleGroupStatement:
Name: AWSManagedRulesCommonRuleSet
VendorName: AWS
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "tca-certificate-images-common-${Stage}"
SampledRequestsEnabled: true
Scope: CLOUDFRONT
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: !Sub "tca-certificate-images-${Stage}"
SampledRequestsEnabled: true

TCAGenerateCertificateCdn:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
WebACLId: !GetAtt TCAGenerateCertificateWebAcl.Arn
Aliases:
- !If [
IsProd,
!Sub "tca.${ImageStoreDomain}",
!Sub "tca-${Stage}.${ImageStoreDomain}",
]
Origins:
- Id: !Join
- ""
- - !Ref TCACertificateImageStore
- .s3.amazonaws.com
DomainName: !Join
- ""
- - !Ref TCACertificateImageStore
- .s3.amazonaws.com
- Id: CertificateImageS3Origin
DomainName: !GetAtt TCACertificateImageStore.RegionalDomainName
OriginAccessControlId: !Ref TCACertificateImageStoreOriginAccessControl
S3OriginConfig:
OriginAccessIdentity: ""
DefaultCacheBehavior:
TargetOriginId: !Join
- ""
- - !Ref TCACertificateImageStore
- .s3.amazonaws.com
TargetOriginId: CertificateImageS3Origin
ViewerProtocolPolicy: redirect-to-https
ForwardedValues:
QueryString: false
Expand All @@ -105,7 +217,7 @@ Resources:
- DomainMap
- !Ref ImageStoreDomain
- CertArn
MinimumProtocolVersion: TLSv1.2_2018
MinimumProtocolVersion: TLSv1.2_2021
SslSupportMethod: sni-only

TCAGenerateCertificateRoute:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ function handleImageUrlExistsRequest(url, certProgress, isAltUrl) {

// if we got an error, we have a prob
if (!!err) {
console.error(`Checking existence of ${url} caused ${err}`)
console.error('Checking certificate image existence failed')
return
}

// if the image exists, don't do anything
const altUrl = getAltImageUrl(url)
if (certificateExists) {

console.log('Exists:', url)
console.log(`Certificate ${isAltUrl ? 'alternate' : 'primary'} image exists`)

// if this isn't the alt url, try the alt url
if (!isAltUrl) {
Expand All @@ -127,7 +127,7 @@ function handleImageUrlExistsRequest(url, certProgress, isAltUrl) {
return
}

console.log('Does Not Exist:', isAltUrl ? altUrl : url)
console.log(`Certificate ${isAltUrl ? 'alternate' : 'primary'} image does not exist`)
generateCertificateImageAsync(certProgress)
}
}
Expand Down
Loading
Loading