@medplum/cdk 2.1.17 → 2.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.test.ts DELETED
@@ -1,539 +0,0 @@
1
- import { unlinkSync, writeFileSync } from 'fs';
2
- import { resolve } from 'path';
3
- import { main } from './index';
4
-
5
- describe('Infra', () => {
6
- beforeEach(() => {
7
- console.log = jest.fn();
8
- });
9
-
10
- test('Missing config', () => {
11
- expect(() => main()).not.toThrow();
12
- });
13
-
14
- test('Synth stack', () => {
15
- // Create a temp config file
16
- const filename = resolve('./medplum.test.config.json');
17
- writeFileSync(
18
- filename,
19
- JSON.stringify({
20
- name: 'unittest',
21
- stackName: 'MedplumUnitTestStack',
22
- accountNumber: '647991932601',
23
- region: 'us-east-1',
24
- domainName: 'medplum.com',
25
- apiPort: 8103,
26
- apiDomainName: 'api.medplum.com',
27
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
28
- appDomainName: 'app.medplum.com',
29
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
30
- storageBucketName: 'medplum-storage',
31
- storageDomainName: 'storage.medplum.com',
32
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
33
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
34
- maxAzs: 2,
35
- rdsInstances: 1,
36
- desiredServerCount: 1,
37
- serverImage: 'medplum/medplum-server:staging',
38
- serverMemory: 512,
39
- serverCpu: 256,
40
- loadBalancerLoggingEnabled: true,
41
- loadBalancerLoggingBucket: 'medplum-logs-us-east-1',
42
- loadBalancerLoggingPrefix: 'elb',
43
- clamscanEnabled: true,
44
- clamscanLoggingBucket: 'medplum-logs-us-east-1',
45
- clamscanLoggingPrefix: 'clamscan',
46
- }),
47
- { encoding: 'utf-8' }
48
- );
49
-
50
- expect(() => main({ config: filename })).not.toThrow();
51
- unlinkSync(filename);
52
- });
53
-
54
- test('Multi region stack', () => {
55
- const filename = resolve('./medplum.multiregion.config.json');
56
- writeFileSync(
57
- filename,
58
- JSON.stringify({
59
- name: 'multiregion',
60
- stackName: 'MedplumMultiRegionStack',
61
- accountNumber: '647991932601',
62
- region: 'ap-southeast-1',
63
- domainName: 'ap-southeast-1.medplum.com',
64
- apiPort: 8103,
65
- apiDomainName: 'api.medplum.com',
66
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
67
- appDomainName: 'app.medplum.com',
68
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
69
- storageBucketName: 'medplum-storage',
70
- storageDomainName: 'storage.medplum.com',
71
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
72
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
73
- maxAzs: 2,
74
- rdsInstances: 1,
75
- desiredServerCount: 1,
76
- serverImage: 'medplum/medplum-server:staging',
77
- serverMemory: 512,
78
- serverCpu: 256,
79
- loadBalancerLoggingEnabled: true,
80
- loadBalancerLoggingBucket: 'medplum-logs-us-east-1',
81
- loadBalancerLoggingPrefix: 'elb',
82
- clamscanEnabled: true,
83
- clamscanLoggingBucket: 'medplum-logs-us-east-1',
84
- clamscanLoggingPrefix: 'clamscan',
85
- }),
86
- { encoding: 'utf-8' }
87
- );
88
-
89
- expect(() => main({ config: filename })).not.toThrow();
90
- unlinkSync(filename);
91
- });
92
-
93
- test('ECR image', () => {
94
- // Create a temp config file
95
- const filename = resolve('./medplum.customvpc.config.json');
96
- writeFileSync(
97
- filename,
98
- JSON.stringify({
99
- name: 'customvpc',
100
- stackName: 'MedplumCustomVpcStack',
101
- accountNumber: '647991932601',
102
- region: 'us-east-1',
103
- domainName: 'medplum.com',
104
- apiPort: 8103,
105
- apiDomainName: 'api.medplum.com',
106
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
107
- appDomainName: 'app.medplum.com',
108
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
109
- storageBucketName: 'medplum-storage',
110
- storageDomainName: 'storage.medplum.com',
111
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
112
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
113
- maxAzs: 2,
114
- rdsInstances: 1,
115
- rdsInstanceType: 't3.micro',
116
- desiredServerCount: 1,
117
- serverImage: '647991932601.dkr.ecr.us-east-1.amazonaws.com/medplum-server:staging',
118
- serverMemory: 512,
119
- serverCpu: 256,
120
- }),
121
- { encoding: 'utf-8' }
122
- );
123
-
124
- expect(() => main({ config: filename })).not.toThrow();
125
- unlinkSync(filename);
126
- });
127
-
128
- test('Custom VPC', () => {
129
- // Create a temp config file
130
- const filename = resolve('./medplum.customvpc.config.json');
131
- writeFileSync(
132
- filename,
133
- JSON.stringify({
134
- name: 'customvpc',
135
- stackName: 'MedplumCustomVpcStack',
136
- accountNumber: '647991932601',
137
- region: 'us-east-1',
138
- domainName: 'medplum.com',
139
- apiPort: 8103,
140
- vpcId: 'vpc-0fc3a4d0600000000',
141
- apiDomainName: 'api.medplum.com',
142
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
143
- appDomainName: 'app.medplum.com',
144
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
145
- storageBucketName: 'medplum-storage',
146
- storageDomainName: 'storage.medplum.com',
147
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
148
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
149
- maxAzs: 2,
150
- rdsInstances: 1,
151
- desiredServerCount: 1,
152
- serverImage: 'medplum/medplum-server:latest',
153
- serverMemory: 512,
154
- serverCpu: 256,
155
- }),
156
- { encoding: 'utf-8' }
157
- );
158
-
159
- expect(() => main({ config: filename })).not.toThrow();
160
- unlinkSync(filename);
161
- });
162
-
163
- test('Custom RDS instance type', () => {
164
- // Create a temp config file
165
- const filename = resolve('./medplum.customRdsInstanceType.config.json');
166
- writeFileSync(
167
- filename,
168
- JSON.stringify({
169
- name: 'customRdsInstanceType',
170
- stackName: 'MedplumCustomRdsInstanceTypeStack',
171
- accountNumber: '647991932601',
172
- region: 'us-east-1',
173
- domainName: 'medplum.com',
174
- apiPort: 8103,
175
- apiDomainName: 'api.medplum.com',
176
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
177
- appDomainName: 'app.medplum.com',
178
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
179
- storageBucketName: 'medplum-storage',
180
- storageDomainName: 'storage.medplum.com',
181
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
182
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
183
- maxAzs: 2,
184
- rdsInstances: 1,
185
- rdsInstanceType: 't3.micro',
186
- desiredServerCount: 1,
187
- serverImage: 'medplum/medplum-server:latest',
188
- serverMemory: 512,
189
- serverCpu: 256,
190
- }),
191
- { encoding: 'utf-8' }
192
- );
193
-
194
- expect(() => main({ config: filename })).not.toThrow();
195
- unlinkSync(filename);
196
- });
197
-
198
- test('Custom RDS secrets', () => {
199
- // Create a temp config file
200
- const filename = resolve('./medplum.customRdsSecrets.config.json');
201
- const rdsSecretsArn = 'arn:aws:secretsmanager:s-east-1:647991932601:secret:SecretName-6RandomCharacters';
202
- writeFileSync(
203
- filename,
204
- JSON.stringify({
205
- name: 'customRdsSecrets',
206
- stackName: 'MedplumCustomRdsSecretsStack',
207
- accountNumber: '647991932601',
208
- region: 'us-east-1',
209
- domainName: 'medplum.com',
210
- apiPort: 8103,
211
- apiDomainName: 'api.medplum.com',
212
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
213
- appDomainName: 'app.medplum.com',
214
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
215
- storageBucketName: 'medplum-storage',
216
- storageDomainName: 'storage.medplum.com',
217
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
218
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
219
- maxAzs: 2,
220
- rdsSecretsArn,
221
- desiredServerCount: 1,
222
- serverImage: 'medplum/medplum-server:latest',
223
- serverMemory: 512,
224
- serverCpu: 256,
225
- }),
226
- { encoding: 'utf-8' }
227
- );
228
-
229
- expect(() => main({ config: filename })).not.toThrow();
230
- unlinkSync(filename);
231
- });
232
-
233
- test('Skip DNS', () => {
234
- // Create a temp config file
235
- const filename = resolve('./medplum.skipDns.config.json');
236
- writeFileSync(
237
- filename,
238
- JSON.stringify({
239
- name: 'skipDns',
240
- stackName: 'MedplumSkipDnsStack',
241
- accountNumber: '647991932601',
242
- region: 'us-east-1',
243
- domainName: 'medplum.com',
244
- apiPort: 8103,
245
- apiDomainName: 'api.medplum.com',
246
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
247
- appDomainName: 'app.medplum.com',
248
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
249
- storageBucketName: 'medplum-storage',
250
- storageDomainName: 'storage.medplum.com',
251
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
252
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
253
- maxAzs: 2,
254
- rdsInstances: 1,
255
- desiredServerCount: 1,
256
- serverImage: 'medplum/medplum-server:latest',
257
- serverMemory: 512,
258
- serverCpu: 256,
259
- skipDns: true,
260
- }),
261
- { encoding: 'utf-8' }
262
- );
263
-
264
- expect(() => main({ config: filename })).not.toThrow();
265
- unlinkSync(filename);
266
- });
267
-
268
- test('Add DataDog container', () => {
269
- // Create a temp config file
270
- const filename = resolve('./medplum.datadog.config.json');
271
- writeFileSync(
272
- filename,
273
- JSON.stringify({
274
- name: 'datadog',
275
- stackName: 'MedplumDataDogStack',
276
- accountNumber: '647991932601',
277
- region: 'us-east-1',
278
- domainName: 'medplum.com',
279
- apiPort: 8103,
280
- apiDomainName: 'api.medplum.com',
281
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
282
- appDomainName: 'app.medplum.com',
283
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
284
- storageBucketName: 'medplum-storage',
285
- storageDomainName: 'storage.medplum.com',
286
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
287
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
288
- maxAzs: 2,
289
- rdsInstances: 1,
290
- desiredServerCount: 1,
291
- serverImage: 'medplum/medplum-server:latest',
292
- serverMemory: 512,
293
- serverCpu: 256,
294
- additionalContainers: [
295
- {
296
- name: 'datadog-agent',
297
- image: 'datadog/agent:latest',
298
- environment: {
299
- DD_SITE: 'datadoghq.com',
300
- DD_API_KEY: 'YOUR_DATADOG_API_KEY',
301
- },
302
- },
303
- ],
304
- }),
305
- { encoding: 'utf-8' }
306
- );
307
-
308
- expect(() => main({ config: filename })).not.toThrow();
309
- unlinkSync(filename);
310
- });
311
-
312
- test('API in private subnet', () => {
313
- // Create a temp config file
314
- const filename = resolve('./medplum.test.config.json');
315
- writeFileSync(
316
- filename,
317
- JSON.stringify({
318
- name: 'unittest',
319
- stackName: 'MedplumUnitTestStack',
320
- accountNumber: '647991932601',
321
- region: 'us-east-1',
322
- domainName: 'medplum.com',
323
- apiPort: 8103,
324
- apiDomainName: 'api.medplum.com',
325
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
326
- apiInternetFacing: false,
327
- appDomainName: 'app.medplum.com',
328
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
329
- storageBucketName: 'medplum-storage',
330
- storageDomainName: 'storage.medplum.com',
331
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
332
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
333
- maxAzs: 2,
334
- rdsInstances: 1,
335
- desiredServerCount: 1,
336
- serverImage: 'medplum/medplum-server:staging',
337
- serverMemory: 512,
338
- serverCpu: 256,
339
- loadBalancerLoggingEnabled: true,
340
- loadBalancerLoggingBucket: 'medplum-logs-us-east-1',
341
- loadBalancerLoggingPrefix: 'elb',
342
- clamscanEnabled: true,
343
- clamscanLoggingBucket: 'medplum-logs-us-east-1',
344
- clamscanLoggingPrefix: 'clamscan',
345
- }),
346
- { encoding: 'utf-8' }
347
- );
348
-
349
- expect(() => main({ config: filename })).not.toThrow();
350
- unlinkSync(filename);
351
- });
352
-
353
- test('Disable app-api proxy', () => {
354
- // Create a temp config file
355
- const filename = resolve('./medplum.test.config.json');
356
- writeFileSync(
357
- filename,
358
- JSON.stringify({
359
- name: 'unittest',
360
- stackName: 'MedplumUnitTestStack',
361
- accountNumber: '647991932601',
362
- region: 'us-east-1',
363
- domainName: 'medplum.com',
364
- apiPort: 8103,
365
- apiDomainName: 'api.medplum.com',
366
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
367
- appDomainName: 'app.medplum.com',
368
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
369
- appApiProxy: false,
370
- storageBucketName: 'medplum-storage',
371
- storageDomainName: 'storage.medplum.com',
372
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
373
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
374
- maxAzs: 2,
375
- rdsInstances: 1,
376
- desiredServerCount: 1,
377
- serverImage: 'medplum/medplum-server:staging',
378
- serverMemory: 512,
379
- serverCpu: 256,
380
- loadBalancerLoggingEnabled: true,
381
- loadBalancerLoggingBucket: 'medplum-logs-us-east-1',
382
- loadBalancerLoggingPrefix: 'elb',
383
- clamscanEnabled: true,
384
- clamscanLoggingBucket: 'medplum-logs-us-east-1',
385
- clamscanLoggingPrefix: 'clamscan',
386
- }),
387
- { encoding: 'utf-8' }
388
- );
389
-
390
- expect(() => main({ config: filename })).not.toThrow();
391
- unlinkSync(filename);
392
- });
393
-
394
- test('Custom cacheNodeType', () => {
395
- // Create a temp config file
396
- const filename = resolve('./medplum.cacheNodeType.config.json');
397
- writeFileSync(
398
- filename,
399
- JSON.stringify({
400
- name: 'unittest',
401
- stackName: 'MedplumCacheNodeTypeStack',
402
- accountNumber: '647991932601',
403
- region: 'us-east-1',
404
- domainName: 'medplum.com',
405
- apiPort: 8103,
406
- apiDomainName: 'api.medplum.com',
407
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
408
- appDomainName: 'app.medplum.com',
409
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
410
- appApiProxy: false,
411
- storageBucketName: 'medplum-storage',
412
- storageDomainName: 'storage.medplum.com',
413
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
414
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
415
- maxAzs: 2,
416
- rdsInstances: 1,
417
- desiredServerCount: 1,
418
- cacheNodeType: 'cache.m4.2xlarge',
419
- serverImage: 'medplum/medplum-server:staging',
420
- serverMemory: 512,
421
- serverCpu: 256,
422
- loadBalancerLoggingEnabled: true,
423
- loadBalancerLoggingBucket: 'medplum-logs-us-east-1',
424
- loadBalancerLoggingPrefix: 'elb',
425
- clamscanEnabled: true,
426
- clamscanLoggingBucket: 'medplum-logs-us-east-1',
427
- clamscanLoggingPrefix: 'clamscan',
428
- }),
429
- { encoding: 'utf-8' }
430
- );
431
-
432
- expect(() => main({ config: filename })).not.toThrow();
433
- unlinkSync(filename);
434
- });
435
-
436
- test('RDS reader instance', () => {
437
- const filename = resolve('./medplum.reader.config.json');
438
- writeFileSync(
439
- filename,
440
- JSON.stringify({
441
- name: 'unittest',
442
- stackName: 'MedplumReaderStack',
443
- accountNumber: '647991932601',
444
- region: 'us-east-1',
445
- domainName: 'medplum.com',
446
- apiPort: 8103,
447
- apiDomainName: 'api.medplum.com',
448
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
449
- appDomainName: 'app.medplum.com',
450
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
451
- storageBucketName: 'medplum-storage',
452
- storageDomainName: 'storage.medplum.com',
453
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
454
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
455
- maxAzs: 2,
456
- rdsInstances: 2,
457
- desiredServerCount: 1,
458
- serverImage: 'medplum/medplum-server:staging',
459
- serverMemory: 512,
460
- serverCpu: 256,
461
- }),
462
- { encoding: 'utf-8' }
463
- );
464
-
465
- expect(() => main({ config: filename })).not.toThrow();
466
- unlinkSync(filename);
467
- });
468
-
469
- test('Existing signing key', () => {
470
- const filename = resolve('./medplum.signingKey.config.json');
471
- writeFileSync(
472
- filename,
473
- JSON.stringify({
474
- name: 'signingKey',
475
- stackName: 'MedplumSigningKeyStack',
476
- accountNumber: '647991932601',
477
- region: 'us-east-1',
478
- domainName: 'medplum.com',
479
- apiPort: 8103,
480
- apiDomainName: 'api.medplum.com',
481
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
482
- appDomainName: 'app.medplum.com',
483
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
484
- storageBucketName: 'medplum-storage',
485
- storageDomainName: 'storage.medplum.com',
486
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
487
- signingKeyId: 'K1234',
488
- maxAzs: 2,
489
- rdsInstances: 2,
490
- desiredServerCount: 1,
491
- serverImage: 'medplum/medplum-server:staging',
492
- serverMemory: 512,
493
- serverCpu: 256,
494
- }),
495
- { encoding: 'utf-8' }
496
- );
497
-
498
- expect(() => main({ config: filename })).not.toThrow();
499
- unlinkSync(filename);
500
- });
501
-
502
- test('CloudTrail alarms', () => {
503
- const filename = resolve('./medplum.cloudtrail.config.json');
504
- writeFileSync(
505
- filename,
506
- JSON.stringify({
507
- name: 'cloudtrail',
508
- stackName: 'MedplumCloudTrailStack',
509
- accountNumber: '647991932601',
510
- region: 'us-east-1',
511
- domainName: 'medplum.com',
512
- apiPort: 8103,
513
- apiDomainName: 'api.medplum.com',
514
- apiSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/08bf1daf-3a2b-4cbe-91a0-739b4364a1ec',
515
- appDomainName: 'app.medplum.com',
516
- appSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/fd21b628-b2c0-4a5d-b4f5-b5c9a6d63b1a',
517
- storageBucketName: 'medplum-storage',
518
- storageDomainName: 'storage.medplum.com',
519
- storageSslCertArn: 'arn:aws:acm:us-east-1:647991932601:certificate/19d85245-0a1d-4bf5-9789-23082b1a15fc',
520
- storagePublicKey: '-----BEGIN PUBLIC KEY-----\n-----END PUBLIC KEY-----',
521
- maxAzs: 2,
522
- rdsInstances: 1,
523
- desiredServerCount: 1,
524
- serverImage: 'medplum/medplum-server:staging',
525
- serverMemory: 512,
526
- serverCpu: 256,
527
- cloudTrailAlarms: {
528
- logGroupName: 'cloudtrail-logs',
529
- logGroupCreate: true,
530
- snsTopicName: 'cloudtrail-alarms',
531
- },
532
- }),
533
- { encoding: 'utf-8' }
534
- );
535
-
536
- expect(() => main({ config: filename })).not.toThrow();
537
- unlinkSync(filename);
538
- });
539
- });
package/src/index.ts DELETED
@@ -1,42 +0,0 @@
1
- import { MedplumSourceInfraConfig } from '@medplum/core';
2
- import { App } from 'aws-cdk-lib';
3
- import { readFileSync } from 'fs';
4
- import { resolve } from 'path';
5
- import { normalizeInfraConfig } from './config';
6
- import { MedplumStack } from './stack';
7
-
8
- export * from './backend';
9
- export * from './cloudtrail';
10
- export * from './frontend';
11
- export * from './stack';
12
- export * from './storage';
13
- export * from './waf';
14
-
15
- export function main(context?: Record<string, string>): void {
16
- const app = new App({ context });
17
-
18
- const configFileName = app.node.tryGetContext('config');
19
- if (!configFileName) {
20
- console.log('Missing "config" context variable');
21
- console.log('Usage: cdk deploy -c config=my-config.json');
22
- return;
23
- }
24
-
25
- const config = JSON.parse(readFileSync(resolve(configFileName), 'utf-8')) as MedplumSourceInfraConfig;
26
-
27
- normalizeInfraConfig(config)
28
- .then((normalizedConfig) => {
29
- const stack = new MedplumStack(app, normalizedConfig);
30
- console.log('Stack', stack.primaryStack.stackId);
31
-
32
- app.synth();
33
- })
34
- .catch((err) => {
35
- console.error(err);
36
- process.exit(1);
37
- });
38
- }
39
-
40
- if (require.main === module) {
41
- main();
42
- }
package/src/oai.ts DELETED
@@ -1,32 +0,0 @@
1
- import { aws_cloudfront as cloudfront, aws_iam as iam, aws_s3 as s3 } from 'aws-cdk-lib';
2
-
3
- /**
4
- * Grants S3 bucket read access to the CloudFront Origin Access Identity (OAI).
5
- *
6
- * Under normal circumstances, where CDK creates both the S3 bucket and the OAI,
7
- * you can achieve this same behavior by simply calling:
8
- *
9
- * bucket.grantRead(identity);
10
- *
11
- * However, if importing an S3 bucket via `s3.Bucket.fromBucketAttributes()`, that does not work.
12
- *
13
- * See: https://stackoverflow.com/a/60917015
14
- *
15
- * @param bucket - The S3 bucket.
16
- * @param identity - The CloudFront Origin Access Identity.
17
- * @returns The policy statement.
18
- */
19
- export function grantBucketAccessToOriginAccessIdentity(
20
- bucket: s3.IBucket,
21
- identity: cloudfront.OriginAccessIdentity
22
- ): iam.PolicyStatement {
23
- const policyStatement = new iam.PolicyStatement();
24
- policyStatement.addActions('s3:GetObject*');
25
- policyStatement.addActions('s3:GetBucket*');
26
- policyStatement.addActions('s3:List*');
27
- policyStatement.addResources(bucket.bucketArn);
28
- policyStatement.addResources(`${bucket.bucketArn}/*`);
29
- policyStatement.addCanonicalUserPrincipal(identity.cloudFrontOriginAccessIdentityS3CanonicalUserId);
30
- bucket.addToResourcePolicy(policyStatement);
31
- return policyStatement;
32
- }
package/src/stack.ts DELETED
@@ -1,65 +0,0 @@
1
- import { MedplumInfraConfig } from '@medplum/core';
2
- import { App, Stack, Tags } from 'aws-cdk-lib';
3
- import { BackEnd } from './backend';
4
- import { CloudTrailAlarms } from './cloudtrail';
5
- import { FrontEnd } from './frontend';
6
- import { Storage } from './storage';
7
-
8
- export class MedplumStack {
9
- primaryStack: MedplumPrimaryStack;
10
- globalStack?: MedplumGlobalStack;
11
-
12
- constructor(scope: App, config: MedplumInfraConfig) {
13
- this.primaryStack = new MedplumPrimaryStack(scope, config);
14
-
15
- if (config.region !== 'us-east-1') {
16
- // Some resources must be created in us-east-1
17
- // For example, CloudFront distributions and ACM certificates
18
- // If the primary region is not us-east-1, create these resources in us-east-1
19
- this.globalStack = new MedplumGlobalStack(scope, config);
20
- this.globalStack.addDependency(this.primaryStack);
21
- }
22
- }
23
- }
24
-
25
- export class MedplumPrimaryStack extends Stack {
26
- backEnd: BackEnd;
27
- frontEnd: FrontEnd;
28
- storage: Storage;
29
- cloudTrail: CloudTrailAlarms;
30
-
31
- constructor(scope: App, config: MedplumInfraConfig) {
32
- super(scope, config.stackName, {
33
- env: {
34
- region: config.region,
35
- account: config.accountNumber,
36
- },
37
- });
38
- Tags.of(this).add('medplum:environment', config.name);
39
-
40
- this.backEnd = new BackEnd(this, config);
41
- this.frontEnd = new FrontEnd(this, config, config.region);
42
- this.storage = new Storage(this, config, config.region);
43
- this.cloudTrail = new CloudTrailAlarms(this, config);
44
- }
45
- }
46
-
47
- export class MedplumGlobalStack extends Stack {
48
- frontEnd: FrontEnd;
49
- storage: Storage;
50
- cloudTrail: CloudTrailAlarms;
51
-
52
- constructor(scope: App, config: MedplumInfraConfig) {
53
- super(scope, config.stackName + '-us-east-1', {
54
- env: {
55
- region: 'us-east-1',
56
- account: config.accountNumber,
57
- },
58
- });
59
- Tags.of(this).add('medplum:environment', config.name);
60
-
61
- this.frontEnd = new FrontEnd(this, config, 'us-east-1');
62
- this.storage = new Storage(this, config, 'us-east-1');
63
- this.cloudTrail = new CloudTrailAlarms(this, config);
64
- }
65
- }