diff --git a/cloudformation/batch.template.js b/cloudformation/batch.template.js index 0f89bd5b..9dbe02d6 100644 --- a/cloudformation/batch.template.js +++ b/cloudformation/batch.template.js @@ -1,10 +1,11 @@ 'use strict'; const cf = require('@mapbox/cloudfriend'); -const api = require('./api'); -const batch = require('./batch'); -const db = require('./db'); -const schedule = require('./schedule'); +const api = require('./lib/api'); +const batch = require('./lib/batch'); +const db = require('./lib/db'); +const schedule = require('./lib/schedule'); +const kms = require('./lib/kms'); const alarms = require('batch-alarms'); const stack = { @@ -39,6 +40,7 @@ module.exports = cf.merge( stack, db, api, + kms, batch, alarms({ prefix: 'Batch', diff --git a/cloudformation/api.js b/cloudformation/lib/api.js similarity index 99% rename from cloudformation/api.js rename to cloudformation/lib/api.js index 4815d246..40543880 100644 --- a/cloudformation/api.js +++ b/cloudformation/lib/api.js @@ -223,7 +223,7 @@ const stack = { { Name: 'MAPBOX_TOKEN', Value: cf.ref('MapboxToken') }, { Name: 'MAILGUN_API_KEY', Value: cf.ref('MailGun') }, { Name: 'OPENCOLLECTIVE_API_KEY', Value: cf.ref('OpenCollective') }, - { Name: 'POSTGRES', Value: cf.join(['postgresql://openaddresses:', cf.ref('DatabasePassword'), '@', cf.getAtt('DBInstance', 'Endpoint.Address'), ':5432/openaddresses']) }, + { Name: 'POSTGRES', Value: cf.join(['postgresql://openaddresses:', cf.ref('DatabasePassword'), '@', cf.getAtt('DBInstanceVPC', 'Endpoint.Address'), ':5432/openaddresses']) }, { Name: 'SharedSecret', Value: cf.ref('SharedSecret') }, { Name: 'GithubSecret', Value: cf.ref('GithubSecret') }, { Name: 'Bucket', Value: cf.ref('Bucket') }, diff --git a/cloudformation/batch.js b/cloudformation/lib/batch.js similarity index 100% rename from cloudformation/batch.js rename to cloudformation/lib/batch.js diff --git a/cloudformation/db.js b/cloudformation/lib/db.js similarity index 75% rename from cloudformation/db.js rename to cloudformation/lib/db.js index 2ee859f4..25b6b786 100644 --- a/cloudformation/db.js +++ b/cloudformation/lib/db.js @@ -18,11 +18,13 @@ const stack = { } }, Resources: { - DBInstance: { + DBInstanceVPC: { Type: 'AWS::RDS::DBInstance', Properties: { Engine: 'postgres', DBName: 'openaddresses', + DBInstanceIdentifier: cf.stackName, + KmsKeyId: cf.ref('OAKMS'), EngineVersion: '13.3', MasterUsername: 'openaddresses', MasterUserPassword: cf.ref('DatabasePassword'), @@ -30,12 +32,27 @@ const stack = { MaxAllocatedStorage: 100, BackupRetentionPeriod: 10, StorageType: 'gp2', + StorageEncrypted: true, DBInstanceClass: cf.ref('DatabaseType'), - DBSecurityGroups: [cf.ref('DBSecurityGroup')], + VPCSecurityGroups: [cf.ref('DBVPCSecurityGroup')], DBSubnetGroupName: cf.ref('DBSubnet'), PubliclyAccessible: true } }, + DBVPCSecurityGroup: { + Type: 'AWS::EC2::SecurityGroup', + Properties: { + GroupDescription: cf.join('-', [cf.stackName, 'rds-sg']), + VpcId: 'vpc-3f2aa15a', + SecurityGroupIngress: [{ + IpProtocol: '-1', + SourceSecurityGroupId: cf.getAtt('APIServiceSecurityGroup', 'GroupId') + },{ + IpProtocol: '-1', + CidrIp: '0.0.0.0/0' + }] + } + }, DBSubnet: { Type: 'AWS::RDS::DBSubnetGroup', Properties: { @@ -50,19 +67,6 @@ const stack = { ] } }, - DBSecurityGroup: { - Type: 'AWS::RDS::DBSecurityGroup', - Properties: { - GroupDescription: cf.join('-', [cf.stackName, 'rds-sg']), - EC2VpcId: 'vpc-3f2aa15a', - DBSecurityGroupIngress: [{ - EC2SecurityGroupId: cf.getAtt('APIServiceSecurityGroup', 'GroupId') - },{ - CIDRIP: '0.0.0.0/0' - }] - } - } - }, Outputs: { DB: { @@ -72,7 +76,7 @@ const stack = { ':', cf.ref('DatabasePassword'), '@', - cf.getAtt('DBInstance', 'Endpoint.Address'), + cf.getAtt('DBInstanceVPC', 'Endpoint.Address'), ':5432/openaddresses' ]) } diff --git a/cloudformation/lib/kms.js b/cloudformation/lib/kms.js new file mode 100644 index 00000000..4e744737 --- /dev/null +++ b/cloudformation/lib/kms.js @@ -0,0 +1,29 @@ +'use strict'; + +const cf = require('@mapbox/cloudfriend'); + +const stack = { + Resources: { + OAKMS: { + Type : 'AWS::KMS::Key', + Properties: { + Description: cf.stackName, + Enabled: true, + EnableKeyRotation: false, + KeyPolicy: { + Id: cf.stackName, + Statement: [{ + Effect: 'Allow', + Principal: { + AWS: cf.join(['arn:aws:iam::', cf.accountId, ':root']), + }, + Action: ['kms:*'], + Resource: '*' + }] + } + } + } + } +}; + +module.exports = stack; diff --git a/cloudformation/schedule.js b/cloudformation/lib/schedule.js similarity index 100% rename from cloudformation/schedule.js rename to cloudformation/lib/schedule.js diff --git a/cloudformation/task.template.js b/cloudformation/task.template.js index db2af843..ec2bf708 100644 --- a/cloudformation/task.template.js +++ b/cloudformation/task.template.js @@ -1,6 +1,7 @@ 'use strict'; const cf = require('@mapbox/cloudfriend'); + const stack = { AWSTemplateFormatVersion: '2010-09-09', Description: 'OpenAddresses Batch T3 Compute Environment',