├── .eslintrc
├── .gitignore
├── .idea
├── .gitignore
├── aws-development-with-localstack.iml
├── aws.xml
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── modules.xml
├── sonarlint
│ └── issuestore
│ │ └── index.pb
└── vcs.xml
├── .prettierrc
├── LICENSE
├── README.md
├── bin
└── app.ts
├── cdk.json
├── jest.config.js
├── lib
├── ApplicationStack.ts
├── dynamodb
│ ├── index.ts
│ └── test-development.ts
├── firehose
│ ├── index.ts
│ └── test-firehose.ts
├── iam
│ ├── firehose_skeleton.json
│ ├── super-role.json
│ └── super-role.ts
├── s3
│ ├── index.ts
│ └── screenshot.ts
└── sqs
│ ├── index.ts
│ └── simple-sqs-development.ts
├── localstack
└── docker-compose.yml
├── package-lock.json
├── package.json
├── scripts
├── config.ts
└── migrationModels
│ └── migrationScript.ts
├── seed
├── config.ts
└── index.ts
├── test
└── app.test.ts
├── tsconfig.json
├── utils
└── createGlobalSecondaryIndex.ts
└── yarn.lock
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "@typescript-eslint/parser",
3 | "extends": ["plugin:@typescript-eslint/recommended"],
4 | "parserOptions": { "ecmaVersion": 2018, "sourceType": "module" },
5 | "rules": {}
6 | }
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
106 | # This local data
107 | localstack/.localstack/
108 |
109 | # your stack
110 | cdk.out/
111 | /cdk.out/
112 | setup
113 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/aws-development-with-localstack.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/aws.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | (-[a-z]+-)?font
50 |
51 | BY_NAME
52 |
53 |
54 |
55 | (-[a-z]+-)?font-family
56 |
57 | BY_NAME
58 |
59 |
60 |
61 | (-[a-z]+-)?font-size
62 |
63 | BY_NAME
64 |
65 |
66 |
67 | (-[a-z]+-)?font-weight
68 |
69 | BY_NAME
70 |
71 |
72 |
73 | (-[a-z]+-)?font-style
74 |
75 | BY_NAME
76 |
77 |
78 |
79 | (-[a-z]+-)?font-variant
80 |
81 | BY_NAME
82 |
83 |
84 |
85 | (-[a-z]+-)?font-size-adjust
86 |
87 | BY_NAME
88 |
89 |
90 |
91 | (-[a-z]+-)?font-stretch
92 |
93 | BY_NAME
94 |
95 |
96 |
97 | (-[a-z]+-)?line-height
98 |
99 | BY_NAME
100 |
101 |
102 |
103 | (-[a-z]+-)?position
104 |
105 | BY_NAME
106 |
107 |
108 |
109 | (-[a-z]+-)?z-index
110 |
111 | BY_NAME
112 |
113 |
114 |
115 | (-[a-z]+-)?top
116 |
117 | BY_NAME
118 |
119 |
120 |
121 | (-[a-z]+-)?right
122 |
123 | BY_NAME
124 |
125 |
126 |
127 | (-[a-z]+-)?bottom
128 |
129 | BY_NAME
130 |
131 |
132 |
133 | (-[a-z]+-)?left
134 |
135 | BY_NAME
136 |
137 |
138 |
139 | (-[a-z]+-)?display
140 |
141 | BY_NAME
142 |
143 |
144 |
145 | (-[a-z]+-)?visibility
146 |
147 | BY_NAME
148 |
149 |
150 |
151 | (-[a-z]+-)?float
152 |
153 | BY_NAME
154 |
155 |
156 |
157 | (-[a-z]+-)?clear
158 |
159 | BY_NAME
160 |
161 |
162 |
163 | (-[a-z]+-)?overflow
164 |
165 | BY_NAME
166 |
167 |
168 |
169 | (-[a-z]+-)?overflow-x
170 |
171 | BY_NAME
172 |
173 |
174 |
175 | (-[a-z]+-)?overflow-y
176 |
177 | BY_NAME
178 |
179 |
180 |
181 | (-[a-z]+-)?clip
182 |
183 | BY_NAME
184 |
185 |
186 |
187 | (-[a-z]+-)?zoom
188 |
189 | BY_NAME
190 |
191 |
192 |
193 | (-[a-z]+-)?align-content
194 |
195 | BY_NAME
196 |
197 |
198 |
199 | (-[a-z]+-)?align-items
200 |
201 | BY_NAME
202 |
203 |
204 |
205 | (-[a-z]+-)?align-self
206 |
207 | BY_NAME
208 |
209 |
210 |
211 | (-[a-z]+-)?flex
212 |
213 | BY_NAME
214 |
215 |
216 |
217 | (-[a-z]+-)?flex-flow
218 |
219 | BY_NAME
220 |
221 |
222 |
223 | (-[a-z]+-)?flex-basis
224 |
225 | BY_NAME
226 |
227 |
228 |
229 | (-[a-z]+-)?flex-direction
230 |
231 | BY_NAME
232 |
233 |
234 |
235 | (-[a-z]+-)?flex-grow
236 |
237 | BY_NAME
238 |
239 |
240 |
241 | (-[a-z]+-)?flex-shrink
242 |
243 | BY_NAME
244 |
245 |
246 |
247 | (-[a-z]+-)?flex-wrap
248 |
249 | BY_NAME
250 |
251 |
252 |
253 | (-[a-z]+-)?justify-content
254 |
255 | BY_NAME
256 |
257 |
258 |
259 | (-[a-z]+-)?order
260 |
261 | BY_NAME
262 |
263 |
264 |
265 | (-[a-z]+-)?box-sizing
266 |
267 | BY_NAME
268 |
269 |
270 |
271 | (-[a-z]+-)?width
272 |
273 | BY_NAME
274 |
275 |
276 |
277 | (-[a-z]+-)?min-width
278 |
279 | BY_NAME
280 |
281 |
282 |
283 | (-[a-z]+-)?max-width
284 |
285 | BY_NAME
286 |
287 |
288 |
289 | (-[a-z]+-)?height
290 |
291 | BY_NAME
292 |
293 |
294 |
295 | (-[a-z]+-)?min-height
296 |
297 | BY_NAME
298 |
299 |
300 |
301 | (-[a-z]+-)?max-height
302 |
303 | BY_NAME
304 |
305 |
306 |
307 | (-[a-z]+-)?margin
308 |
309 | BY_NAME
310 |
311 |
312 |
313 | (-[a-z]+-)?margin-top
314 |
315 | BY_NAME
316 |
317 |
318 |
319 | (-[a-z]+-)?margin-right
320 |
321 | BY_NAME
322 |
323 |
324 |
325 | (-[a-z]+-)?margin-bottom
326 |
327 | BY_NAME
328 |
329 |
330 |
331 | (-[a-z]+-)?margin-left
332 |
333 | BY_NAME
334 |
335 |
336 |
337 | (-[a-z]+-)?padding
338 |
339 | BY_NAME
340 |
341 |
342 |
343 | (-[a-z]+-)?padding-top
344 |
345 | BY_NAME
346 |
347 |
348 |
349 | (-[a-z]+-)?padding-right
350 |
351 | BY_NAME
352 |
353 |
354 |
355 | (-[a-z]+-)?padding-bottom
356 |
357 | BY_NAME
358 |
359 |
360 |
361 | (-[a-z]+-)?padding-left
362 |
363 | BY_NAME
364 |
365 |
366 |
367 | (-[a-z]+-)?table-layout
368 |
369 | BY_NAME
370 |
371 |
372 |
373 | (-[a-z]+-)?empty-cells
374 |
375 | BY_NAME
376 |
377 |
378 |
379 | (-[a-z]+-)?caption-side
380 |
381 | BY_NAME
382 |
383 |
384 |
385 | (-[a-z]+-)?border-spacing
386 |
387 | BY_NAME
388 |
389 |
390 |
391 | (-[a-z]+-)?border-collapse
392 |
393 | BY_NAME
394 |
395 |
396 |
397 | (-[a-z]+-)?list-style
398 |
399 | BY_NAME
400 |
401 |
402 |
403 | (-[a-z]+-)?list-style-position
404 |
405 | BY_NAME
406 |
407 |
408 |
409 | (-[a-z]+-)?list-style-type
410 |
411 | BY_NAME
412 |
413 |
414 |
415 | (-[a-z]+-)?list-style-image
416 |
417 | BY_NAME
418 |
419 |
420 |
421 | (-[a-z]+-)?content
422 |
423 | BY_NAME
424 |
425 |
426 |
427 | (-[a-z]+-)?quotes
428 |
429 | BY_NAME
430 |
431 |
432 |
433 | (-[a-z]+-)?counter-reset
434 |
435 | BY_NAME
436 |
437 |
438 |
439 | (-[a-z]+-)?counter-increment
440 |
441 | BY_NAME
442 |
443 |
444 |
445 | (-[a-z]+-)?resize
446 |
447 | BY_NAME
448 |
449 |
450 |
451 | (-[a-z]+-)?cursor
452 |
453 | BY_NAME
454 |
455 |
456 |
457 | (-[a-z]+-)?user-select
458 |
459 | BY_NAME
460 |
461 |
462 |
463 | (-[a-z]+-)?nav-index
464 |
465 | BY_NAME
466 |
467 |
468 |
469 | (-[a-z]+-)?nav-up
470 |
471 | BY_NAME
472 |
473 |
474 |
475 | (-[a-z]+-)?nav-right
476 |
477 | BY_NAME
478 |
479 |
480 |
481 | (-[a-z]+-)?nav-down
482 |
483 | BY_NAME
484 |
485 |
486 |
487 | (-[a-z]+-)?nav-left
488 |
489 | BY_NAME
490 |
491 |
492 |
493 | (-[a-z]+-)?transition
494 |
495 | BY_NAME
496 |
497 |
498 |
499 | (-[a-z]+-)?transition-delay
500 |
501 | BY_NAME
502 |
503 |
504 |
505 | (-[a-z]+-)?transition-timing-function
506 |
507 | BY_NAME
508 |
509 |
510 |
511 | (-[a-z]+-)?transition-duration
512 |
513 | BY_NAME
514 |
515 |
516 |
517 | (-[a-z]+-)?transition-property
518 |
519 | BY_NAME
520 |
521 |
522 |
523 | (-[a-z]+-)?transform
524 |
525 | BY_NAME
526 |
527 |
528 |
529 | (-[a-z]+-)?transform-origin
530 |
531 | BY_NAME
532 |
533 |
534 |
535 | (-[a-z]+-)?animation
536 |
537 | BY_NAME
538 |
539 |
540 |
541 | (-[a-z]+-)?animation-name
542 |
543 | BY_NAME
544 |
545 |
546 |
547 | (-[a-z]+-)?animation-duration
548 |
549 | BY_NAME
550 |
551 |
552 |
553 | (-[a-z]+-)?animation-play-state
554 |
555 | BY_NAME
556 |
557 |
558 |
559 | (-[a-z]+-)?animation-timing-function
560 |
561 | BY_NAME
562 |
563 |
564 |
565 | (-[a-z]+-)?animation-delay
566 |
567 | BY_NAME
568 |
569 |
570 |
571 | (-[a-z]+-)?animation-iteration-count
572 |
573 | BY_NAME
574 |
575 |
576 |
577 | (-[a-z]+-)?animation-direction
578 |
579 | BY_NAME
580 |
581 |
582 |
583 | (-[a-z]+-)?text-align
584 |
585 | BY_NAME
586 |
587 |
588 |
589 | (-[a-z]+-)?text-align-last
590 |
591 | BY_NAME
592 |
593 |
594 |
595 | (-[a-z]+-)?vertical-align
596 |
597 | BY_NAME
598 |
599 |
600 |
601 | (-[a-z]+-)?white-space
602 |
603 | BY_NAME
604 |
605 |
606 |
607 | (-[a-z]+-)?text-decoration
608 |
609 | BY_NAME
610 |
611 |
612 |
613 | (-[a-z]+-)?text-emphasis
614 |
615 | BY_NAME
616 |
617 |
618 |
619 | (-[a-z]+-)?text-emphasis-color
620 |
621 | BY_NAME
622 |
623 |
624 |
625 | (-[a-z]+-)?text-emphasis-style
626 |
627 | BY_NAME
628 |
629 |
630 |
631 | (-[a-z]+-)?text-emphasis-position
632 |
633 | BY_NAME
634 |
635 |
636 |
637 | (-[a-z]+-)?text-indent
638 |
639 | BY_NAME
640 |
641 |
642 |
643 | (-[a-z]+-)?text-justify
644 |
645 | BY_NAME
646 |
647 |
648 |
649 | (-[a-z]+-)?letter-spacing
650 |
651 | BY_NAME
652 |
653 |
654 |
655 | (-[a-z]+-)?word-spacing
656 |
657 | BY_NAME
658 |
659 |
660 |
661 | (-[a-z]+-)?text-outline
662 |
663 | BY_NAME
664 |
665 |
666 |
667 | (-[a-z]+-)?text-transform
668 |
669 | BY_NAME
670 |
671 |
672 |
673 | (-[a-z]+-)?text-wrap
674 |
675 | BY_NAME
676 |
677 |
678 |
679 | (-[a-z]+-)?text-overflow
680 |
681 | BY_NAME
682 |
683 |
684 |
685 | (-[a-z]+-)?text-overflow-ellipsis
686 |
687 | BY_NAME
688 |
689 |
690 |
691 | (-[a-z]+-)?text-overflow-mode
692 |
693 | BY_NAME
694 |
695 |
696 |
697 | (-[a-z]+-)?word-wrap
698 |
699 | BY_NAME
700 |
701 |
702 |
703 | (-[a-z]+-)?word-break
704 |
705 | BY_NAME
706 |
707 |
708 |
709 | (-[a-z]+-)?tab-size
710 |
711 | BY_NAME
712 |
713 |
714 |
715 | (-[a-z]+-)?hyphens
716 |
717 | BY_NAME
718 |
719 |
720 |
721 | (-[a-z]+-)?pointer-events
722 |
723 | BY_NAME
724 |
725 |
726 |
727 | (-[a-z]+-)?opacity
728 |
729 | BY_NAME
730 |
731 |
732 |
733 | (-[a-z]+-)?color
734 |
735 | BY_NAME
736 |
737 |
738 |
739 | (-[a-z]+-)?border
740 |
741 | BY_NAME
742 |
743 |
744 |
745 | (-[a-z]+-)?border-width
746 |
747 | BY_NAME
748 |
749 |
750 |
751 | (-[a-z]+-)?border-style
752 |
753 | BY_NAME
754 |
755 |
756 |
757 | (-[a-z]+-)?border-color
758 |
759 | BY_NAME
760 |
761 |
762 |
763 | (-[a-z]+-)?border-top
764 |
765 | BY_NAME
766 |
767 |
768 |
769 | (-[a-z]+-)?border-top-width
770 |
771 | BY_NAME
772 |
773 |
774 |
775 | (-[a-z]+-)?border-top-style
776 |
777 | BY_NAME
778 |
779 |
780 |
781 | (-[a-z]+-)?border-top-color
782 |
783 | BY_NAME
784 |
785 |
786 |
787 | (-[a-z]+-)?border-right
788 |
789 | BY_NAME
790 |
791 |
792 |
793 | (-[a-z]+-)?border-right-width
794 |
795 | BY_NAME
796 |
797 |
798 |
799 | (-[a-z]+-)?border-right-style
800 |
801 | BY_NAME
802 |
803 |
804 |
805 | (-[a-z]+-)?border-right-color
806 |
807 | BY_NAME
808 |
809 |
810 |
811 | (-[a-z]+-)?border-bottom
812 |
813 | BY_NAME
814 |
815 |
816 |
817 | (-[a-z]+-)?border-bottom-width
818 |
819 | BY_NAME
820 |
821 |
822 |
823 | (-[a-z]+-)?border-bottom-style
824 |
825 | BY_NAME
826 |
827 |
828 |
829 | (-[a-z]+-)?border-bottom-color
830 |
831 | BY_NAME
832 |
833 |
834 |
835 | (-[a-z]+-)?border-left
836 |
837 | BY_NAME
838 |
839 |
840 |
841 | (-[a-z]+-)?border-left-width
842 |
843 | BY_NAME
844 |
845 |
846 |
847 | (-[a-z]+-)?border-left-style
848 |
849 | BY_NAME
850 |
851 |
852 |
853 | (-[a-z]+-)?border-left-color
854 |
855 | BY_NAME
856 |
857 |
858 |
859 | (-[a-z]+-)?border-radius
860 |
861 | BY_NAME
862 |
863 |
864 |
865 | (-[a-z]+-)?border-top-left-radius
866 |
867 | BY_NAME
868 |
869 |
870 |
871 | (-[a-z]+-)?border-top-right-radius
872 |
873 | BY_NAME
874 |
875 |
876 |
877 | (-[a-z]+-)?border-bottom-right-radius
878 |
879 | BY_NAME
880 |
881 |
882 |
883 | (-[a-z]+-)?border-bottom-left-radius
884 |
885 | BY_NAME
886 |
887 |
888 |
889 | (-[a-z]+-)?border-image
890 |
891 | BY_NAME
892 |
893 |
894 |
895 | (-[a-z]+-)?border-image-source
896 |
897 | BY_NAME
898 |
899 |
900 |
901 | (-[a-z]+-)?border-image-slice
902 |
903 | BY_NAME
904 |
905 |
906 |
907 | (-[a-z]+-)?border-image-width
908 |
909 | BY_NAME
910 |
911 |
912 |
913 | (-[a-z]+-)?border-image-outset
914 |
915 | BY_NAME
916 |
917 |
918 |
919 | (-[a-z]+-)?border-image-repeat
920 |
921 | BY_NAME
922 |
923 |
924 |
925 | (-[a-z]+-)?outline
926 |
927 | BY_NAME
928 |
929 |
930 |
931 | (-[a-z]+-)?outline-width
932 |
933 | BY_NAME
934 |
935 |
936 |
937 | (-[a-z]+-)?outline-style
938 |
939 | BY_NAME
940 |
941 |
942 |
943 | (-[a-z]+-)?outline-color
944 |
945 | BY_NAME
946 |
947 |
948 |
949 | (-[a-z]+-)?outline-offset
950 |
951 | BY_NAME
952 |
953 |
954 |
955 | (-[a-z]+-)?background
956 |
957 | BY_NAME
958 |
959 |
960 |
961 | (-[a-z]+-)?background-color
962 |
963 | BY_NAME
964 |
965 |
966 |
967 | (-[a-z]+-)?background-image
968 |
969 | BY_NAME
970 |
971 |
972 |
973 | (-[a-z]+-)?background-repeat
974 |
975 | BY_NAME
976 |
977 |
978 |
979 | (-[a-z]+-)?background-attachment
980 |
981 | BY_NAME
982 |
983 |
984 |
985 | (-[a-z]+-)?background-position
986 |
987 | BY_NAME
988 |
989 |
990 |
991 | (-[a-z]+-)?background-position-x
992 |
993 | BY_NAME
994 |
995 |
996 |
997 | (-[a-z]+-)?background-position-y
998 |
999 | BY_NAME
1000 |
1001 |
1002 |
1003 | (-[a-z]+-)?background-clip
1004 |
1005 | BY_NAME
1006 |
1007 |
1008 |
1009 | (-[a-z]+-)?background-origin
1010 |
1011 | BY_NAME
1012 |
1013 |
1014 |
1015 | (-[a-z]+-)?background-size
1016 |
1017 | BY_NAME
1018 |
1019 |
1020 |
1021 | (-[a-z]+-)?box-decoration-break
1022 |
1023 | BY_NAME
1024 |
1025 |
1026 |
1027 | (-[a-z]+-)?box-shadow
1028 |
1029 | BY_NAME
1030 |
1031 |
1032 |
1033 | (-[a-z]+-)?text-shadow
1034 |
1035 | BY_NAME
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1055 |
1056 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/sonarlint/issuestore/index.pb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pub-technology/aws-development-with-localstack/ffbfcb15ed4313928c10c052a2ecf8d86f063d79/.idea/sonarlint/issuestore/index.pb
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "trailingComma": "all",
4 | "singleQuote": true,
5 | "printWidth": 120,
6 | "tabWidth": 2
7 | }
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 haithai91
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AWS CDK & Localstack (Local Development)
2 |
3 | 
4 |
5 | ## A few benefits of this approach are
6 | - You can run the lambda function locally
7 | - Don’t impact your team by sharing the same env ( update on the same buckets, same records )
8 | - Debug & Speed up your working
9 | - Don’t need to worry about paying for AWS usage for stupid action 🥰
10 |
11 |
12 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
13 |
14 | ## Useful commands
15 |
16 | * `yarn build` compile typescript to js
17 | * `yarn lint` check code style
18 | * `yarn destroy` destroy the current stack
19 | * `yarn deploy` deploy this stack to your default AWS account/region
20 | * `yarn bootstrap` clean up env
21 |
22 |
23 | ## Install & Setup LocalStack
24 | 1. Install Docker if you haven’t already.
25 | https://docs.docker.com/get-docker/
26 | 2. Install AWS CLI. While we won’t be working with “real” AWS
27 | we will be using it to communicate with our local docker containers.
28 | https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
29 |
30 | ## Install AWS CDK Local
31 |
32 | Avoid the mistake when we use `cdk` command maybe it can impact to real environment
33 | This lib provides a thin wrapper script cdklocal for using the AWS CDK library against local APIs provided by LocalStack.
34 | Refer : https://github.com/localstack/aws-cdk-local
35 |
36 | ```shell
37 | npm install -g aws-cdk-local aws-cdk
38 | ```
39 |
40 |
41 | Or yarn
42 |
43 | ```shell
44 | yarn global add aws-cdk-local aws-cdk
45 | ```
46 |
47 | $ cdklocal --version
48 | 1.65.5
49 |
50 |
51 |
52 | # Start Localstack & Deploy our services
53 |
54 | ### Step 1. init create a fake aws credentials - use for our localstack as below ( This is required for our localstack )
55 | ```shell
56 | cat ~/.aws/credentials
57 |
58 | [default]
59 | aws_access_key_id = test
60 | aws_secret_access_key = test
61 | region = us-west-2
62 | output = json
63 | ```
64 |
65 | ### Step 2. `cd to localstack` folder and run the command `docker-compose up -d`
66 |
67 | #### Open browser check our service `http://localhost:4566/health`
68 | ```json
69 | {
70 | "services": {
71 | "dynamodbstreams": "running",
72 | "firehose": "running",
73 | "kinesis": "running",
74 | "s3": "running",
75 | "ses": "running",
76 | "sns": "running",
77 | "sqs": "running",
78 | "dynamodb": "running"
79 | }, "features": {"persistence": "initialized", "initScripts": "initialized"}
80 | }
81 | ```
82 |
83 | #### Check your `memcached` was run successfully :check_mark:
84 |
85 | ```
86 | # telnet the to port 11211
87 | telnet localhost 11211
88 |
89 | # Add a new key to memcache
90 | set Customer_Id 0 900 5
91 | # Type your value ( Enter - A message STORED will be displayed)
92 | 00-000-000
93 | STORED
94 | # Recheck by get your key stored
95 | get Customer_Id
96 | 00-000-000
97 | # exit telnet
98 | quit
99 | ```
100 |
101 | #### Check your `Redis` was run successfully :check_mark:
102 | Install Redis Client ( Add connection )
103 |
104 | #### Windows
105 | Download latest https://github.com/qishibo/AnotherRedisDesktopManager/releases package from https://github.com/qishibo/AnotherRedisDesktopManager/releases [or gitee in China], double click to install.
106 |
107 | Or by winget: winget install qishibo.AnotherRedisDesktopManager
108 |
109 | #### Mac
110 | Download latest https://github.com/qishibo/AnotherRedisDesktopManager/releases package from release [or gitee in China], double click to install.
111 |
112 | Or by brew: brew install --cask another-redis-desktop-manager
113 |
114 |
115 |
116 | ### Step 3. Deploy our Application Stack
117 |
118 | ```shell
119 | yarn deploy
120 | ```
121 |
122 | ```markdown
123 | IAM Statement Changes ...
124 | ┌───┬───────────────────────┬────────┬─────────────────┬───────────────────────────┬───────────────────────────────────────────────────────┐
125 | │ │ Resource │ Effect │ Action │ Principal │ Condition │
126 | ├───┼───────────────────────┼────────┼─────────────────┼───────────────────────────┼───────────────────────────────────────────────────────┤
127 | │ + │ ${SampleAppQueue.Arn} │ Allow │ sqs:SendMessage │ Service:sns.amazonaws.com │ "ArnEquals": { │
128 | │ │ │ │ │ │ "aws:SourceArn": "${SampleAppTopic}" │
129 | │ │ │ │ │ │ } │
130 | └───┴───────────────────────┴────────┴─────────────────┴───────────────────────────┴───────────────────────────────────────────────────────┘
131 | (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
132 |
133 | Do you wish to deploy these changes (y/n)?
134 |
135 | #### Type `y` and see our stack
136 |
137 | ApplicationStack: deploying...
138 | ApplicationStack: creating CloudFormation changeset...
139 |
140 |
141 | ✅ ApplicationStack
142 |
143 | Stack ARN:
144 | arn:aws:cloudformation:us-west-2:000000000000:stack/ApplicationStack/e67d04e2
145 | ```
146 |
147 | ### Step 4. Quick check our deployment S3 & Dynamo DB Tables
148 | #### DynamoDB
149 | ```shell
150 | aws --endpoint-url=http://localhost:4566 dynamodb list-tables
151 |
152 | {
153 | "TableNames": [
154 | "test-development"
155 | ]
156 | }
157 |
158 | aws --endpoint-url=http://localhost:4566 dynamodb describe-table --table-name test-development
159 | ```
160 |
161 | ## Useful Tools ( How to use it )
162 | | Tool | Description |
163 | | ----------- | ----------- |
164 | | S3 Viewer (MAC & Win)
https://cyberduck.io/ |  |
165 | | DynamoDB Viewer (MAC & Win)
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html |  |
166 | | SQS Sender
https://github.com/kobee-tech-stack/sqs-viewer |
167 | | Redis Viewer (MAC & Win)
https://github.com/qishibo/AnotherRedisDesktopManager | ... |
168 |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/bin/app.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import * as cdk from '@aws-cdk/core';
3 | import {ApplicationStack} from '../lib/ApplicationStack';
4 |
5 | const app = new cdk.App();
6 | new ApplicationStack(app, 'ApplicationStack', {
7 | env: {
8 | region: 'us-west-2'
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node --prefer-ts-exts bin/app.ts",
3 | "context": {
4 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
5 | "@aws-cdk/core:enableStackNameDuplicates": "true",
6 | "aws-cdk:enableDiffNoFail": "true",
7 | "@aws-cdk/core:stackRelativeExports": "true",
8 | "@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true,
9 | "@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true,
10 | "@aws-cdk/aws-kms:defaultKeyPolicies": true,
11 | "@aws-cdk/aws-s3:grantWriteWithoutAcl": true,
12 | "@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true,
13 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
14 | "@aws-cdk/aws-efs:defaultEncryptionAtRest": true,
15 | "@aws-cdk/aws-lambda:recognizeVersionProps": true,
16 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'node',
3 | roots: ['/test'],
4 | testMatch: ['**/*.test.ts'],
5 | transform: {
6 | '^.+\\.tsx?$': 'ts-jest'
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/lib/ApplicationStack.ts:
--------------------------------------------------------------------------------
1 | import * as cdk from "@aws-cdk/core";
2 | import {initDynamoDB} from "./dynamodb";
3 | import {initS3Buckets} from "./s3";
4 | import {initFirehose} from "./firehose";
5 | import {initSQS} from './sqs';
6 |
7 | /**
8 | * This is Application Stack
9 | * Create DynamoDB , S3, FireHose, SQS services support for local development.
10 | */
11 | export class ApplicationStack extends cdk.Stack {
12 | constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
13 | super(scope, id, props);
14 |
15 | // Dynamo DB initialize
16 | initDynamoDB(this);
17 |
18 | // S3 Initialize
19 | initS3Buckets(this);
20 |
21 | // Firehose Initialize
22 | initFirehose(this);
23 |
24 | // SQS Initialize
25 | initSQS(this);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/dynamodb/index.ts:
--------------------------------------------------------------------------------
1 | import { generateTestDevelopmentTable } from './test-development';
2 | import { Stack } from '@aws-cdk/core';
3 |
4 | export const initDynamoDB = (root: Stack): void => {
5 | // Test Development Table
6 | generateTestDevelopmentTable(root);
7 | };
8 |
--------------------------------------------------------------------------------
/lib/dynamodb/test-development.ts:
--------------------------------------------------------------------------------
1 | import * as dynamodb from "@aws-cdk/aws-dynamodb";
2 | import {GlobalSecondaryIndexProps, StreamViewType} from "@aws-cdk/aws-dynamodb/lib/table";
3 | import {createStandardGSI} from "../../utils/createGlobalSecondaryIndex";
4 | import {Stack} from "@aws-cdk/core"
5 |
6 | export const generateTestDevelopmentTable = (root: Stack): dynamodb.Table => {
7 | const testDevelopmentTable = new dynamodb.Table(root, 'Table', {
8 | tableName: 'test-development',
9 | // partition key & sort key
10 | partitionKey: {name: 'pk', type: dynamodb.AttributeType.STRING},
11 | sortKey: {name: 'sk', type: dynamodb.AttributeType.STRING},
12 | // ProvisionedThroughput
13 | readCapacity: 5,
14 | writeCapacity: 5,
15 | // StreamSpecification
16 | stream: StreamViewType.NEW_AND_OLD_IMAGES,
17 | });
18 |
19 | const pk2Sk2Index: GlobalSecondaryIndexProps = createStandardGSI('pk2-sk2-index', 'pk2', 'sk2');
20 | const pk3Sk3Index: GlobalSecondaryIndexProps = createStandardGSI('pk3-sk3-index', 'pk3', 'sk3');
21 | const pk4Sk4Index: GlobalSecondaryIndexProps = createStandardGSI('pk4-sk4-index', 'pk4', 'sk4');
22 |
23 | testDevelopmentTable.addGlobalSecondaryIndex(pk2Sk2Index);
24 | testDevelopmentTable.addGlobalSecondaryIndex(pk3Sk3Index);
25 | testDevelopmentTable.addGlobalSecondaryIndex(pk4Sk4Index);
26 |
27 | return testDevelopmentTable;
28 | }
29 |
--------------------------------------------------------------------------------
/lib/firehose/index.ts:
--------------------------------------------------------------------------------
1 | import {Stack} from "@aws-cdk/core";
2 | import {generateTestFirehose} from "./test-firehose";
3 | import * as iam from "@aws-cdk/aws-iam";
4 |
5 | export const initFirehose = (root: Stack): void => {
6 | const safetyCheckFirehoseRole = new iam.Role(root, 'safety-check-firehose-role', {
7 | assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com')
8 | });
9 |
10 | generateTestFirehose(root, safetyCheckFirehoseRole);
11 | }
12 |
--------------------------------------------------------------------------------
/lib/firehose/test-firehose.ts:
--------------------------------------------------------------------------------
1 | import * as s3 from '@aws-cdk/aws-s3';
2 | import {Duration, RemovalPolicy, Size, Stack} from "@aws-cdk/core";
3 | import {CfnDeliveryStream} from "@aws-cdk/aws-kinesisfirehose";
4 | import {Role} from '@aws-cdk/aws-iam';
5 |
6 | export const generateTestFirehose = (root: Stack, firehoseRole: Role): CfnDeliveryStream => {
7 | // S3 bucket that will serve as the destination for our raw compressed data
8 | const auditLogBucket = new s3.Bucket(root, "test-firehose-s3-bucket", {
9 | removalPolicy: RemovalPolicy.DESTROY, // REMOVE FOR PRODUCTION
10 | autoDeleteObjects: true, // REMOVE FOR PRODUCTION,
11 | bucketName: 'test-firehose-s3',
12 | publicReadAccess: true,
13 | });
14 |
15 | return new CfnDeliveryStream(root, "FirehoseStreamToS", {
16 | deliveryStreamName: "test-firehose-delivery-stream",
17 | deliveryStreamType: "DirectPut",
18 | s3DestinationConfiguration: {
19 | bucketArn: auditLogBucket.bucketArn,
20 | bufferingHints: {
21 | sizeInMBs: Size.mebibytes(1).toMebibytes(),
22 | intervalInSeconds: Duration.seconds(60).toSeconds()
23 | },
24 | compressionFormat: 'UNCOMPRESSED',
25 | encryptionConfiguration: {
26 | noEncryptionConfig: "NoEncryption"
27 | },
28 | prefix: "user-logs",
29 | errorOutputPrefix: 'user-error-logs',
30 | roleArn: firehoseRole.roleArn
31 | },
32 | });
33 | }
34 |
--------------------------------------------------------------------------------
/lib/iam/firehose_skeleton.json:
--------------------------------------------------------------------------------
1 | {
2 | "DeliveryStreamName": "s3-stream-1",
3 | "DeliveryStreamType": "DirectPut",
4 | "S3DestinationConfiguration": {
5 | "RoleARN": "arn:aws:iam::000000000000:role/super-role",
6 | "BucketARN": "arn:aws:s3:::test-firehose-s3",
7 | "Prefix": "test-log",
8 | "ErrorOutputPrefix": "test-error-log",
9 | "BufferingHints": {
10 | "SizeInMBs": 1,
11 | "IntervalInSeconds": 60
12 | },
13 | "CompressionFormat": "UNCOMPRESSED",
14 | "CloudWatchLoggingOptions": {
15 | "Enabled": false,
16 | "LogGroupName": "",
17 | "LogStreamName": ""
18 | }
19 | },
20 | "Tags": [
21 | {
22 | "Key": "tagKey",
23 | "Value": "tagValue"
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/lib/iam/super-role.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "Stmt1572416334166",
6 | "Action": "*",
7 | "Effect": "Allow",
8 | "Resource": "*"
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/lib/iam/super-role.ts:
--------------------------------------------------------------------------------
1 | import {Effect, Group, ManagedPolicy, PolicyStatement, User} from '@aws-cdk/aws-iam';
2 | import {Stack} from "@aws-cdk/core";
3 |
4 | export const generateSuperRole = (root: Stack): User => {
5 | // 👇 Create group
6 | const group = new Group(root, 'admin-group', {
7 | managedPolicies: [
8 | ManagedPolicy.fromAwsManagedPolicyName('*'),
9 | ],
10 | });
11 |
12 | // 👇 Create Managed Policy
13 | const allManagedPolicy = ManagedPolicy.fromAwsManagedPolicyName(
14 | '*',
15 | );
16 |
17 | // 👇 Create Permissions Boundary
18 | const permissionsBoundary = new ManagedPolicy(
19 | root,
20 | 'admin-role-permissions',
21 | {
22 | statements: [
23 | new PolicyStatement({
24 | effect: Effect.ALLOW,
25 | actions: ['*'],
26 | resources: ['*'],
27 | }),
28 | ],
29 | },
30 | );
31 |
32 | // 👇 Create User
33 | const user: User = new User(root, 'super-role', {
34 | userName: 'administrator',
35 | managedPolicies: [allManagedPolicy],
36 | groups: [group],
37 | permissionsBoundary,
38 | });
39 |
40 | console.log('Super Admin : ', user.userArn);
41 | return user;
42 | }
43 |
--------------------------------------------------------------------------------
/lib/s3/index.ts:
--------------------------------------------------------------------------------
1 | import {Stack} from "@aws-cdk/core";
2 | import {generateScreenShotBucket} from "./screenshot";
3 |
4 | export const initS3Buckets = (root: Stack): void => {
5 | generateScreenShotBucket(root);
6 | }
7 |
--------------------------------------------------------------------------------
/lib/s3/screenshot.ts:
--------------------------------------------------------------------------------
1 | import * as s3 from '@aws-cdk/aws-s3';
2 | import { Stack } from '@aws-cdk/core';
3 |
4 | export const generateScreenShotBucket = (root: Stack): s3.Bucket => {
5 | return new s3.Bucket(root, 'screen-shot', {
6 | bucketName: 'screenshot',
7 | // https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html
8 | encryption: s3.BucketEncryption.S3_MANAGED,
9 | versioned: false,
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/lib/sqs/index.ts:
--------------------------------------------------------------------------------
1 | import {Stack} from "@aws-cdk/core";
2 |
3 | import { generateSimpleSQS } from "./simple-sqs-development";
4 |
5 | export const initSQS = (root: Stack): void => {
6 | generateSimpleSQS(root);
7 | }
8 |
--------------------------------------------------------------------------------
/lib/sqs/simple-sqs-development.ts:
--------------------------------------------------------------------------------
1 | import * as sqs from '@aws-cdk/aws-sqs';
2 | import {RemovalPolicy, Stack} from "@aws-cdk/core";
3 |
4 | export const generateSimpleSQS = (root: Stack): sqs.Queue => {
5 | // 👇 create queue
6 | return new sqs.Queue(root, 'simple-sqs', {
7 | queueName: 'simple-sqs-development',
8 | encryption: sqs.QueueEncryption.UNENCRYPTED,
9 | fifo: false,
10 | removalPolicy: RemovalPolicy.DESTROY
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/localstack/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 |
3 | services:
4 | memcached:
5 | container_name: aws_memcached
6 | image: bitnami/memcached:latest
7 | network_mode: bridge
8 | ports:
9 | - "11211:11211"
10 | environment:
11 | - MEMCACHED_CACHE_SIZE=128
12 | redis:
13 | container_name: aws_redis
14 | image: bitnami/redis:latest
15 | network_mode: bridge
16 | ports:
17 | - "6379:6379"
18 | environment:
19 | - ALLOW_EMPTY_PASSWORD=yes
20 | volumes:
21 | - './.redis-persistence:/bitnami/redis/data'
22 | localstack:
23 | container_name: AWS-DEVELOPMENT-WITH-LOCALSTACK
24 | image: localstack/localstack:latest
25 | network_mode: bridge
26 | ports:
27 | - "127.0.0.1:53:53"
28 | - "127.0.0.1:53:53/udp"
29 | - "127.0.0.1:443:443"
30 | - "127.0.0.1:4566:4566"
31 | - "127.0.0.1:4571:4571"
32 | environment:
33 | - SERVICES=apigateway,s3,dynamodb,sns,sqs,firehose,kinesis,ses,sts,cloudformation,iam,lambda
34 | - DEBUG=1
35 | - DATA_DIR=/tmp/localstack/data
36 | - PORT_WEB_UI=8080
37 | - DEFAULT_REGION=us-west-2
38 | - LAMBDA_EXECUTOR=local
39 | - KINESIS_ERROR_PROBABILITY=1.0
40 | - DOCKER_HOST=unix:///var/run/docker.sock
41 | - HOST_TMP_FOLDER=./.localstack
42 | volumes:
43 | - './.localstack:/tmp/localstack'
44 | - '/var/run/docker.sock:/var/run/docker.sock'
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-development-with-localstack",
3 | "version": "0.1.0",
4 | "bin": {
5 | "app": "bin/app.js"
6 | },
7 | "scripts": {
8 | "build": "tsc",
9 | "watch": "tsc -w",
10 | "test": "jest",
11 | "lint": "eslint lib/**/*.ts",
12 | "format": "eslint lib/**/*.ts --fix",
13 | "cdk": "cdklocal",
14 | "deploy": "cdklocal deploy",
15 | "bootstrap": "cdklocal bootstrap aws://unknown-account/us-west-2",
16 | "destroy": "cdklocal destroy",
17 | "seed": "npx ts-node seed/index.ts",
18 | "migrate": "npx ts-node scripts/migrationModels/migrationScript.ts"
19 | },
20 | "devDependencies": {
21 | "@aws-cdk/assert": "1.117.0",
22 | "@types/jest": "^26.0.10",
23 | "@types/node": "10.17.27",
24 | "@typescript-eslint/eslint-plugin": "^4.31.2",
25 | "@typescript-eslint/parser": "^4.31.2",
26 | "@types/lodash": "^4.14.175",
27 | "aws-cdk": "^1.124.0",
28 | "eslint": "^7.32.0",
29 | "jest": "^26.4.2",
30 | "prettier": "^2.4.1",
31 | "ts-jest": "^26.2.0",
32 | "ts-node": "^9.0.0",
33 | "typescript": "~3.9.7",
34 | "husky": "^7.0.2"
35 | },
36 | "dependencies": {
37 | "@aws-cdk/aws-dynamodb": "1.117.0",
38 | "@aws-cdk/aws-iam": "1.117.0",
39 | "@aws-cdk/aws-kinesis": "1.117.0",
40 | "@aws-cdk/aws-kinesisfirehose": "1.117.0",
41 | "@aws-cdk/aws-kinesisfirehose-destinations": "1.117.0",
42 | "@aws-cdk/aws-s3": "1.117.0",
43 | "@aws-cdk/aws-sns": "1.117.0",
44 | "@aws-cdk/aws-sns-subscriptions": "1.117.0",
45 | "@aws-cdk/aws-sqs": "1.117.0",
46 | "@aws-cdk/core": "1.117.0",
47 | "@aws-sdk/client-dynamodb": "^3.32.0",
48 | "@aws-sdk/util-dynamodb": "^3.32.0",
49 | "lodash": "^4.17.21",
50 | "axios": "^0.22.0"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/scripts/config.ts:
--------------------------------------------------------------------------------
1 | const config = {
2 | endpoint: process.env.MIGRATION_SEED_APP_CONFIG_ENDPOINT || "http://localhost:4566",
3 | region: process.env.MIGRATION_SEED_APP_CONFIG_REGION || "us-west-2",
4 | };
5 |
6 | export default config;
7 |
--------------------------------------------------------------------------------
/scripts/migrationModels/migrationScript.ts:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
4 | import appConfig from "../config";
5 |
6 | const migrationScript = async () => {
7 | const client = new DynamoDBClient({
8 | endpoint: appConfig.endpoint,
9 | region: appConfig.region
10 | });
11 |
12 | console.log("Migrate Data : Done");
13 | };
14 |
15 | (async function main() {
16 | await migrationScript();
17 | console.log(`
18 | Migrate development data to local was run successfully.
19 | `);
20 | })();
21 |
--------------------------------------------------------------------------------
/seed/config.ts:
--------------------------------------------------------------------------------
1 | const seedAppConfig = {
2 | endpoint: process.env.SEED_APP_CONFIG_ENDPOINT || 'http://localhost:4566',
3 | region: process.env.SEED_APP_CONFIG_REGION || 'us-west-2'
4 | }
5 |
6 | export default seedAppConfig;
7 |
--------------------------------------------------------------------------------
/seed/index.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
4 |
5 | import seedAppConfig from "./config";
6 |
7 | const seedData = async () => {
8 | const client = new DynamoDBClient({
9 | endpoint: seedAppConfig.endpoint,
10 | region: seedAppConfig.region
11 | });
12 | console.log('Seed Data : Done');
13 | }
14 |
15 | (async function main() {
16 | await seedData();
17 | console.log(`
18 | Seed global data was run successfully.
19 | `);
20 | })();
21 |
--------------------------------------------------------------------------------
/test/app.test.ts:
--------------------------------------------------------------------------------
1 | import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
2 | import * as cdk from '@aws-cdk/core';
3 | import * as App from '../lib/ApplicationStack';
4 |
5 | test('SQS Queue Created', () => {
6 | const app = new cdk.App();
7 | // WHEN
8 | const stack = new App.ApplicationStack(app, 'MyTestStack');
9 | // THEN
10 | expectCDK(stack).to(haveResource("AWS::SQS::Queue",{
11 | VisibilityTimeout: 300
12 | }));
13 | });
14 |
15 | test('SNS Topic Created', () => {
16 | const app = new cdk.App();
17 | // WHEN
18 | const stack = new App.ApplicationStack(app, 'MyTestStack');
19 | // THEN
20 | expectCDK(stack).to(haveResource("AWS::SNS::Topic"));
21 | });
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "commonjs",
5 | "lib": [
6 | "es2018"
7 | ],
8 | "declaration": true,
9 | "strict": true,
10 | "noImplicitAny": true,
11 | "strictNullChecks": true,
12 | "noImplicitThis": true,
13 | "alwaysStrict": true,
14 | "noUnusedLocals": false,
15 | "noUnusedParameters": false,
16 | "noImplicitReturns": true,
17 | "noFallthroughCasesInSwitch": false,
18 | "inlineSourceMap": true,
19 | "inlineSources": true,
20 | "experimentalDecorators": true,
21 | "strictPropertyInitialization": false,
22 | "typeRoots": [
23 | "./node_modules/@types"
24 | ],
25 | "allowSyntheticDefaultImports": true,
26 | "esModuleInterop": true
27 | },
28 | "exclude": [
29 | "node_modules",
30 | "cdk.out"
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/utils/createGlobalSecondaryIndex.ts:
--------------------------------------------------------------------------------
1 | import { AttributeType, ProjectionType, GlobalSecondaryIndexProps } from "@aws-cdk/aws-dynamodb";
2 |
3 | /**
4 | * Default pk & sk is attr type is STRING & read/write capacity is 5.
5 | * @param indexName
6 | * @param pkName
7 | * @param skName
8 | */
9 | export const createStandardGSI = (indexName: string, pkName: string, skName: string) : GlobalSecondaryIndexProps => {
10 | return {
11 | indexName,
12 | partitionKey: { name: pkName, type: AttributeType.STRING },
13 | sortKey: { name: skName, type: AttributeType.STRING },
14 | projectionType: ProjectionType.ALL,
15 | };
16 | }
17 |
--------------------------------------------------------------------------------