├── .github └── workflows │ ├── lint.yaml │ ├── release.yaml │ └── test.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── .releaserc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples ├── ecs_update_service.tf └── terraform-task-definition-multiple-containers │ ├── main.tf │ └── outputs.tf ├── go.mod ├── go.sum ├── main.tf ├── modules └── merge │ ├── README.md │ ├── outputs.tf │ └── variables.tf ├── outputs.tf ├── templates └── container-definition.json.tpl ├── test ├── fixtures │ ├── multiple.json │ └── single.json ├── terraform_ecs_task_definition_test.go └── varfile.tfvars ├── variables.tf └── versions.tf /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | lint: 3 | env: 4 | AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" 5 | AWS_DEFAULT_REGION: us-east-1 6 | AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v1 10 | - uses: hashicorp/setup-terraform@v1 11 | with: 12 | terraform_version: 0.12.24 13 | - run: terraform fmt -check -recursive 14 | - run: terraform init 15 | - run: terraform validate 16 | name: Format and validate 17 | "on": 18 | pull_request: 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | release: 3 | env: 4 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v1 8 | - uses: cycjimmy/semantic-release-action@v2.1.3 9 | with: 10 | branch: master 11 | extra_plugins: | 12 | @semantic-release/changelog 13 | @semantic-release/git@8.0.0 14 | name: Create release 15 | "on": 16 | push: 17 | branches: 18 | - master 19 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | jobs: 2 | test: 3 | env: 4 | AWS_ACCESS_KEY_ID: "${{ secrets.AWS_ACCESS_KEY_ID }}" 5 | AWS_DEFAULT_REGION: us-east-1 6 | AWS_SECRET_ACCESS_KEY: "${{ secrets.AWS_SECRET_ACCESS_KEY }}" 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - uses: actions/setup-go@v2 11 | with: 12 | go-version: ^1.14.2 13 | - uses: actions/cache@v1 14 | with: 15 | key: "${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}" 16 | path: ~/go/pkg/mod 17 | restore-keys: | 18 | ${{ runner.os }}-go- 19 | - uses: hashicorp/setup-terraform@v1 20 | with: 21 | terraform_version: 0.12.24 22 | terraform_wrapper: false 23 | - run: go test -count=1 -timeout=45m ./... 24 | name: Run Terratest 25 | "on": 26 | pull_request: 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | # example.tfvars 16 | 17 | # Ignore override files as they are usually used to override resources locally and so 18 | # are not checked in 19 | override.tf 20 | override.tf.json 21 | *_override.tf 22 | *_override.tf.json 23 | 24 | # Include override files you do wish to add to version control using negated pattern 25 | # 26 | # !example_override.tf 27 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - hooks: 3 | - id: terraform_docs 4 | - id: terraform_fmt 5 | repo: https://github.com/antonbabenko/pre-commit-terraform.git 6 | rev: v1.11.0 7 | 8 | - hooks: 9 | - id: go-fmt 10 | - id: go-lint 11 | exclude: vendor 12 | repo: https://github.com/dnephin/pre-commit-golang.git 13 | rev: v0.3.3 14 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@semantic-release/commit-analyzer", 4 | "@semantic-release/github", 5 | "@semantic-release/release-notes-generator", 6 | "@semantic-release/changelog", 7 | [ 8 | "@semantic-release/git", 9 | { 10 | "assets": [ 11 | "CHANGELOG.md" 12 | ] 13 | } 14 | ] 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [2.1.7](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.6...v2.1.7) (2021-06-14) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * tf fmt ([#54](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/54)) ([597dd24](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/597dd2416f08b4f72bbaa1e3ef453e4edbaf65e6)) 7 | 8 | ## [2.1.6](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.5...v2.1.6) (2021-03-16) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * wrong variables type ([#50](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/50)) ([d5fed9e](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/d5fed9e416dc4617208234415b7f3affebb23ff0)) 14 | 15 | ## [2.1.5](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.4...v2.1.5) (2021-01-19) 16 | 17 | 18 | ### Bug Fixes 19 | 20 | * variable type def for placement constraints ([#40](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/40)) ([3a3f6f8](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/3a3f6f8c53e23e6d94675671c706c11f61e8040f)) 21 | 22 | ## [2.1.4](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.3...v2.1.4) (2021-01-14) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * Add tags to the aws_ecs_task_definition resource ([#48](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/48)) ([5d3b19f](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/5d3b19f2887cdb2195a3e6c993fa0236fe5b6132)) 28 | 29 | ## [2.1.3](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.2...v2.1.3) (2020-12-07) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * secrets type to list(map(string)) ([#45](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/45)) ([78bf0c3](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/78bf0c354c11bc7f7b9f30620ad24497dccfe624)), closes [#44](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/44) 35 | 36 | ## [2.1.2](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.1...v2.1.2) (2020-10-01) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * **task-definition:** update volumesFrom data type ([#42](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/42)) ([9d61d38](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/9d61d386f2659ea3bea491990c10d951eaab971d)) 42 | 43 | ## [2.1.1](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.1.0...v2.1.1) (2020-07-07) 44 | 45 | 46 | ### Bug Fixes 47 | 48 | * use correct type for extraHosts directive ([#39](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/39)) ([084ebe6](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/084ebe60e6b902ea51312cf3833f60122a17959c)) 49 | 50 | # [2.1.0](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.0.1...v2.1.0) (2020-06-29) 51 | 52 | 53 | ### Features 54 | 55 | * allow task definitions to be used by Fargate ([#37](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/37)) ([8e1e46c](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/8e1e46ca235e5fb3113bef6e44622a3f9e2664ee)) 56 | 57 | ## [2.0.1](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v2.0.0...v2.0.1) (2020-03-21) 58 | 59 | 60 | ### Bug Fixes 61 | 62 | * update type of logConfiguration variable ([#27](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/27)) ([041b144](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/041b1445f074dfa3205da1a32d5f91496449f728)), closes [#26](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/26) 63 | 64 | # [2.0.0](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v1.2.1...v2.0.0) (2020-03-19) 65 | 66 | 67 | ### Features 68 | 69 | * upgrade module to support Terraform 0.12.x ([#24](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/24)) ([8998443](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/899844342323285fb5c4cac4f4bc80c9b31dcdc5)) 70 | 71 | 72 | ### BREAKING CHANGES 73 | 74 | * This module no longer supports Terraform versions 0.11.x. Please upgrade 75 | your version of Terraform and run the `0.12upgrade` command. Visit the 76 | following URL for more information: 77 | 78 | https://www.terraform.io/docs/commands/0.12upgrade.html 79 | 80 | * fix: change Terraform download URL to latest in CI 81 | 82 | ## [1.2.1](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v1.2.0...v1.2.1) (2019-12-24) 83 | 84 | 85 | ### Bug Fixes 86 | 87 | * add checkout step to CircleCI config ([d40ec70](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/d40ec709706d7bfafce8c15eaf3f8915af3d424f)) 88 | * begin updating CI config ([1f223b9](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/1f223b93aa62bd76607a4d31a8d55fe5e17d1ca8)) 89 | * remove nested job directive from CI config ([958615c](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/958615c4547f163752560760b2ca3f0477f52e5f)) 90 | 91 | # [1.2.0](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v1.1.0...v1.2.0) (2019-04-16) 92 | 93 | 94 | ### Features 95 | 96 | * Add support for multiple containers ([a7377e2](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/a7377e2)), closes [#9](https://github.com/mongodb/terraform-aws-ecs-task-definition/issues/9) 97 | 98 | # [1.1.0](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v1.0.1...v1.1.0) (2019-04-11) 99 | 100 | 101 | ### Features 102 | 103 | * Add register_task_definition input ([430b1bf](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/430b1bf)) 104 | 105 | ## [1.0.1](https://github.com/mongodb/terraform-aws-ecs-task-definition/compare/v1.0.0...v1.0.1) (2019-04-09) 106 | 107 | 108 | ### Bug Fixes 109 | 110 | * Support negative values for ulimits ([ca6f022](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/ca6f022)) 111 | 112 | # 1.0.0 (2019-04-09) 113 | 114 | 115 | ### Features 116 | 117 | * Use semantic release for GitHub releases ([be3151d](https://github.com/mongodb/terraform-aws-ecs-task-definition/commit/be3151d)) 118 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitHub release](https://img.shields.io/github/release/mongodb/terraform-aws-ecs-task-definition.svg?style=flat-square) ![GitHub](https://img.shields.io/github/license/mongodb/terraform-aws-ecs-task-definition.svg?style=flat-square) 2 | 3 | > A Terraform module for creating Amazon [ECS Task Definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) 4 | 5 | ## NOTICE 6 | 7 | **THIS MODULE IS NOT COMPATIBLE WITH VERSIONS OF TERRAFORM LESS THAN v0.12.x. PLEASE REFER TO THE OFFICIAL [DOCUMENTATION](https://www.terraform.io/upgrade-guides/0-12.html) FOR UPGRADING TO THE LATEST VERSION OF TERRAFORM.** 8 | 9 | ## Contents 10 | 11 | - [Motivation](#motivation) 12 | - [Use Cases](#use-cases) 13 | - [Requirements](#requirements) 14 | - [Usage](#usage) 15 | - [Multiple Container Definitions](#multiple-container-definitions) 16 | - [Inputs](#inputs) 17 | - [Outputs](#outputs) 18 | - [Testing](#testing) 19 | - [License](#license) 20 | 21 | ## Motivation 22 | 23 | The purpose of this module is to generate a valid Amazon [ECS Task Definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) dynamically. A task definition is required to run Docker containers in Amazon ECS. A task definition contains a list of [container definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions) received by the Docker daemon to create a container instance. 24 | 25 | ### Use Cases 26 | 27 | - Have Terraform generate valid task definitions dynamically 28 | - Update the ECS task definition and trigger new [service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) deployments automatically (see [examples/ecs_update_service.tf](examples/ecs_update_service.tf)) 29 | 30 | ## Requirements 31 | 32 | - [Terraform](https://www.terraform.io/downloads.html) 33 | - [Go](https://golang.org/dl/) (for testing) 34 | 35 | ## Usage 36 | 37 | This module uses the same parameters as the [`ContainerDefinition`](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html) object. Given the following Terraform configuration: 38 | 39 | ```hcl 40 | provider "aws" {} 41 | 42 | module "mongo-task-definition" { 43 | source = "github.com/mongodb/terraform-aws-ecs-task-definition" 44 | 45 | family = "mongo" 46 | image = "mongo:3.6" 47 | memory = 512 48 | name = "mongo" 49 | 50 | portMappings = [ 51 | { 52 | containerPort = 27017 53 | }, 54 | ] 55 | } 56 | ``` 57 | 58 | Invoking the commands defined below creates an ECS task definition with the following [`containerDefinitions`](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_RegisterTaskDefinition.html#ECS-RegisterTaskDefinition-request-containerDefinitions): 59 | 60 | $ terraform init 61 | $ terraform apply 62 | 63 | ```json 64 | [ 65 | { 66 | "command": null, 67 | "cpu": null, 68 | "disableNetworking": false, 69 | "dnsSearchDomains": null, 70 | "dnsServers": null, 71 | "dockerLabels": null, 72 | "dockerSecurityOptions": null, 73 | "entryPoint": null, 74 | "environment": null, 75 | "essential": true, 76 | "extraHosts": null, 77 | "healthCheck": null, 78 | "hostname": null, 79 | "image": "mongo:3.6", 80 | "interactive": false, 81 | "links": null, 82 | "linuxParameters": null, 83 | "logConfiguration": null, 84 | "memory": 512, 85 | "memoryReservation": null, 86 | "mountPoints": null, 87 | "name": "mongo", 88 | "portMappings": [{"containerPort":27017}], 89 | "privileged": false, 90 | "pseudoTerminal": false, 91 | "readonlyRootFilesystem": false, 92 | "repositoryCredentials": null, 93 | "resourceRequirements": null, 94 | "secrets": null, 95 | "systemControls": null, 96 | "ulimits": null, 97 | "user": null, 98 | "volumesFrom": null, 99 | "workingDirectory": null 100 | } 101 | ] 102 | ``` 103 | 104 | ### Multiple Container Definitions 105 | 106 | By default, this module creates a task definition with a single container definition. To create a task definition with multiple container definitions, refer to the documentation of the [`merge`](modules/merge) module. 107 | 108 | 109 | ## Providers 110 | 111 | | Name | Version | 112 | |------|---------| 113 | | aws | n/a | 114 | | template | n/a | 115 | 116 | ## Inputs 117 | 118 | | Name | Description | Type | Default | Required | 119 | |------|-------------|------|---------|:-----:| 120 | | command | The command that is passed to the container | `list(string)` | `[]` | no | 121 | | cpu | The number of cpu units reserved for the container | `number` | `0` | no | 122 | | disableNetworking | When this parameter is true, networking is disabled within the container | `bool` | `false` | no | 123 | | dnsSearchDomains | A list of DNS search domains that are presented to the container | `list(string)` | `[]` | no | 124 | | dnsServers | A list of DNS servers that are presented to the container | `list(string)` | `[]` | no | 125 | | dockerLabels | A key/value map of labels to add to the container | `map(string)` | `{}` | no | 126 | | dockerSecurityOptions | A list of strings to provide custom labels for SELinux and AppArmor multi-level security systems | `list(string)` | `[]` | no | 127 | | entryPoint | The entry point that is passed to the container | `list(string)` | `[]` | no | 128 | | environment | The environment variables to pass to a container | `list(map(string))` | `[]` | no | 129 | | essential | If the essential parameter of a container is marked as true, and that container fails or stops for any reason, all other containers that are part of the task are stopped | `bool` | `true` | no | 130 | | execution\_role\_arn | The Amazon Resource Name (ARN) of the task execution role that the Amazon ECS container agent and the Docker daemon can assume | `string` | `""` | no | 131 | | extraHosts | A list of hostnames and IP address mappings to append to the /etc/hosts file on the container | `list(string)` | `[]` | no | 132 | | family | You must specify a family for a task definition, which allows you to track multiple versions of the same task definition | `any` | n/a | yes | 133 | | healthCheck | The health check command and associated configuration parameters for the container | `any` | `{}` | no | 134 | | hostname | The hostname to use for your container | `string` | `""` | no | 135 | | image | The image used to start a container | `string` | `""` | no | 136 | | interactive | When this parameter is true, this allows you to deploy containerized applications that require stdin or a tty to be allocated | `bool` | `false` | no | 137 | | ipc\_mode | The IPC resource namespace to use for the containers in the task | `string` | `"host"` | no | 138 | | links | The link parameter allows containers to communicate with each other without the need for port mappings | `list(string)` | `[]` | no | 139 | | linuxParameters | Linux-specific modifications that are applied to the container, such as Linux KernelCapabilities | `any` | `{}` | no | 140 | | logConfiguration | The log configuration specification for the container | `any` | `{}` | no | 141 | | memory | The hard limit (in MiB) of memory to present to the container | `number` | `0` | no | 142 | | memoryReservation | The soft limit (in MiB) of memory to reserve for the container | `number` | `0` | no | 143 | | mountPoints | The mount points for data volumes in your container | `list(any)` | `[]` | no | 144 | | name | The name of a container | `string` | `""` | no | 145 | | network\_mode | The Docker networking mode to use for the containers in the task | `string` | `"bridge"` | no | 146 | | pid\_mode | The process namespace to use for the containers in the task | `string` | `"host"` | no | 147 | | placement\_constraints | An array of placement constraint objects to use for the task | `list(string)` | `[]` | no | 148 | | portMappings | The list of port mappings for the container | `list(any)` | `[]` | no | 149 | | privileged | When this parameter is true, the container is given elevated privileges on the host container instance (similar to the root user) | `bool` | `false` | no | 150 | | pseudoTerminal | When this parameter is true, a TTY is allocated | `bool` | `false` | no | 151 | | readonlyRootFilesystem | When this parameter is true, the container is given read-only access to its root file system | `bool` | `false` | no | 152 | | register\_task\_definition | Registers a new task definition from the supplied family and containerDefinitions | `bool` | `true` | no | 153 | | repositoryCredentials | The private repository authentication credentials to use | `map(string)` | `{}` | no | 154 | | requires\_compatibilities | The launch type required by the task | `list(string)` | `[]` | no | 155 | | resourceRequirements | The type and amount of a resource to assign to a container | `list(string)` | `[]` | no | 156 | | secrets | The secrets to pass to the container | `list(map(string))` | `[]` | no | 157 | | systemControls | A list of namespaced kernel parameters to set in the container | `list(string)` | `[]` | no | 158 | | tags | The metadata that you apply to the task definition to help you categorize and organize them | `map(string)` | `{}` | no | 159 | | task\_role\_arn | The short name or full Amazon Resource Name (ARN) of the IAM role that containers in this task can assume | `string` | `""` | no | 160 | | ulimits | A list of ulimits to set in the container | `list(any)` | `[]` | no | 161 | | user | The user name to use inside the container | `string` | `""` | no | 162 | | volumes | A list of volume definitions in JSON format that containers in your task may use | `list(any)` | `[]` | no | 163 | | volumesFrom | Data volumes to mount from another container | `list(object)` | `[]` | no | 164 | | workingDirectory | The working directory in which to run commands inside the container | `string` | `""` | no | 165 | 166 | ## Outputs 167 | 168 | | Name | Description | 169 | |------|-------------| 170 | | arn | The full Amazon Resource Name (ARN) of the task definition | 171 | | container\_definitions | A list of container definitions in JSON format that describe the different containers that make up your task | 172 | | family | The family of your task definition, used as the definition name | 173 | | revision | The revision of the task in a particular family | 174 | 175 | 176 | 177 | ## Testing 178 | 179 | This module uses [Terratest](https://github.com/gruntwork-io/terratest), a Go library maintained by [Gruntwork](https://gruntwork.io/), to write automated tests for your infrastructure code. To invoke tests, run the following commands: 180 | 181 | $ go test -v ./... 182 | 183 | ## License 184 | 185 | [Apache License 2.0](LICENSE) 186 | -------------------------------------------------------------------------------- /examples/ecs_update_service.tf: -------------------------------------------------------------------------------- 1 | # This configuration demonstrates forcing the new deployment of an ECS 2 | # service if there is a change to the ECS task definition. The 3 | # configuration uses the `null_resource` provider to invoke the 4 | # `local-exec` provisioner whenever the task definition ARN changes. 5 | # 6 | # To force a new deployment even if there are no changes made to the 7 | # task definition, `taint` the resource: 8 | # 9 | # $ terraform taint null_resource.update-service 10 | 11 | provider "aws" { 12 | region = "us-east-1" 13 | version = "~> 2.0" 14 | } 15 | 16 | module "mongo-task-definition" { 17 | source = "github.com/mongodb/terraform-aws-ecs-task-definition" 18 | 19 | family = "mongo" 20 | image = "mongo:3.6" 21 | memory = 512 22 | name = "mongo" 23 | 24 | portMappings = [ 25 | { 26 | containerPort = 27017 27 | }, 28 | ] 29 | } 30 | 31 | resource "aws_ecs_service" "mongo" { 32 | cluster = "mongo" 33 | name = "mongo" 34 | task_definition = module.mongo-task-definition.arn 35 | } 36 | 37 | resource "null_resource" "update-service" { 38 | triggers = { 39 | arn = module.mongo-task-definition.arn 40 | } 41 | 42 | provisioner "local-exec" { 43 | command = "aws ecs update-service --cluster ${aws_ecs_service.mongo.cluster} --service ${aws_ecs_service.mongo.name} --task-definition ${module.mongo-task-definition.arn} --force-new-deployment" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /examples/terraform-task-definition-multiple-containers/main.tf: -------------------------------------------------------------------------------- 1 | module "mongodb" { 2 | source = "../.." 3 | 4 | family = "mongodb" 5 | image = "mongo:3.6" 6 | memory = 512 7 | name = "mongodb" 8 | 9 | portMappings = [ 10 | { 11 | containerPort = 27017 12 | protocol = "TCP" 13 | }, 14 | ] 15 | 16 | register_task_definition = false 17 | } 18 | 19 | module "redis" { 20 | source = "../.." 21 | 22 | family = "redis" 23 | image = "redis:alpine" 24 | memory = 512 25 | 26 | logConfiguration = { 27 | logDriver = "awslogs" 28 | options = { 29 | awslogs-group = "awslogs-mongodb" 30 | awslogs-region = "us-east-1" 31 | } 32 | } 33 | 34 | name = "redis" 35 | 36 | portMappings = [ 37 | { 38 | containerPort = 6379 39 | protocol = "TCP" 40 | }, 41 | ] 42 | 43 | register_task_definition = false 44 | } 45 | 46 | module "merged" { 47 | source = "../../modules/merge" 48 | 49 | container_definitions = [ 50 | module.mongodb.container_definitions, 51 | module.redis.container_definitions, 52 | ] 53 | } 54 | 55 | resource "aws_ecs_task_definition" "ecs_task_definition" { 56 | container_definitions = module.merged.container_definitions 57 | family = "app" 58 | } 59 | -------------------------------------------------------------------------------- /examples/terraform-task-definition-multiple-containers/outputs.tf: -------------------------------------------------------------------------------- 1 | output "container_definitions" { 2 | value = "${module.merged.container_definitions}" 3 | } 4 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module terraform-aws-ecs-task-definition 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/aws/aws-sdk-go v1.25.26 // indirect 7 | github.com/davecgh/go-spew v1.1.1 // indirect 8 | github.com/go-sql-driver/mysql v1.4.1 // indirect 9 | github.com/google/uuid v1.1.1 // indirect 10 | github.com/gruntwork-io/terratest v0.14.2 11 | github.com/pquerna/otp v1.2.0 // indirect 12 | github.com/stretchr/testify v1.3.0 13 | golang.org/x/sys v0.0.0-20190306155319-3e9a981b8ddb // indirect 14 | google.golang.org/appengine v1.6.5 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/aws/aws-sdk-go v1.25.26 h1:hMrxW3feteaGcP32oKaFdCQsCEWYf9zF12g73C0AcbI= 2 | github.com/aws/aws-sdk-go v1.25.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= 3 | github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= 4 | github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 7 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= 9 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 10 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 11 | github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= 12 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 13 | github.com/gruntwork-io/terratest v0.14.2 h1:A9YUZZlXE/syTnIVeuqhqoyVO5CUJS5Kasvyr5IUsv8= 14 | github.com/gruntwork-io/terratest v0.14.2/go.mod h1:NjUn6YXA5Skxt8Rs20t3isYx5Rl+EgvGB8/+RRXddqk= 15 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= 16 | github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= 17 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 18 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 19 | github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= 20 | github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= 21 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 22 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 23 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 24 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= 25 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 26 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ= 27 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 28 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 29 | golang.org/x/sys v0.0.0-20190306155319-3e9a981b8ddb h1:xIUJ1YHSR/6NhHkg597Yw0jPKhHGJmQfc8CzOmXgEco= 30 | golang.org/x/sys v0.0.0-20190306155319-3e9a981b8ddb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 31 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 32 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 33 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 34 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 35 | google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= 36 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 37 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | # The ternary operators in this module are mandatory. All composite types (e.g., lists and maps) require encoding to 2 | # pass as arguments to the Terraform `templatefile`[1] data source The `locals.tf` file contains the encoded values of 3 | # the composite types defined in the ECS Task Definition[2]. Certain variables, such as `healthCheck`, `linuxParameters` 4 | # and `portMappings`, require the `replace` function since they contain numerical values. For example, given the 5 | # following JSON: 6 | # 7 | # -var 'portMappings=[{containerPort = 80, protocol = "TCP"}]' 8 | # 9 | # [ 10 | # { 11 | # "containerDefinitions": [ 12 | # { 13 | # "portMappings": [ 14 | # { 15 | # "containerPort": 80, 16 | # "protocol": "TCP" 17 | # } 18 | # ] 19 | # } 20 | # ] 21 | # } 22 | # ] 23 | # 24 | # Since the `containerPort` and `hostPort`[3] fields are both integer types, then the `replace` function is necessary to 25 | # prevent quoting the value in strings. This issue is a known limitation in the Terraform `jsonencode`[4] function. 26 | # 27 | # - 1. https://www.terraform.io/language/functions/templatefile 28 | # - 2. https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html 29 | # - 3. https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_PortMapping.html 30 | # - 4. https://github.com/hashicorp/terraform/issues/17033 31 | 32 | locals { 33 | command = jsonencode(var.command) 34 | dnsSearchDomains = jsonencode(var.dnsSearchDomains) 35 | dnsServers = jsonencode(var.dnsServers) 36 | dockerLabels = jsonencode(var.dockerLabels) 37 | dockerSecurityOptions = jsonencode(var.dockerSecurityOptions) 38 | entryPoint = jsonencode(var.entryPoint) 39 | environment = jsonencode(var.environment) 40 | extraHosts = jsonencode(var.extraHosts) 41 | 42 | healthCheck = replace(jsonencode(var.healthCheck), local.classes["digit"], "$1") 43 | 44 | links = jsonencode(var.links) 45 | 46 | linuxParameters = replace( 47 | replace( 48 | replace(jsonencode(var.linuxParameters), "/\"1\"/", "true"), 49 | "/\"0\"/", 50 | "false", 51 | ), 52 | local.classes["digit"], 53 | "$1", 54 | ) 55 | 56 | logConfiguration = jsonencode(var.logConfiguration) 57 | 58 | mountPoints = replace( 59 | replace(jsonencode(var.mountPoints), "/\"1\"/", "true"), 60 | "/\"0\"/", 61 | "false", 62 | ) 63 | 64 | portMappings = replace(jsonencode(var.portMappings), local.classes["digit"], "$1") 65 | 66 | repositoryCredentials = jsonencode(var.repositoryCredentials) 67 | resourceRequirements = jsonencode(var.resourceRequirements) 68 | secrets = jsonencode(var.secrets) 69 | systemControls = jsonencode(var.systemControls) 70 | 71 | ulimits = replace(jsonencode(var.ulimits), local.classes["digit"], "$1") 72 | 73 | volumesFrom = replace( 74 | replace(jsonencode(var.volumesFrom), "/\"1\"/", "true"), 75 | "/\"0\"/", 76 | "false", 77 | ) 78 | 79 | # re2 ASCII character classes 80 | # https://github.com/google/re2/wiki/Syntax 81 | classes = { 82 | digit = "/\"(-[[:digit:]]|[[:digit:]]+)\"/" 83 | } 84 | 85 | container_definition = var.register_task_definition ? format("[%s]", local.container_definition_template) : format("%s", local.container_definition_template) 86 | 87 | 88 | container_definitions = replace(local.container_definition, "/\"(null)\"/", "$1") 89 | 90 | container_definition_template = templatefile( 91 | "${path.module}/templates/container-definition.json.tpl", 92 | { 93 | command = local.command == "[]" ? "null" : local.command 94 | cpu = var.cpu == 0 ? "null" : var.cpu 95 | disableNetworking = var.disableNetworking ? true : false 96 | dnsSearchDomains = local.dnsSearchDomains == "[]" ? "null" : local.dnsSearchDomains 97 | dnsServers = local.dnsServers == "[]" ? "null" : local.dnsServers 98 | dockerLabels = local.dockerLabels == "{}" ? "null" : local.dockerLabels 99 | dockerSecurityOptions = local.dockerSecurityOptions == "[]" ? "null" : local.dockerSecurityOptions 100 | entryPoint = local.entryPoint == "[]" ? "null" : local.entryPoint 101 | environment = local.environment == "[]" ? "null" : local.environment 102 | essential = var.essential ? true : false 103 | extraHosts = local.extraHosts == "[]" ? "null" : local.extraHosts 104 | healthCheck = local.healthCheck == "{}" ? "null" : local.healthCheck 105 | hostname = var.hostname == "" ? "null" : var.hostname 106 | image = var.image == "" ? "null" : var.image 107 | interactive = var.interactive ? true : false 108 | links = local.links == "[]" ? "null" : local.links 109 | linuxParameters = local.linuxParameters == "{}" ? "null" : local.linuxParameters 110 | logConfiguration = local.logConfiguration == "{}" ? "null" : local.logConfiguration 111 | memory = var.memory == 0 ? "null" : var.memory 112 | memoryReservation = var.memoryReservation == 0 ? "null" : var.memoryReservation 113 | mountPoints = local.mountPoints == "[]" ? "null" : local.mountPoints 114 | name = var.name == "" ? "null" : var.name 115 | portMappings = local.portMappings == "[]" ? "null" : local.portMappings 116 | privileged = var.privileged ? true : false 117 | pseudoTerminal = var.pseudoTerminal ? true : false 118 | readonlyRootFilesystem = var.readonlyRootFilesystem ? true : false 119 | repositoryCredentials = local.repositoryCredentials == "{}" ? "null" : local.repositoryCredentials 120 | resourceRequirements = local.resourceRequirements == "[]" ? "null" : local.resourceRequirements 121 | secrets = local.secrets == "[]" ? "null" : local.secrets 122 | systemControls = local.systemControls == "[]" ? "null" : local.systemControls 123 | ulimits = local.ulimits == "[]" ? "null" : local.ulimits 124 | user = var.user == "" ? "null" : var.user 125 | volumesFrom = local.volumesFrom == "[]" ? "null" : local.volumesFrom 126 | workingDirectory = var.workingDirectory == "" ? "null" : var.workingDirectory 127 | } 128 | ) 129 | } 130 | 131 | resource "aws_ecs_task_definition" "ecs_task_definition" { 132 | container_definitions = local.container_definitions 133 | execution_role_arn = var.execution_role_arn 134 | family = var.family 135 | ipc_mode = var.ipc_mode 136 | network_mode = var.network_mode 137 | pid_mode = var.pid_mode 138 | 139 | # Fargate requires cpu and memory to be defined at the task level 140 | cpu = var.cpu 141 | memory = var.memory 142 | 143 | dynamic "placement_constraints" { 144 | for_each = var.placement_constraints 145 | content { 146 | # TF-UPGRADE-TODO: The automatic upgrade tool can't predict 147 | # which keys might be set in maps assigned here, so it has 148 | # produced a comprehensive set here. Consider simplifying 149 | # this after confirming which keys can be set in practice. 150 | 151 | expression = lookup(placement_constraints.value, "expression", null) 152 | type = placement_constraints.value.type 153 | } 154 | } 155 | requires_compatibilities = var.requires_compatibilities 156 | task_role_arn = var.task_role_arn 157 | dynamic "volume" { 158 | for_each = var.volumes 159 | content { 160 | # TF-UPGRADE-TODO: The automatic upgrade tool can't predict 161 | # which keys might be set in maps assigned here, so it has 162 | # produced a comprehensive set here. Consider simplifying 163 | # this after confirming which keys can be set in practice. 164 | 165 | host_path = lookup(volume.value, "host_path", null) 166 | name = volume.value.name 167 | 168 | dynamic "docker_volume_configuration" { 169 | for_each = lookup(volume.value, "docker_volume_configuration", []) 170 | content { 171 | autoprovision = lookup(docker_volume_configuration.value, "autoprovision", null) 172 | driver = lookup(docker_volume_configuration.value, "driver", null) 173 | driver_opts = lookup(docker_volume_configuration.value, "driver_opts", null) 174 | labels = lookup(docker_volume_configuration.value, "labels", null) 175 | scope = lookup(docker_volume_configuration.value, "scope", null) 176 | } 177 | } 178 | dynamic "efs_volume_configuration" { 179 | for_each = lookup(volume.value, "efs_volume_configuration", []) 180 | content { 181 | file_system_id = lookup(efs_volume_configuration.value, "file_system_id", null) 182 | root_directory = lookup(efs_volume_configuration.value, "root_directory", null) 183 | } 184 | } 185 | } 186 | } 187 | tags = var.tags 188 | 189 | count = var.register_task_definition ? 1 : 0 190 | } 191 | -------------------------------------------------------------------------------- /modules/merge/README.md: -------------------------------------------------------------------------------- 1 | ## Contents 2 | 3 | - [Purpose](#purpose) 4 | - [Usage](#usage) 5 | - [Inputs](#inputs) 6 | - [Outputs](#outputs) 7 | 8 | ## Purpose 9 | 10 | AWS ECS task definitions allow for multiple containers to be defined. For example, the following task definition contains two container definitions: 11 | 12 | ```json 13 | { 14 | "containerDefinitions": [ 15 | { 16 | "name": "wordpress", 17 | "links": [ 18 | "mysql" 19 | ], 20 | "image": "wordpress", 21 | "essential": true, 22 | "portMappings": [ 23 | { 24 | "containerPort": 80, 25 | "hostPort": 80 26 | } 27 | ], 28 | "memory": 500, 29 | "cpu": 10 30 | }, 31 | { 32 | "environment": [ 33 | { 34 | "name": "MYSQL_ROOT_PASSWORD", 35 | "value": "password" 36 | } 37 | ], 38 | "name": "mysql", 39 | "image": "mysql", 40 | "cpu": 10, 41 | "memory": 500, 42 | "essential": true 43 | } 44 | ], 45 | "family": "hello_world" 46 | } 47 | ``` 48 | 49 | Due to some known limitations with the [HashiCorp Configuration Language](https://github.com/hashicorp/hcl) (HCL), the `merge` module allows for combining multiple container definitions. To see an example of the `merge` module in use, see the [usage](#usage) section. 50 | 51 | ## Usage 52 | 53 | The task definition defined in the purpose section can be created using a combination of the [`terraform-aws-ecs-task-definition`](https://github.com/mongodb/terraform-aws-ecs-task-definition) module and the `merge` module like so: 54 | 55 | ```hcl 56 | module "wordpress" { 57 | source = "mongodb/ecs-task-definition/aws" 58 | 59 | name = "wordpress" 60 | 61 | links = [ 62 | "mysql", 63 | ] 64 | 65 | image = "wordpress" 66 | essential = true 67 | 68 | portMappings = [ 69 | { 70 | containerPort = 80 71 | hostPort = 80 72 | }, 73 | ] 74 | 75 | memory = 500 76 | cpu = 10 77 | 78 | register_task_definition = false 79 | } 80 | 81 | module "mysql" { 82 | source = "mongodb/ecs-task-definition/aws" 83 | 84 | environment = [ 85 | { 86 | name = "MYSQL_ROOT_PASSWORD" 87 | value = "password" 88 | }, 89 | ] 90 | 91 | name = "mysql" 92 | image = "mysql" 93 | cpu = 10 94 | memory = 500 95 | essential = true 96 | 97 | register_task_definition = false 98 | } 99 | 100 | module "merged" { 101 | source = "mongodb/ecs-task-definition/aws//modules/merge" 102 | 103 | container_definitions = [ 104 | "${module.wordpress.container_definitions}", 105 | "${module.mysql.container_definitions}", 106 | ] 107 | } 108 | 109 | resource "aws_ecs_task_definition" "hello_world" { 110 | container_definitions = "${module.merged.container_definitions}" 111 | family = "hello_world" 112 | } 113 | ``` 114 | 115 | **Note:** The `register_task_definition` flag for both task definitions is required; otherwise a task definition containing a single container definition is registered created for both the `wordpress` and `mysql` services. 116 | 117 | 118 | ## Providers 119 | 120 | No provider. 121 | 122 | ## Inputs 123 | 124 | | Name | Description | Type | Default | Required | 125 | |------|-------------|------|---------|:-----:| 126 | | container\_definitions | A list of container definitions in JSON format that describe the different containers that make up your task | `list` | `[]` | no | 127 | 128 | ## Outputs 129 | 130 | | Name | Description | 131 | |------|-------------| 132 | | container\_definitions | A list of container definitions in JSON format that describe the different containers that make up your task | 133 | 134 | 135 | -------------------------------------------------------------------------------- /modules/merge/outputs.tf: -------------------------------------------------------------------------------- 1 | output "container_definitions" { 2 | description = "A list of container definitions in JSON format that describe the different containers that make up your task" 3 | value = format("[%s]", join(",", var.container_definitions)) 4 | } 5 | -------------------------------------------------------------------------------- /modules/merge/variables.tf: -------------------------------------------------------------------------------- 1 | variable "container_definitions" { 2 | default = [] 3 | description = "A list of container definitions in JSON format that describe the different containers that make up your task" 4 | } 5 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "The full Amazon Resource Name (ARN) of the task definition" 3 | value = join("", aws_ecs_task_definition.ecs_task_definition.*.arn) 4 | } 5 | 6 | output "container_definitions" { 7 | description = "A list of container definitions in JSON format that describe the different containers that make up your task" 8 | value = local.container_definitions 9 | } 10 | 11 | output "family" { 12 | description = "The family of your task definition, used as the definition name" 13 | value = join("", aws_ecs_task_definition.ecs_task_definition.*.family) 14 | } 15 | 16 | output "revision" { 17 | description = "The revision of the task in a particular family" 18 | value = join("", aws_ecs_task_definition.ecs_task_definition.*.revision) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /templates/container-definition.json.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "command": ${command}, 3 | "cpu": ${cpu}, 4 | "disableNetworking": ${disableNetworking}, 5 | "dnsSearchDomains": ${dnsSearchDomains}, 6 | "dnsServers": ${dnsServers}, 7 | "dockerLabels": ${dockerLabels}, 8 | "dockerSecurityOptions": ${dockerSecurityOptions}, 9 | "entryPoint": ${entryPoint}, 10 | "environment": ${environment}, 11 | "essential": ${essential}, 12 | "extraHosts": ${extraHosts}, 13 | "healthCheck": ${healthCheck}, 14 | "hostname": "${hostname}", 15 | "image": "${image}", 16 | "interactive": ${interactive}, 17 | "links": ${links}, 18 | "linuxParameters": ${linuxParameters}, 19 | "logConfiguration": ${logConfiguration}, 20 | "memory": ${memory}, 21 | "memoryReservation": ${memoryReservation}, 22 | "mountPoints": ${mountPoints}, 23 | "name": "${name}", 24 | "portMappings": ${portMappings}, 25 | "privileged": ${privileged}, 26 | "pseudoTerminal": ${pseudoTerminal}, 27 | "readonlyRootFilesystem": ${readonlyRootFilesystem}, 28 | "repositoryCredentials": ${repositoryCredentials}, 29 | "resourceRequirements": ${resourceRequirements}, 30 | "secrets": ${secrets}, 31 | "systemControls": ${systemControls}, 32 | "ulimits": ${ulimits}, 33 | "user": "${user}", 34 | "volumesFrom": ${volumesFrom}, 35 | "workingDirectory": "${workingDirectory}" 36 | } 37 | -------------------------------------------------------------------------------- /test/fixtures/multiple.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "command": null, 4 | "cpu": 256, 5 | "disableNetworking": false, 6 | "dnsSearchDomains": null, 7 | "dnsServers": null, 8 | "dockerLabels": null, 9 | "dockerSecurityOptions": null, 10 | "entryPoint": null, 11 | "environment": null, 12 | "essential": true, 13 | "extraHosts": null, 14 | "healthCheck": null, 15 | "hostname": null, 16 | "image": "mongo:3.6", 17 | "interactive": false, 18 | "links": null, 19 | "linuxParameters": null, 20 | "logConfiguration": null, 21 | "memory": 512, 22 | "memoryReservation": null, 23 | "mountPoints": null, 24 | "name": "mongodb", 25 | "portMappings": [ 26 | { 27 | "containerPort": 27017, 28 | "protocol": "TCP" 29 | } 30 | ], 31 | "privileged": false, 32 | "pseudoTerminal": false, 33 | "readonlyRootFilesystem": false, 34 | "repositoryCredentials": null, 35 | "resourceRequirements": null, 36 | "secrets": null, 37 | "systemControls": null, 38 | "ulimits": null, 39 | "user": null, 40 | "volumesFrom": null, 41 | "workingDirectory": null 42 | }, 43 | { 44 | "command": null, 45 | "cpu": 256, 46 | "disableNetworking": false, 47 | "dnsSearchDomains": null, 48 | "dnsServers": null, 49 | "dockerLabels": null, 50 | "dockerSecurityOptions": null, 51 | "entryPoint": null, 52 | "environment": null, 53 | "essential": true, 54 | "extraHosts": null, 55 | "healthCheck": null, 56 | "hostname": null, 57 | "image": "redis:alpine", 58 | "interactive": false, 59 | "links": null, 60 | "linuxParameters": null, 61 | "logConfiguration": { 62 | "logDriver": "awslogs", 63 | "options": { 64 | "awslogs-group": "awslogs-mongodb", 65 | "awslogs-region": "us-east-1" 66 | } 67 | }, 68 | "memory": 512, 69 | "memoryReservation": null, 70 | "mountPoints": null, 71 | "name": "redis", 72 | "portMappings": [ 73 | { 74 | "containerPort": 6379, 75 | "protocol": "TCP" 76 | } 77 | ], 78 | "privileged": false, 79 | "pseudoTerminal": false, 80 | "readonlyRootFilesystem": false, 81 | "repositoryCredentials": null, 82 | "resourceRequirements": null, 83 | "secrets": null, 84 | "systemControls": null, 85 | "ulimits": null, 86 | "user": null, 87 | "volumesFrom": null, 88 | "workingDirectory": null 89 | } 90 | ] 91 | -------------------------------------------------------------------------------- /test/fixtures/single.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "command": null, 4 | "cpu": 256, 5 | "disableNetworking": false, 6 | "dnsSearchDomains": null, 7 | "dnsServers": null, 8 | "dockerLabels": null, 9 | "dockerSecurityOptions": null, 10 | "entryPoint": null, 11 | "environment": [ 12 | { 13 | "name": "AWS_DEFAULT_REGION", 14 | "value": "us-east-1" 15 | } 16 | ], 17 | "essential": true, 18 | "extraHosts": null, 19 | "healthCheck": { 20 | "command": [ 21 | "echo" 22 | ], 23 | "interval": 30, 24 | "retries": 3, 25 | "startPeriod": 0, 26 | "timeout": 5 27 | }, 28 | "hostname": null, 29 | "image": "mongo:3.6", 30 | "interactive": false, 31 | "links": null, 32 | "linuxParameters": { 33 | "capabilities": { 34 | "add": [ 35 | "AUDIT_CONTROL", 36 | "AUDIT_WRITE" 37 | ], 38 | "drop": [ 39 | "SYS_RAWIO", 40 | "SYS_TIME" 41 | ] 42 | }, 43 | "devices": [ 44 | { 45 | "containerPath": "/dev/disk0", 46 | "hostPath": "/dev/disk0", 47 | "permissions": [ 48 | "read" 49 | ] 50 | } 51 | ], 52 | "initProcessEnabled": true, 53 | "sharedMemorySize": 512, 54 | "tmpfs": [ 55 | { 56 | "containerPath": "/tmp", 57 | "mountOptions": [ 58 | "defaults" 59 | ], 60 | "size": 512 61 | } 62 | ] 63 | }, 64 | "logConfiguration": { 65 | "logDriver": "awslogs", 66 | "options": { 67 | "awslogs-group": "awslogs-mongodb", 68 | "awslogs-region": "us-east-1" 69 | } 70 | }, 71 | "memory": 512, 72 | "memoryReservation": 512, 73 | "mountPoints": [ 74 | { 75 | "containerPath": "/dev/disk0", 76 | "readOnly": true, 77 | "sourceVolume": "data" 78 | } 79 | ], 80 | "name": "mongo", 81 | "portMappings": [ 82 | { 83 | "containerPort": 8080, 84 | "hostPort": 0, 85 | "protocol": "tcp" 86 | } 87 | ], 88 | "privileged": false, 89 | "pseudoTerminal": false, 90 | "readonlyRootFilesystem": false, 91 | "repositoryCredentials": null, 92 | "resourceRequirements": null, 93 | "secrets": null, 94 | "systemControls": null, 95 | "ulimits": [ 96 | { 97 | "hardLimit": 1024, 98 | "name": "cpu", 99 | "softLimit": 1024 100 | } 101 | ], 102 | "user": "root", 103 | "volumesFrom": null, 104 | "workingDirectory": "~/project" 105 | } 106 | ] 107 | -------------------------------------------------------------------------------- /test/terraform_ecs_task_definition_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "io/ioutil" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/gruntwork-io/terratest/modules/terraform" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func minify(s string) string { 13 | return strings.Replace(strings.Replace(s, "\n", "", -1), " ", "", -1) 14 | } 15 | 16 | func TestSingleContainerDefinition(t *testing.T) { 17 | t.Parallel() 18 | options := &terraform.Options{ 19 | TerraformDir: "..", 20 | VarFiles: []string{"test/varfile.tfvars"}, 21 | } 22 | defer terraform.Destroy(t, options) 23 | terraform.InitAndApply(t, options) 24 | b, err := ioutil.ReadFile("fixtures/single.json") 25 | if err != nil { 26 | t.Error(err) 27 | } 28 | expected := minify(string(b)) 29 | actual := minify(terraform.Output(t, options, "container_definitions")) 30 | assert.Equal(t, expected, actual) 31 | } 32 | 33 | func TestMultipleContainerDefinitions(t *testing.T) { 34 | t.Parallel() 35 | options := &terraform.Options{ 36 | TerraformDir: "../examples/terraform-task-definition-multiple-containers", 37 | } 38 | defer terraform.Destroy(t, options) 39 | terraform.InitAndApply(t, options) 40 | b, err := ioutil.ReadFile("fixtures/multiple.json") 41 | if err != nil { 42 | t.Error(err) 43 | } 44 | expected := minify(string(b)) 45 | actual := minify(terraform.Output(t, options, "container_definitions")) 46 | assert.Equal(t, expected, actual) 47 | } 48 | -------------------------------------------------------------------------------- /test/varfile.tfvars: -------------------------------------------------------------------------------- 1 | environment = [ 2 | { 3 | name = "AWS_DEFAULT_REGION" 4 | value = "us-east-1" 5 | }, 6 | ] 7 | 8 | family = "default" 9 | 10 | healthCheck = { 11 | command = ["echo"] 12 | interval = 30 13 | retries = 3 14 | startPeriod = 0 15 | timeout = 5 16 | } 17 | 18 | image = "mongo:3.6" 19 | 20 | linuxParameters = { 21 | capabilities = { 22 | add = ["AUDIT_CONTROL", "AUDIT_WRITE"] 23 | drop = ["SYS_RAWIO", "SYS_TIME"] 24 | } 25 | 26 | devices = [ 27 | { 28 | containerPath = "/dev/disk0" 29 | hostPath = "/dev/disk0" 30 | permissions = ["read"] 31 | }, 32 | ] 33 | 34 | initProcessEnabled = true 35 | sharedMemorySize = 512 36 | 37 | tmpfs = [ 38 | { 39 | containerPath = "/tmp" 40 | mountOptions = ["defaults"] 41 | size = 512 42 | }, 43 | ] 44 | } 45 | 46 | logConfiguration = { 47 | logDriver = "awslogs" 48 | options = { 49 | awslogs-group = "awslogs-mongodb" 50 | awslogs-region = "us-east-1" 51 | } 52 | } 53 | 54 | memoryReservation = 512 55 | 56 | mountPoints = [ 57 | { 58 | containerPath = "/dev/disk0" 59 | readOnly = true 60 | sourceVolume = "data" 61 | }, 62 | ] 63 | 64 | name = "mongo" 65 | 66 | portMappings = [ 67 | { 68 | containerPort = 8080 69 | hostPort = 0 70 | protocol = "tcp" 71 | }, 72 | ] 73 | 74 | ulimits = [ 75 | { 76 | hardLimit = 1024 77 | name = "cpu" 78 | softLimit = 1024 79 | }, 80 | ] 81 | 82 | user = "root" 83 | 84 | volumes = [ 85 | { 86 | name = "data" 87 | }, 88 | ] 89 | 90 | workingDirectory = "~/project" 91 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | # Container definitions are used in task definitions to describe the different containers that are launched as part of a task. 2 | # https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html 3 | 4 | variable "command" { 5 | default = [] 6 | description = "The command that is passed to the container" 7 | type = list(string) 8 | } 9 | 10 | variable "cpu" { 11 | default = 256 12 | description = "The number of cpu units reserved for the container" 13 | type = number 14 | } 15 | 16 | variable "disableNetworking" { 17 | default = false 18 | description = "When this parameter is true, networking is disabled within the container" 19 | } 20 | 21 | variable "dnsSearchDomains" { 22 | default = [] 23 | description = "A list of DNS search domains that are presented to the container" 24 | type = list(string) 25 | } 26 | 27 | variable "dnsServers" { 28 | default = [] 29 | description = "A list of DNS servers that are presented to the container" 30 | type = list(string) 31 | } 32 | 33 | variable "dockerLabels" { 34 | default = {} 35 | description = "A key/value map of labels to add to the container" 36 | type = map(string) 37 | } 38 | 39 | variable "dockerSecurityOptions" { 40 | default = [] 41 | description = "A list of strings to provide custom labels for SELinux and AppArmor multi-level security systems" 42 | type = list(string) 43 | } 44 | 45 | variable "entryPoint" { 46 | default = [] 47 | description = "The entry point that is passed to the container" 48 | type = list(string) 49 | } 50 | 51 | variable "environment" { 52 | default = [] 53 | description = "The environment variables to pass to a container" 54 | type = list(map(string)) 55 | } 56 | 57 | variable "essential" { 58 | default = true 59 | description = "If the essential parameter of a container is marked as true, and that container fails or stops for any reason, all other containers that are part of the task are stopped" 60 | } 61 | 62 | variable "execution_role_arn" { 63 | default = "" 64 | description = "The Amazon Resource Name (ARN) of the task execution role that the Amazon ECS container agent and the Docker daemon can assume" 65 | } 66 | 67 | variable "extraHosts" { 68 | default = [] 69 | description = "A list of hostnames and IP address mappings to append to the /etc/hosts file on the container" 70 | 71 | type = list(object({ 72 | ipAddress = string 73 | hostname = string 74 | })) 75 | } 76 | 77 | variable "family" { 78 | description = "You must specify a family for a task definition, which allows you to track multiple versions of the same task definition" 79 | } 80 | 81 | variable "healthCheck" { 82 | default = {} 83 | description = "The health check command and associated configuration parameters for the container" 84 | type = any 85 | } 86 | 87 | variable "hostname" { 88 | default = "" 89 | description = "The hostname to use for your container" 90 | } 91 | 92 | variable "image" { 93 | default = "" 94 | description = "The image used to start a container" 95 | } 96 | 97 | variable "interactive" { 98 | default = false 99 | description = "When this parameter is true, this allows you to deploy containerized applications that require stdin or a tty to be allocated" 100 | } 101 | 102 | variable "ipc_mode" { 103 | default = null 104 | description = "The IPC resource namespace to use for the containers in the task" 105 | } 106 | 107 | variable "links" { 108 | default = [] 109 | description = "The link parameter allows containers to communicate with each other without the need for port mappings" 110 | type = list(string) 111 | } 112 | 113 | variable "linuxParameters" { 114 | default = {} 115 | description = "Linux-specific modifications that are applied to the container, such as Linux KernelCapabilities" 116 | type = any 117 | } 118 | 119 | variable "logConfiguration" { 120 | default = {} 121 | description = "The log configuration specification for the container" 122 | type = any 123 | } 124 | 125 | variable "memory" { 126 | default = 512 127 | description = "The hard limit (in MiB) of memory to present to the container" 128 | type = number 129 | } 130 | 131 | variable "memoryReservation" { 132 | default = 0 133 | description = "The soft limit (in MiB) of memory to reserve for the container" 134 | } 135 | 136 | variable "mountPoints" { 137 | default = [] 138 | description = "The mount points for data volumes in your container" 139 | type = list(any) 140 | } 141 | 142 | variable "name" { 143 | default = "" 144 | description = "The name of a container" 145 | } 146 | 147 | variable "network_mode" { 148 | default = "bridge" 149 | description = "The Docker networking mode to use for the containers in the task" 150 | } 151 | 152 | variable "pid_mode" { 153 | default = null 154 | description = "The process namespace to use for the containers in the task" 155 | } 156 | 157 | variable "placement_constraints" { 158 | default = [] 159 | description = "An array of placement constraint objects to use for the task" 160 | type = list(object({ 161 | type = string 162 | expression = string 163 | })) 164 | } 165 | 166 | variable "portMappings" { 167 | default = [] 168 | description = "The list of port mappings for the container" 169 | type = list(any) 170 | } 171 | 172 | variable "privileged" { 173 | default = false 174 | description = "When this parameter is true, the container is given elevated privileges on the host container instance (similar to the root user)" 175 | } 176 | 177 | variable "pseudoTerminal" { 178 | default = false 179 | description = "When this parameter is true, a TTY is allocated" 180 | } 181 | 182 | variable "readonlyRootFilesystem" { 183 | default = false 184 | description = "When this parameter is true, the container is given read-only access to its root file system" 185 | } 186 | 187 | variable "register_task_definition" { 188 | default = true 189 | description = "Registers a new task definition from the supplied family and containerDefinitions" 190 | } 191 | 192 | variable "repositoryCredentials" { 193 | default = {} 194 | description = "The private repository authentication credentials to use" 195 | type = map(string) 196 | } 197 | 198 | variable "requires_compatibilities" { 199 | default = [] 200 | description = "The launch type required by the task" 201 | type = list(string) 202 | } 203 | 204 | variable "resourceRequirements" { 205 | default = [] 206 | description = "The type and amount of a resource to assign to a container" 207 | type = list(string) 208 | } 209 | 210 | variable "secrets" { 211 | default = [] 212 | description = "The secrets to pass to the container" 213 | type = list(map(string)) 214 | } 215 | 216 | variable "systemControls" { 217 | default = [] 218 | description = "A list of namespaced kernel parameters to set in the container" 219 | type = list(string) 220 | } 221 | 222 | variable "tags" { 223 | default = {} 224 | description = "The metadata that you apply to the task definition to help you categorize and organize them" 225 | type = map(string) 226 | } 227 | 228 | variable "task_role_arn" { 229 | default = "" 230 | description = "The short name or full Amazon Resource Name (ARN) of the IAM role that containers in this task can assume" 231 | } 232 | 233 | variable "ulimits" { 234 | default = [] 235 | description = "A list of ulimits to set in the container" 236 | type = list(any) 237 | } 238 | 239 | variable "user" { 240 | default = "" 241 | description = "The user name to use inside the container" 242 | } 243 | 244 | variable "volumes" { 245 | default = [] 246 | description = "A list of volume definitions in JSON format that containers in your task may use" 247 | type = list(any) 248 | } 249 | 250 | variable "volumesFrom" { 251 | default = [] 252 | description = "Data volumes to mount from another container" 253 | 254 | type = list(object({ 255 | readOnly = bool 256 | sourceContainer = string 257 | })) 258 | } 259 | 260 | variable "workingDirectory" { 261 | default = "" 262 | description = "The working directory in which to run commands inside the container" 263 | } 264 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | 2 | terraform { 3 | required_version = ">= 0.12" 4 | } 5 | --------------------------------------------------------------------------------