├── .github
└── workflows
│ ├── json.yml
│ ├── markdown.yml
│ ├── terraform.yml
│ └── yaml.yml
├── .gitignore
├── .markdownlint.json
├── .prettierignore
├── .yamllint
├── LICENSE
├── Makefile
├── README.md
├── VERSION
├── examples
├── complete
│ ├── main.tf
│ ├── outputs.tf
│ └── providers.tf
└── minimal
│ ├── main.tf
│ ├── outputs.tf
│ └── providers.tf
├── main.tf
├── modules
└── .gitkeep
├── outputs.tf
├── variables.tf
└── versions.tf
/.github/workflows/json.yml:
--------------------------------------------------------------------------------
1 | name: JSON
2 | on:
3 | pull_request:
4 |
5 | jobs:
6 | format:
7 | name: Format
8 | runs-on: ubuntu-latest
9 | timeout-minutes: 5
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v2.1.0
13 | - name: Prettier
14 | run: docker run --rm -v ${PWD}:/work tmknom/prettier --list-different --parser=json '**/*.json'
15 |
--------------------------------------------------------------------------------
/.github/workflows/markdown.yml:
--------------------------------------------------------------------------------
1 | name: Markdown
2 | on:
3 | pull_request:
4 |
5 | jobs:
6 | lint:
7 | name: Lint
8 | runs-on: ubuntu-latest
9 | timeout-minutes: 5
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v2.1.0
13 | - name: markdownlint
14 | run: docker run --rm -i -v ${PWD}:/work tmknom/markdownlint
15 |
16 | format:
17 | name: Format
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 5
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v2.1.0
23 | - name: Prettier
24 | run: docker run --rm -v ${PWD}:/work tmknom/prettier --list-different --parser=markdown '**/*.md'
25 |
--------------------------------------------------------------------------------
/.github/workflows/terraform.yml:
--------------------------------------------------------------------------------
1 | name: Terraform
2 | on:
3 | pull_request:
4 |
5 | env:
6 | TERRAFORM_VERSION: 0.12.24
7 | AWS_DEFAULT_REGION: us-east-1
8 |
9 | jobs:
10 | format:
11 | name: Format
12 | runs-on: ubuntu-latest
13 | timeout-minutes: 5
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2.1.0
17 | - name: Format all
18 | uses: hashicorp/terraform-github-actions@v0.8.0
19 | env:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 | with:
22 | tf_actions_version: ${{ env.TERRAFORM_VERSION }}
23 | tf_actions_comment: true
24 | tf_actions_subcommand: fmt
25 |
26 | validate:
27 | name: Validate
28 | runs-on: ubuntu-latest
29 | timeout-minutes: 5
30 | strategy:
31 | matrix:
32 | dir:
33 | - .
34 | - examples/minimal
35 | - examples/complete
36 | steps:
37 | - name: Checkout
38 | uses: actions/checkout@v2.1.0
39 | - name: Init
40 | uses: hashicorp/terraform-github-actions@v0.8.0
41 | env:
42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | with:
44 | tf_actions_version: ${{ env.TERRAFORM_VERSION }}
45 | tf_actions_working_dir: ${{ matrix.dir }}
46 | tf_actions_comment: true
47 | tf_actions_subcommand: init
48 | - name: Validate
49 | uses: hashicorp/terraform-github-actions@v0.8.0
50 | env:
51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52 | with:
53 | tf_actions_version: ${{ env.TERRAFORM_VERSION }}
54 | tf_actions_working_dir: ${{ matrix.dir }}
55 | tf_actions_comment: true
56 | tf_actions_subcommand: validate
57 |
58 | lint:
59 | name: Lint
60 | runs-on: ubuntu-latest
61 | timeout-minutes: 5
62 | steps:
63 | - name: Checkout
64 | uses: actions/checkout@v2.1.0
65 | - name: TFLint
66 | run: docker run --rm -v ${PWD}:/data wata727/tflint
67 |
--------------------------------------------------------------------------------
/.github/workflows/yaml.yml:
--------------------------------------------------------------------------------
1 | name: YAML
2 | on:
3 | pull_request:
4 |
5 | jobs:
6 | lint:
7 | name: Lint
8 | runs-on: ubuntu-latest
9 | timeout-minutes: 5
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v2.1.0
13 | - name: yamllint
14 | run: docker run --rm -v ${PWD}:/work tmknom/yamllint --strict .
15 |
16 | format:
17 | name: Format
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 5
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v2.1.0
23 | - name: Prettier
24 | run: docker run --rm -v ${PWD}:/work tmknom/prettier --list-different --parser=yaml '**/*.y*ml'
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 |
4 | # .tfstate files
5 | *.tfstate
6 | *.tfstate.*
7 |
8 | # .tfvars files
9 | *.tfvars
10 |
11 | # IntelliJ
12 | .idea/
13 |
14 | # direnv
15 | .envrc
16 |
17 | # Auto include makefiles
18 | .Makefile.terraform
19 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "no-inline-html": false,
3 | "line-length": false
4 | }
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # https://prettier.io/docs/en/cli.html#ignore-path
2 |
3 | **/.terraform/*
4 |
--------------------------------------------------------------------------------
/.yamllint:
--------------------------------------------------------------------------------
1 | extends: default
2 |
3 | rules:
4 | document-start: disable
5 | truthy:
6 | allowed-values: ['true', 'false', 'on']
7 | line-length:
8 | max: 120
9 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # https://github.com/tmknom/template-terraform-module
2 | TERRAFORM_VERSION := 0.12.24
3 | -include .Makefile.terraform
4 |
5 | .Makefile.terraform:
6 | curl -sSL https://raw.githubusercontent.com/tmknom/template-terraform-module/0.2.7/Makefile.terraform -o .Makefile.terraform
7 |
8 | MINIMAL_DIR := ./examples/minimal
9 | COMPLETE_DIR := ./examples/complete
10 |
11 | plan-minimal: ## Run terraform plan examples/minimal
12 | $(call terraform,${MINIMAL_DIR},init,)
13 | $(call terraform,${MINIMAL_DIR},plan,)
14 |
15 | apply-minimal: ## Run terraform apply examples/minimal
16 | $(call terraform,${MINIMAL_DIR},apply,)
17 |
18 | destroy-minimal: ## Run terraform destroy examples/minimal
19 | $(call terraform,${MINIMAL_DIR},destroy,)
20 |
21 | plan-complete: ## Run terraform plan examples/complete
22 | $(call terraform,${COMPLETE_DIR},init,)
23 | $(call terraform,${COMPLETE_DIR},plan,)
24 |
25 | apply-complete: ## Run terraform apply examples/complete
26 | $(call terraform,${COMPLETE_DIR},apply,)
27 |
28 | destroy-complete: ## Run terraform destroy examples/complete
29 | $(call terraform,${COMPLETE_DIR},destroy,)
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # terraform-aws-ecs-fargate
2 |
3 | [](https://github.com/tmknom/terraform-aws-ecs-fargate/actions?query=workflow%3ATerraform)
4 | [](https://github.com/tmknom/terraform-aws-ecs-fargate/actions?query=workflow%3AMarkdown)
5 | [](https://github.com/tmknom/terraform-aws-ecs-fargate/actions?query=workflow%3AYAML)
6 | [](https://github.com/tmknom/terraform-aws-ecs-fargate/actions?query=workflow%3AJSON)
7 | [](https://registry.terraform.io/modules/tmknom/ecs-fargate/aws)
8 | [](https://opensource.org/licenses/Apache-2.0)
9 |
10 | Terraform module which creates ECS Fargate resources on AWS.
11 |
12 | ## Description
13 |
14 | Provision [ECS Service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html) and
15 | [ECS Task Definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html).
16 |
17 | This module provides recommended settings:
18 |
19 | - Fargate launch type
20 | - Disable assign public ip address
21 |
22 | ## Usage
23 |
24 | ### Minimal
25 |
26 | ```hcl
27 | module "ecs_fargate" {
28 | source = "git::https://github.com/tmknom/terraform-aws-ecs-fargate.git?ref=tags/2.0.0"
29 | name = "example"
30 | container_name = "nginx"
31 | container_port = "80"
32 | cluster = var.ecs_cluster_arn
33 | subnets = var.subnets
34 | target_group_arn = var.target_group_arn
35 | vpc_id = var.vpc_id
36 | container_definitions = var.container_definitions
37 | }
38 | ```
39 |
40 | ### Complete
41 |
42 | ```hcl
43 | module "ecs_fargate" {
44 | source = "git::https://github.com/tmknom/terraform-aws-ecs-fargate.git?ref=tags/2.0.0"
45 | name = "example"
46 | container_name = "nginx"
47 | container_port = "80"
48 | cluster = var.ecs_cluster_arn
49 | subnets = var.subnets
50 | target_group_arn = var.target_group_arn
51 | vpc_id = var.vpc_id
52 | container_definitions = var.container_definitions
53 |
54 | desired_count = 2
55 | deployment_maximum_percent = 200
56 | deployment_minimum_healthy_percent = 100
57 | deployment_controller_type = "ECS"
58 | assign_public_ip = true
59 | health_check_grace_period_seconds = 10
60 | platform_version = "1.4.0"
61 | source_cidr_blocks = ["0.0.0.0/0"]
62 | cpu = 256
63 | memory = 512
64 | requires_compatibilities = ["FARGATE"]
65 | iam_path = "/service_role/"
66 | description = "This is example"
67 | enabled = true
68 |
69 | create_ecs_task_execution_role = false
70 | ecs_task_execution_role_arn = var.ecs_task_execution_role_arn
71 |
72 | tags = {
73 | Environment = "prod"
74 | }
75 | }
76 | ```
77 |
78 | ## Examples
79 |
80 | - [Minimal](https://github.com/tmknom/terraform-aws-ecs-fargate/tree/master/examples/minimal)
81 | - [Complete](https://github.com/tmknom/terraform-aws-ecs-fargate/tree/master/examples/complete)
82 |
83 |
84 |
85 | ## Requirements
86 |
87 | | Name | Version |
88 | | --------- | ------- |
89 | | terraform | >= 0.12 |
90 |
91 | ## Providers
92 |
93 | | Name | Version |
94 | | ---- | ------- |
95 | | aws | n/a |
96 |
97 | ## Inputs
98 |
99 | | Name | Description | Type | Default | Required |
100 | | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------------------- | :------: |
101 | | cluster | ARN of an ECS cluster. | `string` | n/a | yes |
102 | | container_definitions | A list of valid container definitions provided as a single valid JSON document. | `string` | n/a | yes |
103 | | container_name | The name of the container to associate with the load balancer (as it appears in a container definition). | `string` | n/a | yes |
104 | | container_port | The port on the container to associate with the load balancer. | `string` | n/a | yes |
105 | | name | The name of ecs service. | `string` | n/a | yes |
106 | | subnets | The subnets associated with the task or service. | `list(string)` | n/a | yes |
107 | | target_group_arn | The ARN of the Load Balancer target group to associate with the service. | `string` | n/a | yes |
108 | | vpc_id | VPC Id to associate with ECS Service. | `string` | n/a | yes |
109 | | assign_public_ip | Assign a public IP address to the ENI (Fargate launch type only). Valid values are true or false. | `string` | `false` | no |
110 | | cpu | The number of cpu units used by the task. | `string` | `"256"` | no |
111 | | create_ecs_task_execution_role | Specify true to indicate that ECS Task Execution IAM Role creation. | `string` | `true` | no |
112 | | deployment_controller_type | Type of deployment controller. Valid values: CODE_DEPLOY, ECS. | `string` | `"ECS"` | no |
113 | | deployment_maximum_percent | The upper limit (as a percentage of the service's desiredCount) of the number of running tasks that can be running in a service during a deployment. | `string` | `200` | no |
114 | | deployment_minimum_healthy_percent | The lower limit (as a percentage of the service's desiredCount) of the number of running tasks that must remain running and healthy in a service during a deployment. | `string` | `100` | no |
115 | | description | The description of the all resources. | `string` | `"Managed by Terraform"` | no |
116 | | desired_count | The number of instances of the task definition to place and keep running. | `string` | `0` | no |
117 | | ecs_task_execution_role_arn | The ARN of the ECS Task Execution IAM Role. | `string` | `""` | no |
118 | | enabled | Set to false to prevent the module from creating anything. | `string` | `true` | no |
119 | | health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. | `string` | `60` | no |
120 | | iam_path | Path in which to create the IAM Role and the IAM Policy. | `string` | `"/"` | no |
121 | | memory | The amount (in MiB) of memory used by the task. | `string` | `"512"` | no |
122 | | platform_version | The platform version on which to run your service. | `string` | `"1.4.0"` | no |
123 | | requires_compatibilities | A set of launch types required by the task. The valid values are EC2 and FARGATE. | `list(string)` |
[
"FARGATE"
]
| no |
124 | | source_cidr_blocks | List of source CIDR blocks. | `list(string)` | [
"0.0.0.0/0"
]
| no |
125 | | tags | A mapping of tags to assign to all resources. | `map(string)` | `{}` | no |
126 |
127 | ## Outputs
128 |
129 | | Name | Description |
130 | | ---------------------------- | --------------------------------------------------------------------- |
131 | | ecs_service_cluster | The Amazon Resource Name (ARN) of cluster which the service runs on. |
132 | | ecs_service_desired_count | The number of instances of the task definition. |
133 | | ecs_service_iam_role | The ARN of IAM role used for ELB. |
134 | | ecs_service_id | The Amazon Resource Name (ARN) that identifies the service. |
135 | | ecs_service_name | The name of the service. |
136 | | ecs_task_definition_arn | Full ARN of the Task Definition (including both family and revision). |
137 | | ecs_task_definition_family | The family of the Task Definition. |
138 | | ecs_task_definition_revision | The revision of the task in a particular family. |
139 | | iam_policy_arn | The ARN assigned by AWS to this IAM Policy. |
140 | | iam_policy_description | The description of the IAM Policy. |
141 | | iam_policy_document | The policy document of the IAM Policy. |
142 | | iam_policy_id | The IAM Policy's ID. |
143 | | iam_policy_name | The name of the IAM Policy. |
144 | | iam_policy_path | The path of the IAM Policy. |
145 | | iam_role_arn | The Amazon Resource Name (ARN) specifying the IAM Role. |
146 | | iam_role_create_date | The creation date of the IAM Role. |
147 | | iam_role_description | The description of the IAM Role. |
148 | | iam_role_name | The name of the IAM Role. |
149 | | iam_role_unique_id | The stable and unique string identifying the IAM Role. |
150 | | security_group_arn | The ARN of the ECS Service security group. |
151 | | security_group_description | The description of the ECS Service security group. |
152 | | security_group_egress | The egress rules of the ECS Service security group. |
153 | | security_group_id | The ID of the ECS Service security group. |
154 | | security_group_ingress | The ingress rules of the ECS Service security group. |
155 | | security_group_name | The name of the ECS Service security group. |
156 | | security_group_owner_id | The owner ID of the ECS Service security group. |
157 | | security_group_vpc_id | The VPC ID of the ECS Service security group. |
158 |
159 |
160 |
161 | ## Development
162 |
163 | ### Development Requirements
164 |
165 | - [Docker](https://www.docker.com/)
166 |
167 | ### Configure environment variables
168 |
169 | ```shell
170 | export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
171 | export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
172 | export AWS_DEFAULT_REGION=ap-northeast-1
173 | ```
174 |
175 | ### Installation
176 |
177 | ```shell
178 | git clone git@github.com:tmknom/terraform-aws-ecs-fargate.git
179 | cd terraform-aws-ecs-fargate
180 | make install
181 | ```
182 |
183 | ### Makefile targets
184 |
185 | ```text
186 | apply-complete Run terraform apply examples/complete
187 | apply-minimal Run terraform apply examples/minimal
188 | check-format Check format code
189 | clean Clean .terraform
190 | destroy-complete Run terraform destroy examples/complete
191 | destroy-minimal Run terraform destroy examples/minimal
192 | diff Word diff
193 | docs Generate docs
194 | format Format code
195 | help Show help
196 | install Install requirements
197 | lint Lint code
198 | plan-complete Run terraform plan examples/complete
199 | plan-minimal Run terraform plan examples/minimal
200 | release Release GitHub and Terraform Module Registry
201 | upgrade Upgrade makefile
202 | ```
203 |
204 | ### Releasing new versions
205 |
206 | Bump VERSION file, and run `make release`.
207 |
208 | ### Terraform Module Registry
209 |
210 | -
211 |
212 | ## License
213 |
214 | Apache 2 Licensed. See LICENSE for full details.
215 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2.0.0
2 |
--------------------------------------------------------------------------------
/examples/complete/main.tf:
--------------------------------------------------------------------------------
1 | module "ecs_fargate" {
2 | source = "../../"
3 | name = "example"
4 | container_name = local.container_name
5 | container_port = local.container_port
6 | cluster = aws_ecs_cluster.example.arn
7 | subnets = module.vpc.public_subnet_ids
8 | target_group_arn = module.alb.alb_target_group_arn
9 | vpc_id = module.vpc.vpc_id
10 |
11 | container_definitions = jsonencode([
12 | {
13 | name = local.container_name
14 | image = "nginx:latest"
15 | essential = true
16 | portMappings = [
17 | {
18 | containerPort = local.container_port
19 | protocol = "tcp"
20 | }
21 | ]
22 | }
23 | ])
24 |
25 | desired_count = 2
26 | deployment_maximum_percent = 200
27 | deployment_minimum_healthy_percent = 100
28 | deployment_controller_type = "ECS"
29 | assign_public_ip = true
30 | health_check_grace_period_seconds = 10
31 | platform_version = "LATEST"
32 | source_cidr_blocks = ["0.0.0.0/0"]
33 | cpu = 256
34 | memory = 512
35 | requires_compatibilities = ["FARGATE"]
36 | iam_path = "/service_role/"
37 | description = "This is example"
38 | enabled = true
39 |
40 | create_ecs_task_execution_role = false
41 | ecs_task_execution_role_arn = aws_iam_role.default.arn
42 |
43 | tags = {
44 | Environment = "prod"
45 | }
46 | }
47 |
48 | resource "aws_iam_role" "default" {
49 | name = "ecs-task-execution-for-ecs-fargate"
50 | assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
51 | }
52 |
53 | data "aws_iam_policy_document" "assume_role_policy" {
54 | statement {
55 | actions = ["sts:AssumeRole"]
56 |
57 | principals {
58 | type = "Service"
59 | identifiers = ["ecs-tasks.amazonaws.com"]
60 | }
61 | }
62 | }
63 |
64 | resource "aws_iam_policy" "default" {
65 | name = aws_iam_role.default.name
66 | policy = data.aws_iam_policy.ecs_task_execution.policy
67 | }
68 |
69 | resource "aws_iam_role_policy_attachment" "default" {
70 | role = aws_iam_role.default.name
71 | policy_arn = aws_iam_policy.default.arn
72 | }
73 |
74 | data "aws_iam_policy" "ecs_task_execution" {
75 | arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
76 | }
77 |
78 | locals {
79 | container_name = "example"
80 | container_port = tonumber(module.alb.alb_target_group_port)
81 | }
82 |
83 | resource "aws_ecs_cluster" "example" {
84 | name = "default"
85 | }
86 |
87 | module "alb" {
88 | source = "git::https://github.com/tmknom/terraform-aws-alb.git?ref=tags/2.1.0"
89 | name = "ecs-fargate"
90 | vpc_id = module.vpc.vpc_id
91 | subnets = module.vpc.public_subnet_ids
92 | access_logs_bucket = module.s3_lb_log.s3_bucket_id
93 | enable_https_listener = false
94 | enable_http_listener = true
95 | enable_deletion_protection = false
96 | }
97 |
98 | module "s3_lb_log" {
99 | source = "git::https://github.com/tmknom/terraform-aws-s3-lb-log.git?ref=tags/2.0.0"
100 | name = "s3-lb-log-ecs-fargate-${data.aws_caller_identity.current.account_id}"
101 | logging_target_bucket = module.s3_access_log.s3_bucket_id
102 | force_destroy = true
103 | }
104 |
105 | module "s3_access_log" {
106 | source = "git::https://github.com/tmknom/terraform-aws-s3-access-log.git?ref=tags/2.0.0"
107 | name = "s3-access-log-ecs-fargate-${data.aws_caller_identity.current.account_id}"
108 | force_destroy = true
109 | }
110 |
111 | module "vpc" {
112 | source = "git::https://github.com/tmknom/terraform-aws-vpc.git?ref=tags/2.0.1"
113 | cidr_block = local.cidr_block
114 | name = "ecs-fargate"
115 | public_subnet_cidr_blocks = [cidrsubnet(local.cidr_block, 8, 0), cidrsubnet(local.cidr_block, 8, 1)]
116 | public_availability_zones = data.aws_availability_zones.available.names
117 | }
118 |
119 | locals {
120 | cidr_block = "10.255.0.0/16"
121 | }
122 |
123 | data "aws_caller_identity" "current" {}
124 |
125 | data "aws_availability_zones" "available" {}
126 |
--------------------------------------------------------------------------------
/examples/complete/outputs.tf:
--------------------------------------------------------------------------------
1 | output "ecs_service_id" {
2 | value = module.ecs_fargate.ecs_service_id
3 | }
4 |
5 | output "ecs_service_name" {
6 | value = module.ecs_fargate.ecs_service_name
7 | }
8 |
9 | output "ecs_service_cluster" {
10 | value = module.ecs_fargate.ecs_service_cluster
11 | }
12 |
13 | output "ecs_service_iam_role" {
14 | value = module.ecs_fargate.ecs_service_iam_role
15 | }
16 |
17 | output "ecs_service_desired_count" {
18 | value = module.ecs_fargate.ecs_service_desired_count
19 | }
20 |
21 | output "security_group_id" {
22 | value = module.ecs_fargate.security_group_id
23 | }
24 |
25 | output "security_group_arn" {
26 | value = module.ecs_fargate.security_group_arn
27 | }
28 |
29 | output "security_group_vpc_id" {
30 | value = module.ecs_fargate.security_group_vpc_id
31 | }
32 |
33 | output "security_group_owner_id" {
34 | value = module.ecs_fargate.security_group_owner_id
35 | }
36 |
37 | output "security_group_name" {
38 | value = module.ecs_fargate.security_group_name
39 | }
40 |
41 | output "security_group_description" {
42 | value = module.ecs_fargate.security_group_description
43 | }
44 |
45 | output "security_group_ingress" {
46 | value = module.ecs_fargate.security_group_ingress
47 | }
48 |
49 | output "security_group_egress" {
50 | value = module.ecs_fargate.security_group_egress
51 | }
52 |
53 | output "ecs_task_definition_arn" {
54 | value = module.ecs_fargate.ecs_task_definition_arn
55 | }
56 |
57 | output "ecs_task_definition_family" {
58 | value = module.ecs_fargate.ecs_task_definition_family
59 | }
60 |
61 | output "ecs_task_definition_revision" {
62 | value = module.ecs_fargate.ecs_task_definition_revision
63 | }
64 |
65 | output "iam_role_arn" {
66 | value = module.ecs_fargate.iam_role_arn
67 | }
68 |
69 | output "iam_role_create_date" {
70 | value = module.ecs_fargate.iam_role_create_date
71 | }
72 |
73 | output "iam_role_unique_id" {
74 | value = module.ecs_fargate.iam_role_unique_id
75 | }
76 |
77 | output "iam_role_name" {
78 | value = module.ecs_fargate.iam_role_name
79 | }
80 |
81 | output "iam_role_description" {
82 | value = module.ecs_fargate.iam_role_description
83 | }
84 |
85 | output "iam_policy_id" {
86 | value = module.ecs_fargate.iam_policy_id
87 | }
88 |
89 | output "iam_policy_arn" {
90 | value = module.ecs_fargate.iam_policy_arn
91 | }
92 |
93 | output "iam_policy_description" {
94 | value = module.ecs_fargate.iam_policy_description
95 | }
96 |
97 | output "iam_policy_name" {
98 | value = module.ecs_fargate.iam_policy_name
99 | }
100 |
101 | output "iam_policy_path" {
102 | value = module.ecs_fargate.iam_policy_path
103 | }
104 |
105 | output "iam_policy_document" {
106 | value = module.ecs_fargate.iam_policy_document
107 | }
108 |
--------------------------------------------------------------------------------
/examples/complete/providers.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "ap-northeast-1"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/minimal/main.tf:
--------------------------------------------------------------------------------
1 | module "ecs_fargate" {
2 | source = "../../"
3 | name = "example"
4 | container_name = local.container_name
5 | container_port = local.container_port
6 | cluster = aws_ecs_cluster.example.arn
7 | subnets = module.vpc.public_subnet_ids
8 | target_group_arn = module.alb.alb_target_group_arn
9 | vpc_id = module.vpc.vpc_id
10 |
11 | container_definitions = jsonencode([
12 | {
13 | name = local.container_name
14 | image = "nginx:latest"
15 | essential = true
16 | portMappings = [
17 | {
18 | containerPort = local.container_port
19 | protocol = "tcp"
20 | }
21 | ]
22 | }
23 | ])
24 | }
25 |
26 | locals {
27 | container_name = "example"
28 | container_port = tonumber(module.alb.alb_target_group_port)
29 | }
30 |
31 | resource "aws_ecs_cluster" "example" {
32 | name = "default"
33 | }
34 |
35 | module "alb" {
36 | source = "git::https://github.com/tmknom/terraform-aws-alb.git?ref=tags/2.1.0"
37 | name = "ecs-fargate"
38 | vpc_id = module.vpc.vpc_id
39 | subnets = module.vpc.public_subnet_ids
40 | access_logs_bucket = module.s3_lb_log.s3_bucket_id
41 | enable_https_listener = false
42 | enable_http_listener = true
43 | enable_deletion_protection = false
44 | }
45 |
46 | module "s3_lb_log" {
47 | source = "git::https://github.com/tmknom/terraform-aws-s3-lb-log.git?ref=tags/2.0.0"
48 | name = "s3-lb-log-ecs-fargate-${data.aws_caller_identity.current.account_id}"
49 | logging_target_bucket = module.s3_access_log.s3_bucket_id
50 | force_destroy = true
51 | }
52 |
53 | module "s3_access_log" {
54 | source = "git::https://github.com/tmknom/terraform-aws-s3-access-log.git?ref=tags/2.0.0"
55 | name = "s3-access-log-ecs-fargate-${data.aws_caller_identity.current.account_id}"
56 | force_destroy = true
57 | }
58 |
59 | module "vpc" {
60 | source = "git::https://github.com/tmknom/terraform-aws-vpc.git?ref=tags/2.0.1"
61 | cidr_block = local.cidr_block
62 | name = "ecs-fargate"
63 | public_subnet_cidr_blocks = [cidrsubnet(local.cidr_block, 8, 0), cidrsubnet(local.cidr_block, 8, 1)]
64 | public_availability_zones = data.aws_availability_zones.available.names
65 | }
66 |
67 | locals {
68 | cidr_block = "10.255.0.0/16"
69 | }
70 |
71 | data "aws_caller_identity" "current" {}
72 |
73 | data "aws_availability_zones" "available" {}
74 |
--------------------------------------------------------------------------------
/examples/minimal/outputs.tf:
--------------------------------------------------------------------------------
1 | output "ecs_service_id" {
2 | value = module.ecs_fargate.ecs_service_id
3 | }
4 |
5 | output "ecs_service_name" {
6 | value = module.ecs_fargate.ecs_service_name
7 | }
8 |
9 | output "ecs_service_cluster" {
10 | value = module.ecs_fargate.ecs_service_cluster
11 | }
12 |
13 | output "ecs_service_iam_role" {
14 | value = module.ecs_fargate.ecs_service_iam_role
15 | }
16 |
17 | output "ecs_service_desired_count" {
18 | value = module.ecs_fargate.ecs_service_desired_count
19 | }
20 |
21 | output "security_group_id" {
22 | value = module.ecs_fargate.security_group_id
23 | }
24 |
25 | output "security_group_arn" {
26 | value = module.ecs_fargate.security_group_arn
27 | }
28 |
29 | output "security_group_vpc_id" {
30 | value = module.ecs_fargate.security_group_vpc_id
31 | }
32 |
33 | output "security_group_owner_id" {
34 | value = module.ecs_fargate.security_group_owner_id
35 | }
36 |
37 | output "security_group_name" {
38 | value = module.ecs_fargate.security_group_name
39 | }
40 |
41 | output "security_group_description" {
42 | value = module.ecs_fargate.security_group_description
43 | }
44 |
45 | output "security_group_ingress" {
46 | value = module.ecs_fargate.security_group_ingress
47 | }
48 |
49 | output "security_group_egress" {
50 | value = module.ecs_fargate.security_group_egress
51 | }
52 |
53 | output "ecs_task_definition_arn" {
54 | value = module.ecs_fargate.ecs_task_definition_arn
55 | }
56 |
57 | output "ecs_task_definition_family" {
58 | value = module.ecs_fargate.ecs_task_definition_family
59 | }
60 |
61 | output "ecs_task_definition_revision" {
62 | value = module.ecs_fargate.ecs_task_definition_revision
63 | }
64 |
65 | output "iam_role_arn" {
66 | value = module.ecs_fargate.iam_role_arn
67 | }
68 |
69 | output "iam_role_create_date" {
70 | value = module.ecs_fargate.iam_role_create_date
71 | }
72 |
73 | output "iam_role_unique_id" {
74 | value = module.ecs_fargate.iam_role_unique_id
75 | }
76 |
77 | output "iam_role_name" {
78 | value = module.ecs_fargate.iam_role_name
79 | }
80 |
81 | output "iam_role_description" {
82 | value = module.ecs_fargate.iam_role_description
83 | }
84 |
85 | output "iam_policy_id" {
86 | value = module.ecs_fargate.iam_policy_id
87 | }
88 |
89 | output "iam_policy_arn" {
90 | value = module.ecs_fargate.iam_policy_arn
91 | }
92 |
93 | output "iam_policy_description" {
94 | value = module.ecs_fargate.iam_policy_description
95 | }
96 |
97 | output "iam_policy_name" {
98 | value = module.ecs_fargate.iam_policy_name
99 | }
100 |
101 | output "iam_policy_path" {
102 | value = module.ecs_fargate.iam_policy_path
103 | }
104 |
105 | output "iam_policy_document" {
106 | value = module.ecs_fargate.iam_policy_document
107 | }
108 |
--------------------------------------------------------------------------------
/examples/minimal/providers.tf:
--------------------------------------------------------------------------------
1 | provider "aws" {
2 | region = "ap-northeast-1"
3 | }
4 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | # Terraform module which creates ECS Fargate resources on AWS.
2 | #
3 | # NOTE: The volume parameter of ECS Task Definition is not supported for this module.
4 | #
5 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_GetStarted.html
6 |
7 | # ECS Service
8 | #
9 | # The Fargate launch type allows you to run your containerized applications
10 | # without the need to provision and manage the backend infrastructure.
11 | #
12 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service_definition_parameters.html
13 |
14 | # https://www.terraform.io/docs/providers/aws/r/ecs_service.html
15 | resource "aws_ecs_service" "default" {
16 | count = var.enabled ? 1 : 0
17 |
18 | # The name of your service. Up to 255 letters (uppercase and lowercase), numbers, hyphens, and underscores are allowed.
19 | # Service names must be unique within a cluster, but you can have similarly named services
20 | # in multiple clusters within a region or across multiple regions.
21 | name = var.name
22 |
23 | # The family and revision (family:revision) or full ARN of the task definition to run in your service.
24 | # If a revision is not specified, the latest ACTIVE revision is used.
25 | task_definition = aws_ecs_task_definition.default[0].arn
26 |
27 | # The short name or full Amazon Resource Name (ARN) of the cluster on which to run your service.
28 | # If you do not specify a cluster, the default cluster is assumed.
29 | cluster = var.cluster
30 |
31 | # The number of instantiations of the specified task definition to place and keep running on your cluster.
32 | desired_count = var.desired_count
33 |
34 | # The maximumPercent parameter represents an upper limit on the number of your service's tasks
35 | # that are allowed in the RUNNING or PENDING state during a deployment,
36 | # as a percentage of the desiredCount (rounded down to the nearest integer).
37 | deployment_maximum_percent = var.deployment_maximum_percent
38 |
39 | # The minimumHealthyPercent represents a lower limit on the number of your service's tasks
40 | # that must remain in the RUNNING state during a deployment,
41 | # as a percentage of the desiredCount (rounded up to the nearest integer).
42 | deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
43 |
44 | deployment_controller {
45 | # The deployment controller type to use. Valid values: CODE_DEPLOY, ECS.
46 | type = var.deployment_controller_type
47 | }
48 |
49 | # The network configuration for the service. This parameter is required for task definitions
50 | # that use the awsvpc network mode to receive their own Elastic Network Interface.
51 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
52 | network_configuration {
53 | subnets = var.subnets
54 | security_groups = [aws_security_group.default[0].id]
55 |
56 | # Whether the task's elastic network interface receives a public IP address.
57 | assign_public_ip = var.assign_public_ip
58 | }
59 |
60 | # Note: As a result of an AWS limitation, a single load_balancer can be attached to the ECS service at most.
61 | #
62 | # When you create any target groups for these services, you must choose ip as the target type, not instance.
63 | # This is because tasks that use the awsvpc network mode are associated with an elastic network interface, not an EC2 instance.
64 | #
65 | # After you create a service, the load balancer name or target group ARN, container name,
66 | # and container port specified in the service definition are immutable.
67 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html#load-balancing-concepts
68 | load_balancer {
69 | # The ARN of the Load Balancer target group to associate with the service.
70 | target_group_arn = var.target_group_arn
71 |
72 | # The name of the container to associate with the load balancer (as it appears in a container definition).
73 | container_name = var.container_name
74 |
75 | # The port on the container to associate with the load balancer.
76 | container_port = var.container_port
77 | }
78 |
79 | # If your service's tasks take a while to start and respond to Elastic Load Balancing health checks,
80 | # you can specify a health check grace period of up to 7,200 seconds. This grace period can prevent
81 | # the service scheduler from marking tasks as unhealthy and stopping them before they have time to come up.
82 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-create-loadbalancer-rolling.html
83 | health_check_grace_period_seconds = var.health_check_grace_period_seconds
84 |
85 | # You can use either the version number (for example, 1.4.0) or LATEST.
86 | # If you specify LATEST, your tasks use the most current platform version available,
87 | # which may not be the most recent platform version.
88 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html
89 | platform_version = var.platform_version
90 |
91 | # The launch type on which to run your service.
92 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html
93 | launch_type = "FARGATE"
94 |
95 | # Note that Fargate tasks do support only the REPLICA scheduling strategy.
96 | #
97 | # The replica scheduling strategy places and maintains the desired number of tasks across your cluster.
98 | # By default, the service scheduler spreads tasks across Availability Zones.
99 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html#service_scheduler_replica
100 | scheduling_strategy = "REPLICA"
101 |
102 | lifecycle {
103 | # Ignore any changes to that count caused externally (e.g. Application Autoscaling).
104 | # https://www.terraform.io/docs/providers/aws/r/ecs_service.html#ignoring-changes-to-desired-count
105 | ignore_changes = [desired_count]
106 | }
107 | }
108 |
109 | # Security Group for ECS Service
110 | #
111 | # NOTE: At this time you cannot use a Security Group with in-line rules
112 | # in conjunction with any Security Group Rule resources.
113 | # Doing so will cause a conflict of rule settings and will overwrite rules.
114 | #
115 | # https://www.terraform.io/docs/providers/aws/r/security_group.html
116 | resource "aws_security_group" "default" {
117 | count = var.enabled ? 1 : 0
118 |
119 | name = local.security_group_name
120 | vpc_id = var.vpc_id
121 | tags = merge({ "Name" = local.security_group_name }, var.tags)
122 | }
123 |
124 | locals {
125 | security_group_name = "${var.name}-ecs-fargate"
126 | }
127 |
128 | # https://www.terraform.io/docs/providers/aws/r/security_group_rule.html
129 | resource "aws_security_group_rule" "ingress" {
130 | count = var.enabled ? 1 : 0
131 |
132 | type = "ingress"
133 | from_port = var.container_port
134 | to_port = var.container_port
135 | protocol = "tcp"
136 | cidr_blocks = var.source_cidr_blocks
137 | security_group_id = aws_security_group.default[0].id
138 | }
139 |
140 | resource "aws_security_group_rule" "egress" {
141 | count = var.enabled ? 1 : 0
142 |
143 | type = "egress"
144 | from_port = 0
145 | to_port = 0
146 | protocol = "-1"
147 | cidr_blocks = ["0.0.0.0/0"]
148 | security_group_id = aws_security_group.default[0].id
149 | }
150 |
151 | # ECS Task Definitions
152 | #
153 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html
154 |
155 | # https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html
156 | resource "aws_ecs_task_definition" "default" {
157 | count = var.enabled ? 1 : 0
158 |
159 | # A unique name for your task definition.
160 | family = var.name
161 |
162 | # The ARN of the task execution role that the Amazon ECS container agent and the Docker daemon can assume.
163 | execution_role_arn = var.create_ecs_task_execution_role ? join("", aws_iam_role.default.*.arn) : var.ecs_task_execution_role_arn
164 |
165 | # A list of container definitions in JSON format that describe the different containers that make up your task.
166 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions
167 | container_definitions = var.container_definitions
168 |
169 | # The number of CPU units used by the task.
170 | # It can be expressed as an integer using CPU units, for example 1024, or as a string using vCPUs, for example 1 vCPU or 1 vcpu.
171 | # String values are converted to an integer indicating the CPU units when the task definition is registered.
172 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
173 | cpu = var.cpu
174 |
175 | # The amount of memory (in MiB) used by the task.
176 | # It can be expressed as an integer using MiB, for example 1024, or as a string using GB, for example 1GB or 1 GB.
177 | # String values are converted to an integer indicating the MiB when the task definition is registered.
178 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
179 | memory = var.memory
180 |
181 | # The launch type that the task is using.
182 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#requires_compatibilities
183 | requires_compatibilities = var.requires_compatibilities
184 |
185 | # Fargate infrastructure support the awsvpc network mode.
186 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#network_mode
187 | network_mode = "awsvpc"
188 |
189 | # A mapping of tags to assign to the resource.
190 | tags = merge({ "Name" = var.name }, var.tags)
191 | }
192 |
193 | # ECS Task Execution IAM Role
194 | #
195 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html
196 |
197 | # https://www.terraform.io/docs/providers/aws/r/iam_role.html
198 | resource "aws_iam_role" "default" {
199 | count = local.enabled_ecs_task_execution
200 |
201 | name = local.iam_name
202 | assume_role_policy = data.aws_iam_policy_document.assume_role_policy.json
203 | path = var.iam_path
204 | description = var.description
205 | tags = merge({ "Name" = local.iam_name }, var.tags)
206 | }
207 |
208 | data "aws_iam_policy_document" "assume_role_policy" {
209 | statement {
210 | actions = ["sts:AssumeRole"]
211 |
212 | principals {
213 | type = "Service"
214 | identifiers = ["ecs-tasks.amazonaws.com"]
215 | }
216 | }
217 | }
218 |
219 | # https://www.terraform.io/docs/providers/aws/r/iam_policy.html
220 | resource "aws_iam_policy" "default" {
221 | count = local.enabled_ecs_task_execution
222 |
223 | name = local.iam_name
224 | policy = data.aws_iam_policy.ecs_task_execution.policy
225 | path = var.iam_path
226 | description = var.description
227 | }
228 |
229 | # https://www.terraform.io/docs/providers/aws/r/iam_role_policy_attachment.html
230 | resource "aws_iam_role_policy_attachment" "default" {
231 | count = local.enabled_ecs_task_execution
232 |
233 | role = aws_iam_role.default[0].name
234 | policy_arn = aws_iam_policy.default[0].arn
235 | }
236 |
237 | locals {
238 | iam_name = "${var.name}-ecs-task-execution"
239 | enabled_ecs_task_execution = var.enabled ? 1 : 0 && var.create_ecs_task_execution_role ? 1 : 0
240 | }
241 |
242 | data "aws_iam_policy" "ecs_task_execution" {
243 | arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
244 | }
245 |
--------------------------------------------------------------------------------
/modules/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tmknom/terraform-aws-ecs-fargate/4f0cdef82110c75705031da56d759e185f26765b/modules/.gitkeep
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | output "ecs_service_id" {
2 | value = join("", aws_ecs_service.default.*.id)
3 | description = "The Amazon Resource Name (ARN) that identifies the service."
4 | }
5 |
6 | output "ecs_service_name" {
7 | value = join("", aws_ecs_service.default.*.name)
8 | description = "The name of the service."
9 | }
10 |
11 | output "ecs_service_cluster" {
12 | value = join("", aws_ecs_service.default.*.cluster)
13 | description = "The Amazon Resource Name (ARN) of cluster which the service runs on."
14 | }
15 |
16 | output "ecs_service_iam_role" {
17 | value = join("", aws_ecs_service.default.*.iam_role)
18 | description = "The ARN of IAM role used for ELB."
19 | }
20 |
21 | output "ecs_service_desired_count" {
22 | value = join("", aws_ecs_service.default.*.desired_count)
23 | description = "The number of instances of the task definition."
24 | }
25 |
26 | output "security_group_id" {
27 | value = join("", aws_security_group.default.*.id)
28 | description = "The ID of the ECS Service security group."
29 | }
30 |
31 | output "security_group_arn" {
32 | value = join("", aws_security_group.default.*.arn)
33 | description = "The ARN of the ECS Service security group."
34 | }
35 |
36 | output "security_group_vpc_id" {
37 | value = join("", aws_security_group.default.*.vpc_id)
38 | description = "The VPC ID of the ECS Service security group."
39 | }
40 |
41 | output "security_group_owner_id" {
42 | value = join("", aws_security_group.default.*.owner_id)
43 | description = "The owner ID of the ECS Service security group."
44 | }
45 |
46 | output "security_group_name" {
47 | value = join("", aws_security_group.default.*.name)
48 | description = "The name of the ECS Service security group."
49 | }
50 |
51 | output "security_group_description" {
52 | value = join("", aws_security_group.default.*.description)
53 | description = "The description of the ECS Service security group."
54 | }
55 |
56 | output "security_group_ingress" {
57 | value = flatten(aws_security_group.default.*.ingress)
58 | description = "The ingress rules of the ECS Service security group."
59 | }
60 |
61 | output "security_group_egress" {
62 | value = flatten(aws_security_group.default.*.egress)
63 | description = "The egress rules of the ECS Service security group."
64 | }
65 |
66 | output "ecs_task_definition_arn" {
67 | value = join("", aws_ecs_task_definition.default.*.arn)
68 | description = "Full ARN of the Task Definition (including both family and revision)."
69 | }
70 |
71 | output "ecs_task_definition_family" {
72 | value = join("", aws_ecs_task_definition.default.*.family)
73 | description = "The family of the Task Definition."
74 | }
75 |
76 | output "ecs_task_definition_revision" {
77 | value = join("", aws_ecs_task_definition.default.*.revision)
78 | description = "The revision of the task in a particular family."
79 | }
80 |
81 | output "iam_role_arn" {
82 | value = join("", aws_iam_role.default.*.arn)
83 | description = "The Amazon Resource Name (ARN) specifying the IAM Role."
84 | }
85 |
86 | output "iam_role_create_date" {
87 | value = join("", aws_iam_role.default.*.create_date)
88 | description = "The creation date of the IAM Role."
89 | }
90 |
91 | output "iam_role_unique_id" {
92 | value = join("", aws_iam_role.default.*.unique_id)
93 | description = "The stable and unique string identifying the IAM Role."
94 | }
95 |
96 | output "iam_role_name" {
97 | value = join("", aws_iam_role.default.*.name)
98 | description = "The name of the IAM Role."
99 | }
100 |
101 | output "iam_role_description" {
102 | value = join("", aws_iam_role.default.*.description)
103 | description = "The description of the IAM Role."
104 | }
105 |
106 | output "iam_policy_id" {
107 | value = join("", aws_iam_policy.default.*.id)
108 | description = "The IAM Policy's ID."
109 | }
110 |
111 | output "iam_policy_arn" {
112 | value = join("", aws_iam_policy.default.*.arn)
113 | description = "The ARN assigned by AWS to this IAM Policy."
114 | }
115 |
116 | output "iam_policy_description" {
117 | value = join("", aws_iam_policy.default.*.description)
118 | description = "The description of the IAM Policy."
119 | }
120 |
121 | output "iam_policy_name" {
122 | value = join("", aws_iam_policy.default.*.name)
123 | description = "The name of the IAM Policy."
124 | }
125 |
126 | output "iam_policy_path" {
127 | value = join("", aws_iam_policy.default.*.path)
128 | description = "The path of the IAM Policy."
129 | }
130 |
131 | output "iam_policy_document" {
132 | value = join("", aws_iam_policy.default.*.policy)
133 | description = "The policy document of the IAM Policy."
134 | }
135 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | variable "name" {
2 | type = string
3 | description = "The name of ecs service."
4 | }
5 |
6 | variable "container_name" {
7 | type = string
8 | description = "The name of the container to associate with the load balancer (as it appears in a container definition)."
9 | }
10 |
11 | variable "container_port" {
12 | type = string
13 | description = "The port on the container to associate with the load balancer."
14 | }
15 |
16 | variable "cluster" {
17 | type = string
18 | description = "ARN of an ECS cluster."
19 | }
20 |
21 | variable "subnets" {
22 | type = list(string)
23 | description = "The subnets associated with the task or service."
24 | }
25 |
26 | variable "target_group_arn" {
27 | type = string
28 | description = "The ARN of the Load Balancer target group to associate with the service."
29 | }
30 |
31 | variable "vpc_id" {
32 | type = string
33 | description = "VPC Id to associate with ECS Service."
34 | }
35 |
36 | variable "container_definitions" {
37 | type = string
38 | description = "A list of valid container definitions provided as a single valid JSON document."
39 | }
40 |
41 | variable "desired_count" {
42 | default = 0
43 | type = string
44 | description = "The number of instances of the task definition to place and keep running."
45 | }
46 |
47 | variable "deployment_maximum_percent" {
48 | default = 200
49 | type = string
50 | description = "The upper limit (as a percentage of the service's desiredCount) of the number of running tasks that can be running in a service during a deployment."
51 | }
52 |
53 | variable "deployment_minimum_healthy_percent" {
54 | default = 100
55 | type = string
56 | description = "The lower limit (as a percentage of the service's desiredCount) of the number of running tasks that must remain running and healthy in a service during a deployment."
57 | }
58 |
59 | variable "deployment_controller_type" {
60 | default = "ECS"
61 | type = string
62 | description = "Type of deployment controller. Valid values: CODE_DEPLOY, ECS."
63 | }
64 |
65 | variable "assign_public_ip" {
66 | default = false
67 | type = string
68 | description = "Assign a public IP address to the ENI (Fargate launch type only). Valid values are true or false."
69 | }
70 |
71 | variable "health_check_grace_period_seconds" {
72 | default = 60
73 | type = string
74 | description = "Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200."
75 | }
76 |
77 | variable "platform_version" {
78 | default = "1.4.0"
79 | type = string
80 | description = "The platform version on which to run your service."
81 | }
82 |
83 | variable "source_cidr_blocks" {
84 | default = ["0.0.0.0/0"]
85 | type = list(string)
86 | description = "List of source CIDR blocks."
87 | }
88 |
89 | variable "cpu" {
90 | default = "256"
91 | type = string
92 | description = "The number of cpu units used by the task."
93 | }
94 |
95 | variable "memory" {
96 | default = "512"
97 | type = string
98 | description = "The amount (in MiB) of memory used by the task."
99 | }
100 |
101 | variable "requires_compatibilities" {
102 | default = ["FARGATE"]
103 | type = list(string)
104 | description = "A set of launch types required by the task. The valid values are EC2 and FARGATE."
105 | }
106 |
107 | variable "iam_path" {
108 | default = "/"
109 | type = string
110 | description = "Path in which to create the IAM Role and the IAM Policy."
111 | }
112 |
113 | variable "description" {
114 | default = "Managed by Terraform"
115 | type = string
116 | description = "The description of the all resources."
117 | }
118 |
119 | variable "tags" {
120 | default = {}
121 | type = map(string)
122 | description = "A mapping of tags to assign to all resources."
123 | }
124 |
125 | variable "enabled" {
126 | default = true
127 | type = string
128 | description = "Set to false to prevent the module from creating anything."
129 | }
130 |
131 | variable "create_ecs_task_execution_role" {
132 | default = true
133 | type = string
134 | description = "Specify true to indicate that ECS Task Execution IAM Role creation."
135 | }
136 |
137 | variable "ecs_task_execution_role_arn" {
138 | default = ""
139 | type = string
140 | description = "The ARN of the ECS Task Execution IAM Role."
141 | }
142 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.12"
3 | }
4 |
--------------------------------------------------------------------------------