├── .gitignore ├── LICENSE.md ├── Pipfile ├── Pipfile.lock ├── README.md ├── backend ├── __init__.py └── main.py ├── docker ├── api │ └── Dockerfile └── docker-compose.yml └── stacks ├── .gitignore ├── app.py ├── cdk.context.json ├── cdk.json └── cdk ├── __init__.py ├── ecr_stack.py └── ecs_stack.py /.gitignore: -------------------------------------------------------------------------------- 1 | # CDK asset staging directory 2 | .cdk.staging 3 | cdk.out 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | # pytype static type analyzer 139 | .pytype/ 140 | 141 | # Cython debug symbols 142 | cython_debug/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright (c) 2020 Sintaro 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | aws-cdk-core = "*" 8 | aws-cdk-aws-ecr = "*" 9 | aws-cdk-aws-ec2 = "*" 10 | aws-cdk-aws-ecs = "*" 11 | aws-cdk-aws-ecs-patterns = "*" 12 | aws-cdk-aws-iam = "*" 13 | python-dotenv = "*" 14 | 15 | [packages] 16 | starlette = "*" 17 | fastapi = "*" 18 | uvicorn = "*" 19 | 20 | [requires] 21 | python_version = "3.8" 22 | 23 | [scripts] 24 | start = "bash -c 'cd backend && uvicorn main:api --reload --host 0.0.0.0 --port ${PORT}'" 25 | docker_build = "docker build -t ${REPOSITORY_IMAGE} -f docker/api/Dockerfile ." 26 | docker_run = "docker run -p ${PORT}:${PORT} ${REPOSITORY_IMAGE}" 27 | docker_compose_up = "docker-compose -f docker/docker-compose.yml up" 28 | ecr_login = "bash -c 'aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_IMAGE}'" 29 | tagged_image="bash -c 'docker tag ${REPOSITORY_IMAGE} ${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_IMAGE}:latest'" 30 | push_to_ecr="bash -c 'docker push ${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com/${REPOSITORY_IMAGE}:latest'" 31 | deploy_image_ecr = "bash -c 'pipenv run tagged_image && pipenv run push_to_ecr'" 32 | deploy_ecr_stack = "bash -c 'cd stacks && cdk deploy ${ECR_STACK_NAME}'" 33 | deploy_ecs_stack = "bash -c 'cd stacks && cdk deploy ${ECS_STACK_NAME}'" 34 | cdk = "bash -c 'cd stacks'" 35 | cdk_ls = "bash -c 'cd stacks && cdk ls'" 36 | cdk_diff = "bash -c 'cd stacks && cdk diff'" 37 | cdk_doctor = "bash -c 'cd stacks && cdk doctor'" 38 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "40a15443ed550c0a14fa4d3377888839ed5ebf62d9850cd6d1ef8b071fd79731" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.8" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "click": { 20 | "hashes": [ 21 | "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", 22 | "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" 23 | ], 24 | "version": "==7.1.2" 25 | }, 26 | "fastapi": { 27 | "hashes": [ 28 | "sha256:1ee9a49f28d510b62b3b51a9452b274853bfc9c5d4b947ed054366e2d49f9efa", 29 | "sha256:72f40f47e5235cb5cbbad1d4f97932ede6059290c07e12e9784028dcd1063d28" 30 | ], 31 | "index": "pypi", 32 | "version": "==0.54.1" 33 | }, 34 | "h11": { 35 | "hashes": [ 36 | "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1", 37 | "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1" 38 | ], 39 | "version": "==0.9.0" 40 | }, 41 | "httptools": { 42 | "hashes": [ 43 | "sha256:07659649fe6b3948b6490825f89abe5eb1cec79ebfaaa0b4bf30f3f33f3c2ba8", 44 | "sha256:08b79e09114e6ab5c3dbf560bba2cb2257ea38cdaeaf99b7cb80d8f92622fcd9", 45 | "sha256:1e35aa179b67086cc600a984924a88589b90793c9c1b260152ca4908786e09df", 46 | "sha256:31629e1f1b89959f8c0927bad12184dc07977dcf71e24f4772934aa490aa199b", 47 | "sha256:851026bd63ec0af7e7592890d97d15c92b62d9e17094353f19a52c8e2b33710a", 48 | "sha256:8fcca4b7efe353b13a24017211334c57d055a6e132c7adffed13a10d28efca57", 49 | "sha256:9abd788465aa46a0f288bd3a99e53edd184177d6379e2098fd6097bb359ad9d6", 50 | "sha256:aebdf0bd7bf7c90ae6b3be458692bf6e9e5b610b501f9f74c7979015a51db4c4", 51 | "sha256:bda99a5723e7eab355ce57435c70853fc137a65aebf2f1cd4d15d96e2956da7b", 52 | "sha256:c1c63d860749841024951b0a78e4dec6f543d23751ef061d6ab60064c7b8b524", 53 | "sha256:c4111a0a8a00eff1e495d43ea5230aaf64968a48ddba8ea2d5f982efae827404", 54 | "sha256:dce59ee45dd6ee6c434346a5ac527c44014326f560866b4b2f414a692ee1aca8", 55 | "sha256:f759717ca1b2ef498c67ba4169c2b33eecf943a89f5329abcff8b89d153eb500", 56 | "sha256:fb7199b8fb0c50a22e77260bb59017e0c075fa80cb03bb2c8692de76e7bb7fe7", 57 | "sha256:fbf7ecd31c39728f251b1c095fd27c84e4d21f60a1d079a0333472ff3ae59d34" 58 | ], 59 | "markers": "sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'PyPy'", 60 | "version": "==0.1.2" 61 | }, 62 | "pydantic": { 63 | "hashes": [ 64 | "sha256:14e598055b65d2e6cedf10dc3de6ad1bb04ca3eec348e4af1cf5e5e496deab55", 65 | "sha256:1d42c7408cde8a224c2bb969bfb9dca21f3b1eec37a92044be8bcd7d35ea5826", 66 | "sha256:433dda6200104d7aa38c27a6ea52485e69931042556065402281cc73a57fd680", 67 | "sha256:51dec047b44f0de4dbfa301b73df605918088348b951b8b4616127249febfe30", 68 | "sha256:548c284237b0c61e0e785ad03167c75723f22000f82e8104d8981fdf50ce14e8", 69 | "sha256:60b8956b57045224294691b78a6a4be0f321271a9f1c2a7fef25248e4c4f20df", 70 | "sha256:6eea211e8b427841a16f43fa739ac06059db6af0d167476b928dbb237d870b77", 71 | "sha256:76b241172d6e22403e116e1d3b7305b6a9479323f8168f2fcb300ffe698443b9", 72 | "sha256:90310c1c5945b4fe2ff7bd69e306e54d192e55d22480657ddd6d2519cf2f12ba", 73 | "sha256:93f7f510fc366b99dace4a3d1f036aafcfe908092c5f2572ad4a96be24da199c", 74 | "sha256:ae48129396bd5acfaef1cdaaa959ac8ab5d02c026b1fdffb421dc6fa81d7861d", 75 | "sha256:be4e0263ef515ae14f06e9fb372843f00bdb218ec4f2f04beb3480ac1538a9a9", 76 | "sha256:bf9e5dd5e0e7e64541508f657c63bf6ab869109cb39f017f935acfeb64ea9be8", 77 | "sha256:cd777c102ba31bc9992093c2e9f778c21b3965566d1fa5ac9f9b7cea2e67fe2a", 78 | "sha256:d09adff1c70351a8750941dd39fda25447eab2e3cdb5b2aade340f69f6f53e84", 79 | "sha256:e77e5f640f1093bf417b841d9b4148bd4212bb0dbb2cbb9024aa07f2b3b260eb", 80 | "sha256:f6a1a465dd72aff0462486588a2bf905f9169e575deec1e6f6d00240fe1b4e00" 81 | ], 82 | "index": "pypi", 83 | "version": "==1.6.2" 84 | }, 85 | "starlette": { 86 | "hashes": [ 87 | "sha256:6169ee78ded501095d1dda7b141a1dc9f9934d37ad23196e180150ace2c6449b", 88 | "sha256:a9bb130fa7aa736eda8a814b6ceb85ccf7a209ed53843d0d61e246b380afa10f" 89 | ], 90 | "index": "pypi", 91 | "version": "==0.13.2" 92 | }, 93 | "uvicorn": { 94 | "hashes": [ 95 | "sha256:1d46a22cc55a52f5567e0c66f000ae56f26263e44cef59b7c885bf10f487ce6e", 96 | "sha256:b50f7f4c0c499c9b8d0280924cfbd24b90ba02456e3dc80934b9a786a291f09f" 97 | ], 98 | "index": "pypi", 99 | "version": "==0.11.7" 100 | }, 101 | "uvloop": { 102 | "hashes": [ 103 | "sha256:114543c84e95df1b4ff546e6e3a27521580466a30127f12172a3278172ad68bc", 104 | "sha256:19fa1d56c91341318ac5d417e7b61c56e9a41183946cc70c411341173de02c69", 105 | "sha256:2bb0624a8a70834e54dde8feed62ed63b50bad7a1265c40d6403a2ac447bce01", 106 | "sha256:42eda9f525a208fbc4f7cecd00fa15c57cc57646c76632b3ba2fe005004f051d", 107 | "sha256:44cac8575bf168601424302045234d74e3561fbdbac39b2b54cc1d1d00b70760", 108 | "sha256:6de130d0cb78985a5d080e323b86c5ecaf3af82f4890492c05981707852f983c", 109 | "sha256:7ae39b11a5f4cec1432d706c21ecc62f9e04d116883178b09671aa29c46f7a47", 110 | "sha256:90e56f17755e41b425ad19a08c41dc358fa7bf1226c0f8e54d4d02d556f7af7c", 111 | "sha256:b45218c99795803fb8bdbc9435ff7f54e3a591b44cd4c121b02fa83affb61c7c", 112 | "sha256:e5e5f855c9bf483ee6cd1eb9a179b740de80cb0ae2988e3fa22309b78e2ea0e7" 113 | ], 114 | "markers": "sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'PyPy'", 115 | "version": "==0.15.2" 116 | }, 117 | "websockets": { 118 | "hashes": [ 119 | "sha256:0e4fb4de42701340bd2353bb2eee45314651caa6ccee80dbd5f5d5978888fed5", 120 | "sha256:1d3f1bf059d04a4e0eb4985a887d49195e15ebabc42364f4eb564b1d065793f5", 121 | "sha256:20891f0dddade307ffddf593c733a3fdb6b83e6f9eef85908113e628fa5a8308", 122 | "sha256:295359a2cc78736737dd88c343cd0747546b2174b5e1adc223824bcaf3e164cb", 123 | "sha256:2db62a9142e88535038a6bcfea70ef9447696ea77891aebb730a333a51ed559a", 124 | "sha256:3762791ab8b38948f0c4d281c8b2ddfa99b7e510e46bd8dfa942a5fff621068c", 125 | "sha256:3db87421956f1b0779a7564915875ba774295cc86e81bc671631379371af1170", 126 | "sha256:3ef56fcc7b1ff90de46ccd5a687bbd13a3180132268c4254fc0fa44ecf4fc422", 127 | "sha256:4f9f7d28ce1d8f1295717c2c25b732c2bc0645db3215cf757551c392177d7cb8", 128 | "sha256:5c01fd846263a75bc8a2b9542606927cfad57e7282965d96b93c387622487485", 129 | "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f", 130 | "sha256:751a556205d8245ff94aeef23546a1113b1dd4f6e4d102ded66c39b99c2ce6c8", 131 | "sha256:7ff46d441db78241f4c6c27b3868c9ae71473fe03341340d2dfdbe8d79310acc", 132 | "sha256:965889d9f0e2a75edd81a07592d0ced54daa5b0785f57dc429c378edbcffe779", 133 | "sha256:9b248ba3dd8a03b1a10b19efe7d4f7fa41d158fdaa95e2cf65af5a7b95a4f989", 134 | "sha256:9bef37ee224e104a413f0780e29adb3e514a5b698aabe0d969a6ba426b8435d1", 135 | "sha256:c1ec8db4fac31850286b7cd3b9c0e1b944204668b8eb721674916d4e28744092", 136 | "sha256:c8a116feafdb1f84607cb3b14aa1418424ae71fee131642fc568d21423b51824", 137 | "sha256:ce85b06a10fc65e6143518b96d3dca27b081a740bae261c2fb20375801a9d56d", 138 | "sha256:d705f8aeecdf3262379644e4b55107a3b55860eb812b673b28d0fbc347a60c55", 139 | "sha256:e898a0863421650f0bebac8ba40840fc02258ef4714cb7e1fd76b6a6354bda36", 140 | "sha256:f8a7bff6e8664afc4e6c28b983845c5bc14965030e3fb98789734d416af77c4b" 141 | ], 142 | "version": "==8.1" 143 | } 144 | }, 145 | "develop": { 146 | "attrs": { 147 | "hashes": [ 148 | "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", 149 | "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" 150 | ], 151 | "version": "==20.3.0" 152 | }, 153 | "aws-cdk-aws-ec2": { 154 | "hashes": [ 155 | "sha256:ef71837981ccb652b453a56354b2d75165208a9e034a1dca96426c874e6f29e9" 156 | ], 157 | "index": "pypi", 158 | "version": "==1.36.1" 159 | }, 160 | "aws-cdk-aws-ecr": { 161 | "hashes": [ 162 | "sha256:e8f70072a6799938e9f9b14245119dcdb14ee245e2875f9728941de2d70a749d" 163 | ], 164 | "index": "pypi", 165 | "version": "==1.36.1" 166 | }, 167 | "aws-cdk-aws-ecs": { 168 | "hashes": [ 169 | "sha256:79b39d0b20c9eaecbe53b300b094cc564caff68795af46ed17815a5887af93de" 170 | ], 171 | "index": "pypi", 172 | "version": "==1.36.1" 173 | }, 174 | "aws-cdk-aws-ecs-patterns": { 175 | "hashes": [ 176 | "sha256:ba3546b38e5cbe8ff9de24934d60ab9d1f964283007dd10f92eac5f1787db88f" 177 | ], 178 | "index": "pypi", 179 | "version": "==1.36.1" 180 | }, 181 | "aws-cdk-aws-iam": { 182 | "hashes": [ 183 | "sha256:6751ec129d7e942f7057f0b69e6632eef4a05b89a00d9aef4a8fca0d01779e91" 184 | ], 185 | "index": "pypi", 186 | "version": "==1.36.1" 187 | }, 188 | "aws-cdk-core": { 189 | "hashes": [ 190 | "sha256:e698325df97e805a59243c1ae6276aee43ba0b23f8827394507bd4c86df32ece" 191 | ], 192 | "index": "pypi", 193 | "version": "==1.36.1" 194 | }, 195 | "aws-cdk.assets": { 196 | "hashes": [ 197 | "sha256:3c69c62bb7625277b97656b08480521069b81714a082ac35ae429c208058c035", 198 | "sha256:7abb04823239b8932cc7912f5f0c9c0f40ed43a076d8ef863a4b6db6ed2c3bed" 199 | ], 200 | "version": "==1.36.1" 201 | }, 202 | "aws-cdk.aws-apigateway": { 203 | "hashes": [ 204 | "sha256:a9f8cff9c1847affdc6ebfd30dfb03fd87f297c6503c251ce78111cbf6ce7e9c", 205 | "sha256:f2d3a064cb19de397bc031bc3f97b22fbf745f2c8f5edf0ead28891e4cc3831b" 206 | ], 207 | "version": "==1.36.1" 208 | }, 209 | "aws-cdk.aws-applicationautoscaling": { 210 | "hashes": [ 211 | "sha256:612f3fe0a772e36e4e9b2669be53af9815ba4afd453c2e29a2533d4a63e64b19", 212 | "sha256:76c91f42b9df24bc0c85dd72626888faf691596b07232312ea4e640a53de922d" 213 | ], 214 | "version": "==1.36.1" 215 | }, 216 | "aws-cdk.aws-autoscaling": { 217 | "hashes": [ 218 | "sha256:372eee777f9c6cf9df427c90d395329524f472421c495c555ccfc8569d21ee84", 219 | "sha256:f1e4690a8488251a9906ee9ed8e80fc7592f65b49b7e442f3a534913c7314ea6" 220 | ], 221 | "version": "==1.36.1" 222 | }, 223 | "aws-cdk.aws-autoscaling-common": { 224 | "hashes": [ 225 | "sha256:b242ae6240a209d48e474fadefcc3a713cd6eb4626f6723b3c77df7e1dae8585", 226 | "sha256:b2cd8569e793877454f3f6e009004442484288f4725b48aed78926071e6263ad" 227 | ], 228 | "version": "==1.36.1" 229 | }, 230 | "aws-cdk.aws-autoscaling-hooktargets": { 231 | "hashes": [ 232 | "sha256:002f03e85baf2f96de0e7f4e77fe9c6db4a1304cfe749a54a5832d7da4ae2cbd", 233 | "sha256:e79f9b122bb4a533dd379d551ad9fd324bd15088ffaf6863d8f284571eb2dea9" 234 | ], 235 | "version": "==1.36.1" 236 | }, 237 | "aws-cdk.aws-batch": { 238 | "hashes": [ 239 | "sha256:97b887c29afba3ecc33f328707dd3cd3ad84e8cb6c53d5a17ff0af58b8063bec", 240 | "sha256:e82a42f2e85b3d5511f039a89ec73a7d38336211e810b9c3f3cb20d037552d6c" 241 | ], 242 | "version": "==1.36.1" 243 | }, 244 | "aws-cdk.aws-certificatemanager": { 245 | "hashes": [ 246 | "sha256:64bd322620c1dbb08438fc4bc038351467f6cc79a2bb496d2de8a2c0dcd72b23", 247 | "sha256:795160fbce3d7fed79f86b8b778588692780775e85b06e68e6cfc0f9c2718fe7" 248 | ], 249 | "version": "==1.36.1" 250 | }, 251 | "aws-cdk.aws-cloudformation": { 252 | "hashes": [ 253 | "sha256:270aa6f66c93e48d43a7c2894129ff57453f02809e8c596fe324326e537349ca", 254 | "sha256:7ba8601f320dc483f32bf6ed363e12d38b1d64a9ee2e6eda24804f5362b039bd" 255 | ], 256 | "version": "==1.36.1" 257 | }, 258 | "aws-cdk.aws-cloudfront": { 259 | "hashes": [ 260 | "sha256:97c43a1ff5413b9bba3f7a9d3cc094b65398b28a3998ae30ac597492d366bd4d", 261 | "sha256:d8f184a006b8b97a2cb17633d9d9d99fc82dd4fb001b44c8b1169369863cc8ef" 262 | ], 263 | "version": "==1.36.1" 264 | }, 265 | "aws-cdk.aws-cloudwatch": { 266 | "hashes": [ 267 | "sha256:c0618c52f6d2812c3d04cb5bcd3b6cab28efe6c8c4d7dbbdc0d42c77abdbc9df", 268 | "sha256:f57203a844ccbcdb133a8c36436ab721edd7955d02f0e5a4451486bb1c7ff3d0" 269 | ], 270 | "version": "==1.36.1" 271 | }, 272 | "aws-cdk.aws-codebuild": { 273 | "hashes": [ 274 | "sha256:175d4f216f279749d83180bc048ea91167d227a941fbd8bf0b4982f52db44be2", 275 | "sha256:f6b8b7124e848e90cb9a45468d2399c0f2196eb2d7a15033885d0c1186623705" 276 | ], 277 | "version": "==1.36.1" 278 | }, 279 | "aws-cdk.aws-codecommit": { 280 | "hashes": [ 281 | "sha256:40949db33e7aff104d48797e2be0ea3ebed59b352b3e4c952e9d8a47dbaac673", 282 | "sha256:99d1c2bc05f4ab7fabc8d60b57e01f1dbcdf4864c32347f08e0b7706580a744a" 283 | ], 284 | "version": "==1.36.1" 285 | }, 286 | "aws-cdk.aws-codepipeline": { 287 | "hashes": [ 288 | "sha256:b818a5bc88cff564961c0a32e287639e7c6920474e06dda44fe50aff1ff07deb", 289 | "sha256:be9d6bc505db57fed4fcde709fe6426d5161964ce07a1fdf6af34b8744977b1e" 290 | ], 291 | "version": "==1.36.1" 292 | }, 293 | "aws-cdk.aws-cognito": { 294 | "hashes": [ 295 | "sha256:392ca8d955b3fb4d6a600e7574654b1b190eda7010fd0db70ebc8276865d6c21", 296 | "sha256:e7853d8d890dd319ec803939ae40c839e3aaf1a17bc5249a0acb6744058be575" 297 | ], 298 | "version": "==1.36.1" 299 | }, 300 | "aws-cdk.aws-ec2": { 301 | "hashes": [ 302 | "sha256:38b6729de2b58e23f58d66431241579ca301438ba1f29d24a3a1bea0444c53b8", 303 | "sha256:ef71837981ccb652b453a56354b2d75165208a9e034a1dca96426c874e6f29e9" 304 | ], 305 | "version": "==1.36.1" 306 | }, 307 | "aws-cdk.aws-ecr": { 308 | "hashes": [ 309 | "sha256:05733a23d16e2ee69288cf026e16f0a0641ad7a7df5db86ed362d1a77253dbb6", 310 | "sha256:e8f70072a6799938e9f9b14245119dcdb14ee245e2875f9728941de2d70a749d" 311 | ], 312 | "version": "==1.36.1" 313 | }, 314 | "aws-cdk.aws-ecr-assets": { 315 | "hashes": [ 316 | "sha256:38893ec9b9a190f8f1d9048c7315780d7ae2117e0e8e4e8f99ebf32e35ba9d44", 317 | "sha256:441ec5b4732b24c7e72d99a70b8a9eada718082eecee40b0e054c39904953093" 318 | ], 319 | "version": "==1.36.1" 320 | }, 321 | "aws-cdk.aws-ecs": { 322 | "hashes": [ 323 | "sha256:36ac7d481f752101ad0d2956e96633f5da557d9c1855a54e5d3f2dada72006f5", 324 | "sha256:79b39d0b20c9eaecbe53b300b094cc564caff68795af46ed17815a5887af93de" 325 | ], 326 | "version": "==1.36.1" 327 | }, 328 | "aws-cdk.aws-elasticloadbalancing": { 329 | "hashes": [ 330 | "sha256:47dc3aec5d90180c00aa0dcf454faf65faf526b65dc969443d6130700925ad6a", 331 | "sha256:f9d376a19a0f24e5b35bcb944cdbe8f99fc923fa8286eea03fecc34d28a91f0b" 332 | ], 333 | "version": "==1.36.1" 334 | }, 335 | "aws-cdk.aws-elasticloadbalancingv2": { 336 | "hashes": [ 337 | "sha256:22e2f60d6ca39cc0f3089ef5c33f56030fd5402b5df94194d10cf145f930bb8a", 338 | "sha256:a23d07b7f3cb952d697b83da725395168cdb08f7521007a062001f42a47b090f" 339 | ], 340 | "version": "==1.36.1" 341 | }, 342 | "aws-cdk.aws-events": { 343 | "hashes": [ 344 | "sha256:721fdff6f8903c583318c342cdc12cb1550e7c9d49baebb2e2db98847c8ab03b", 345 | "sha256:fc1483345c6e5bb6b644e753b7fa3a2db5edd9a230c9194b3f7ee915eb5b50e9" 346 | ], 347 | "version": "==1.36.1" 348 | }, 349 | "aws-cdk.aws-events-targets": { 350 | "hashes": [ 351 | "sha256:b0fee5dacbbdd0c93bac6656f5bf1f4008d70e4d338d8b370a70bd5fabb1b7d8", 352 | "sha256:fdb1be02eea3ed837c672e12e00b405aedf1bf53685513752942a3719cbb9a19" 353 | ], 354 | "version": "==1.36.1" 355 | }, 356 | "aws-cdk.aws-iam": { 357 | "hashes": [ 358 | "sha256:6751ec129d7e942f7057f0b69e6632eef4a05b89a00d9aef4a8fca0d01779e91", 359 | "sha256:c7dafdf208060749dd85ae3d8510c34676de825959eb89319473e1631a765ce3" 360 | ], 361 | "version": "==1.36.1" 362 | }, 363 | "aws-cdk.aws-kms": { 364 | "hashes": [ 365 | "sha256:8661b00da07e11f095a9082ff81f8a987d570a968d42040c886bdc13caa3e99c", 366 | "sha256:8c36e42fa8bac163c08033ba2d892b22bb5718a8f31f1f747d3114b8120be213" 367 | ], 368 | "version": "==1.36.1" 369 | }, 370 | "aws-cdk.aws-lambda": { 371 | "hashes": [ 372 | "sha256:4a38fd68eb45af45bc2871106ffe1bd15e4ae28ed9f648a3bf4096283fcd7d2a", 373 | "sha256:fcd765c53e07851941953ea368bbf7dc6e9b67bb37e4113b8c4eb1371f81b730" 374 | ], 375 | "version": "==1.36.1" 376 | }, 377 | "aws-cdk.aws-logs": { 378 | "hashes": [ 379 | "sha256:5858d91536dba584d1b58471606e78f750326759dfd478856ee03b4978226762", 380 | "sha256:e624a8888908a6b4a175517321ba97cf72185aa3511720f7f188a798dc1c437f" 381 | ], 382 | "version": "==1.36.1" 383 | }, 384 | "aws-cdk.aws-route53": { 385 | "hashes": [ 386 | "sha256:ba9905c6937bc7cdb9d0c7b18e0ba82a52c75a6a87ef5de5ad5c283845660b63", 387 | "sha256:beec1c84300d4c3d172f0d8b97a6975bd172a622beb1a0eb66db7f972e47b795" 388 | ], 389 | "version": "==1.36.1" 390 | }, 391 | "aws-cdk.aws-route53-targets": { 392 | "hashes": [ 393 | "sha256:168edfe7d97e3b2dcf4c9ab1be103a76e917f58f03c13499d03b9791612657fe", 394 | "sha256:dea7175f5d89f062101ca4b30ff89a6f1e3ca5777cf394c5d2af7a976f6759cc" 395 | ], 396 | "version": "==1.36.1" 397 | }, 398 | "aws-cdk.aws-s3": { 399 | "hashes": [ 400 | "sha256:44d2fd825580102d5d7ce3099994895e758d21dc253fb4ed991b4e47059f9a16", 401 | "sha256:eeb2d632cf81bc6fc7a88270d5886bba1fb9406746b171b9002a8b2f88dc0041" 402 | ], 403 | "version": "==1.36.1" 404 | }, 405 | "aws-cdk.aws-s3-assets": { 406 | "hashes": [ 407 | "sha256:57711eb57c00d87ee30613c5c467730715df0f309e45adc43105d84ca5e28f64", 408 | "sha256:724528ab116b303a34c9ba6a053f52543320d657cbfde684435420ffaebcb074" 409 | ], 410 | "version": "==1.36.1" 411 | }, 412 | "aws-cdk.aws-sam": { 413 | "hashes": [ 414 | "sha256:3bb400fe1fd0dc3cccfc5596cf5c5562b04c2fae863d03ab16381ec973af30a1", 415 | "sha256:775bdfe026561ad5fd27c7cd98b2dd6e284b85403423f03c353645a5b0d23441" 416 | ], 417 | "version": "==1.36.1" 418 | }, 419 | "aws-cdk.aws-secretsmanager": { 420 | "hashes": [ 421 | "sha256:0d84d9cfa3383a7bfcdaff52348f495f3a9ab89fb91bde2ebef26118534f2601", 422 | "sha256:520743cdca0f2a59b9e4a49b0c16c7ce3f84e14023c2273b66166bac38195b68" 423 | ], 424 | "version": "==1.36.1" 425 | }, 426 | "aws-cdk.aws-servicediscovery": { 427 | "hashes": [ 428 | "sha256:25ddfc5c837e276b2b6ee0f72fb28271ab6daa1315dcb738345c594c74cd2e0e", 429 | "sha256:62406325c974a1b001ea008689fb56c348293b25b7aac5d73913783aea4cc0d4" 430 | ], 431 | "version": "==1.36.1" 432 | }, 433 | "aws-cdk.aws-sns": { 434 | "hashes": [ 435 | "sha256:60fbc305e3deb0fdd7ad15e253c0c1762650fe3b28f735ea4e386cae2fc19cb1", 436 | "sha256:b0b41738b8248ea6dbfae1bbc42b2ea267325f8f5eec59d40a1bab32521834df" 437 | ], 438 | "version": "==1.36.1" 439 | }, 440 | "aws-cdk.aws-sns-subscriptions": { 441 | "hashes": [ 442 | "sha256:40ba9b29ccdaf2251d41546cfbaf2fe63707b6a9d715a2dad3998b919962fa3b", 443 | "sha256:b86ccf3bcfb5412bc658e864e68dc62acbe8afdb58ff49716812793bb36cdd6a" 444 | ], 445 | "version": "==1.36.1" 446 | }, 447 | "aws-cdk.aws-sqs": { 448 | "hashes": [ 449 | "sha256:01c3e7bb20d2d8c6d49073d645d2f0a93ad4c809b97ccb52983fb3deb74132dc", 450 | "sha256:f1432497cd6555ee2fadcaf03e78dfc64ad400066a231d0dd6a934d347f1ccfa" 451 | ], 452 | "version": "==1.36.1" 453 | }, 454 | "aws-cdk.aws-ssm": { 455 | "hashes": [ 456 | "sha256:63ab919eeeaae471eb2ee451fb73ab47ee7e258fcf0f466de656e46987724087", 457 | "sha256:e6cb44cac94b184b367d08828a4098c3462668e0a03b66fef9d8a93a9d33194f" 458 | ], 459 | "version": "==1.36.1" 460 | }, 461 | "aws-cdk.aws-stepfunctions": { 462 | "hashes": [ 463 | "sha256:96b2ddf3a622d6827752e7fdd8da49cb1e629e0b5c211a2118948b74cff6dfc5", 464 | "sha256:e0c932192c609996e0b4c8ef88104bf169679572ec01654a42f925243cc9f5a6" 465 | ], 466 | "version": "==1.36.1" 467 | }, 468 | "aws-cdk.cloud-assembly-schema": { 469 | "hashes": [ 470 | "sha256:441c3b01bcfd69742663f094e3ba8fbd8ba911593bbe701193a151a24c8c0f3b", 471 | "sha256:51d8bc2338a66361428bf9de4874225f4245ab94070b3638604b36a07a8cd305" 472 | ], 473 | "version": "==1.36.1" 474 | }, 475 | "aws-cdk.core": { 476 | "hashes": [ 477 | "sha256:3d8510bec9151b41834808f17532e08aa448bf88611ae8920a1d1d1f4e2bd875", 478 | "sha256:e698325df97e805a59243c1ae6276aee43ba0b23f8827394507bd4c86df32ece" 479 | ], 480 | "version": "==1.36.1" 481 | }, 482 | "aws-cdk.custom-resources": { 483 | "hashes": [ 484 | "sha256:39b7964bcedb38f7dffe3177909818400f9306e369d9d82ae970dea872c90ba6", 485 | "sha256:3cedf839873766003e0da0e41664b23198e43ab2357a96113e0cc594bb7a3fad" 486 | ], 487 | "version": "==1.36.1" 488 | }, 489 | "aws-cdk.cx-api": { 490 | "hashes": [ 491 | "sha256:846ef001db1716a940440a10aa47d2b5f74a4ae183b8de60f3d43eb4aa9756dd", 492 | "sha256:89bc03abe63d5c7343cb8760b18f372ab8129e8762decd8ecd4749aff60b3652" 493 | ], 494 | "version": "==1.36.1" 495 | }, 496 | "aws-cdk.region-info": { 497 | "hashes": [ 498 | "sha256:24b54cffe4b40ea9504753c1e36e8a1ab80da9f27fc0bdac8583b824839e0035", 499 | "sha256:a9cae4df850a6c96f6c8f81605b0991a3f0970a27fb68fc993227a787257ae08" 500 | ], 501 | "version": "==1.36.1" 502 | }, 503 | "cattrs": { 504 | "hashes": [ 505 | "sha256:277d12740b45e46318b41c3b2e4a3bc067a7b9971cf61f0e96497598ad83f282", 506 | "sha256:a6233d0ce33d48ac71ef818f8e0b9309a89496b359994c4dfe9ad211c1f6d0a3" 507 | ], 508 | "markers": "python_version >= '3.7'", 509 | "version": "==1.5.0" 510 | }, 511 | "constructs": { 512 | "hashes": [ 513 | "sha256:24f9c40a54e66eba22f8e020d7b8efa2f7df415219225f934f217c575afdd8c9", 514 | "sha256:a4ebf536b74a805bb9277d507c6d355f8b8421ced7879d2186b6464c53fe9496" 515 | ], 516 | "version": "==3.3.75" 517 | }, 518 | "jsii": { 519 | "hashes": [ 520 | "sha256:76d1f7b4aeec8f59356494f1ed253f5ce1094eeaa46b15232564e4c07c0e1fb5", 521 | "sha256:d3611f0cc4626ceb26ff55e6fe9ad5dae7a351709ed9c4f12f3bd8065b4c9809" 522 | ], 523 | "version": "==1.29.0" 524 | }, 525 | "publication": { 526 | "hashes": [ 527 | "sha256:0248885351febc11d8a1098d5c8e3ab2dabcf3e8c0c96db1e17ecd12b53afbe6", 528 | "sha256:68416a0de76dddcdd2930d1c8ef853a743cc96c82416c4e4d3b5d901c6276dc4" 529 | ], 530 | "version": "==0.0.3" 531 | }, 532 | "python-dateutil": { 533 | "hashes": [ 534 | "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", 535 | "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" 536 | ], 537 | "version": "==2.8.1" 538 | }, 539 | "python-dotenv": { 540 | "hashes": [ 541 | "sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", 542 | "sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" 543 | ], 544 | "index": "pypi", 545 | "version": "==0.13.0" 546 | }, 547 | "six": { 548 | "hashes": [ 549 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 550 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 551 | ], 552 | "version": "==1.16.0" 553 | }, 554 | "typing-extensions": { 555 | "hashes": [ 556 | "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", 557 | "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", 558 | "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" 559 | ], 560 | "version": "==3.10.0.0" 561 | } 562 | } 563 | } 564 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ECS fargate stacks by CDK with fastAPI 2 | 3 | [![MIT License](https://badgen.now.sh/badge/License/MIT/blue)](https://github.com/sintaro/CDK_ECSFargate_FastAPI/blob/master/LICENSE.md) 4 | [![sintaro](https://badgen.now.sh/badge/by/sintaro/purple)](https://github.com/sintaro) 5 | 6 | 7 | ## Requirements 8 | 9 | 10 | ## Architecture 11 | 12 | - **Python**, 13 | - Basic **Python** pipenv `./Pipfile` 14 | - Backend with FastAPI `./backend` 15 | - **Docker** using `./docker/api/Dockerfile` and docker-coompose in `./docker/docker-compose` 16 | - **Infrastructure as Code** using [AWS Cloud Development Kit][cdk] in `./stacks` 17 | - Pipenv scripts 18 | 19 | ``` text:Pipfile 20 | start 21 | docker_build 22 | docker_run 23 | docker_compose_up 24 | 25 | # ECR deploy image scripts 26 | tagged_image 27 | push_to_ecr 28 | deploy_image_ecr 29 | deploy_ecr_stack 30 | deploy_ecs_stack 31 | 32 | # CDK scripts 33 | cdk 34 | cdk_ls 35 | cdk_diff 36 | cdk_doctor 37 | ``` 38 | 39 | ## Usage 40 | 41 | Specified these to environment like .env file 42 | 43 | `$ touch > .env` 44 | 45 | ```sh title=.envに記載 46 | REPOSITORY_IMAGE=XXXXX-ecr-image 47 | ECR_STACK_NAME=xxxxxxxxxxx 48 | ECS_STACK_NAME=xxxxxxxxxxx 49 | PORT=XXXX 50 | ACCOUNT=XXXXXX 51 | AWS_REGION=XXXXXX 52 | AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXX 53 | AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXX 54 | ROLE_ARN=arn:aws:iam::XXXXXXXXXXXXXXXXXXX:role/ecsTaskExecutionRole 55 | ECR_REGISOTRY=XXXXXXXXXX.dkr.ecr.XXXXXXXXXXXXXXXX.amazonaws.com/XXXXXXXXXXXXXXXX:latest 56 | ``` -------------------------------------------------------------------------------- /backend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xShin0221/CDK_ECSFargate_FastAPI/f3a72d4395938006486256233ea8dd4e3b7f183c/backend/__init__.py -------------------------------------------------------------------------------- /backend/main.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI 2 | 3 | openapi_params = { 4 | "title": "CDK-Fargate-fastAPI", 5 | "openapi": "3.0.0", 6 | "version": "1.0", 7 | "docs_route": "/docs", 8 | } 9 | # cors ,doc 10 | api = FastAPI() 11 | 12 | 13 | @api.get("/") 14 | def route(): 15 | """Helloworld endpoint. 16 | --- 17 | get: 18 | description: Helloworld 19 | responses: 20 | 200: 21 | description: Helloworld 22 | """ 23 | return {"status": "ok"} 24 | -------------------------------------------------------------------------------- /docker/api/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Python image. 2 | # https://hub.docker.com/_/python 3 | FROM python:3.7 4 | 5 | RUN apt-get update && \ 6 | apt-get install -y --no-install-recommends \ 7 | ca-certificates \ 8 | git \ 9 | && apt-get clean && \ 10 | rm -rf /var/lib/apt/lists/* 11 | 12 | ENV WORKDIR /usr/src/server/ 13 | 14 | WORKDIR ${WORKDIR} 15 | 16 | COPY Pipfile Pipfile.lock ${WORKDIR} 17 | 18 | RUN set -ex \ 19 | && apt-get update -y --fix-missing \ 20 | && apt-get install -y -q --no-install-recommends \ 21 | curl \ 22 | file \ 23 | && apt-get purge -y --auto-remove 24 | 25 | 26 | RUN pip install pipenv --no-cache-dir && \ 27 | pipenv install --system --deploy && \ 28 | pip uninstall -y pipenv virtualenv-clone virtualenv 29 | 30 | COPY backend $WORKDIR 31 | 32 | CMD ["uvicorn", "main:api", "--host", "0.0.0.0", "--port", "8080"] -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | services: 4 | api: 5 | container_name: "api" 6 | build: ./api 7 | ports: 8 | - "8080:8080" 9 | volumes: 10 | - ./../backend:/usr/src/server 11 | networks: 12 | - local-net 13 | 14 | networks: 15 | local-net: 16 | driver: bridge -------------------------------------------------------------------------------- /stacks/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | package-lock.json 3 | __pycache__ 4 | .pytest_cache 5 | .env 6 | *.egg-info 7 | 8 | # CDK asset staging directory 9 | .cdk.staging 10 | cdk.out 11 | -------------------------------------------------------------------------------- /stacks/app.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | 4 | from aws_cdk import core 5 | 6 | from cdk.ecs_stack import ECSStack 7 | from cdk.ecr_stack import ECRStack 8 | 9 | app = core.App() 10 | ECRStack(app, os.environ["ECR_STACK_NAME"]) 11 | ECSStack(app, os.environ["ECS_STACK_NAME"]) 12 | -------------------------------------------------------------------------------- /stacks/cdk.context.json: -------------------------------------------------------------------------------- 1 | { 2 | "@aws-cdk/core:enableStackNameDuplicates": "true", 3 | "aws-cdk:enableDiffNoFail": "true" 4 | } 5 | -------------------------------------------------------------------------------- /stacks/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "python3 app.py" 3 | } 4 | -------------------------------------------------------------------------------- /stacks/cdk/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xShin0221/CDK_ECSFargate_FastAPI/f3a72d4395938006486256233ea8dd4e3b7f183c/stacks/cdk/__init__.py -------------------------------------------------------------------------------- /stacks/cdk/ecr_stack.py: -------------------------------------------------------------------------------- 1 | import os 2 | from aws_cdk import core, aws_ecr as ecr 3 | 4 | 5 | class ECRStack(core.Stack): 6 | def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: 7 | super().__init__(scope, id, **kwargs) 8 | 9 | ecr.Repository( 10 | self, id="CDKFargateFastAPI", repository_name=os.environ["REPOSITORY_NAME"] 11 | ) 12 | -------------------------------------------------------------------------------- /stacks/cdk/ecs_stack.py: -------------------------------------------------------------------------------- 1 | import os 2 | from dotenv import load_dotenv 3 | 4 | from aws_cdk import ( 5 | core, 6 | aws_ec2 as ec2, 7 | aws_ecs as ecs, 8 | aws_iam as iam, 9 | aws_ecs_patterns as ecs_patterns, 10 | ) 11 | 12 | load_dotenv() 13 | 14 | ROLE_ARN = os.environ["ROLE_ARN"] 15 | ECR_REGISOTRY = os.environ["ECR_REGISOTRY"] 16 | 17 | 18 | class ECSStack(core.Stack): 19 | def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: 20 | super().__init__(scope, id, **kwargs) 21 | 22 | vpc = ec2.Vpc(self, "CDKFargateVpc", max_azs=2) 23 | 24 | cluster = ecs.Cluster(self, "CDKFargateCluster", vpc=vpc) 25 | 26 | role = iam.Role.from_role_arn(self, "CDKFargateECSTaskRole", ROLE_ARN) 27 | image = ecs.ContainerImage.from_registry(ECR_REGISOTRY) 28 | task_definition = ecs.FargateTaskDefinition( 29 | scope=self, id="CDKFargateECSTask", execution_role=role, task_role=role 30 | ) 31 | 32 | port_mapping = ecs.PortMapping(container_port=8080, host_port=8080) 33 | task_definition.add_container( 34 | id="CDKFargateContainer", image=image 35 | ).add_port_mappings(port_mapping) 36 | fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService( 37 | self, "CDKFargateService", cluster=cluster, task_definition=task_definition, 38 | ) 39 | 40 | core.CfnOutput( 41 | self, 42 | "CDKFargateLoadBalancerDNS", 43 | value=fargate_service.load_balancer.load_balancer_dns_name, 44 | ) 45 | --------------------------------------------------------------------------------