├── .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-scheduled-task 2 | 3 | [![Terraform Actions Status](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/workflows/Terraform/badge.svg)](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/actions?query=workflow%3ATerraform) 4 | [![Markdown Actions Status](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/workflows/Markdown/badge.svg)](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/actions?query=workflow%3AMarkdown) 5 | [![YAML Actions Status](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/workflows/YAML/badge.svg)](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/actions?query=workflow%3AYAML) 6 | [![JSON Actions Status](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/workflows/JSON/badge.svg)](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/actions?query=workflow%3AJSON) 7 | [![GitHub tag](https://img.shields.io/github/tag/tmknom/terraform-aws-ecs-scheduled-task.svg)](https://registry.terraform.io/modules/tmknom/ecs-scheduled-task/aws) 8 | [![License](https://img.shields.io/github/license/tmknom/terraform-aws-ecs-scheduled-task.svg)](https://opensource.org/licenses/Apache-2.0) 9 | 10 | Terraform module which creates ECS Scheduled Task resources on AWS. 11 | 12 | ## Description 13 | 14 | Provision [ECS Task Definitions](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) and 15 | [CloudWatch Events](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/WhatIsCloudWatchEvents.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_scheduled_task" { 28 | source = "git::https://github.com/tmknom/terraform-aws-ecs-scheduled-task.git?ref=tags/2.0.0" 29 | name = "example" 30 | schedule_expression = "rate(3 minutes)" 31 | container_definitions = var.container_definitions 32 | cluster_arn = var.cluster_arn 33 | subnets = var.subnets 34 | } 35 | ``` 36 | 37 | ### Complete 38 | 39 | ```hcl 40 | module "ecs_scheduled_task" { 41 | source = "git::https://github.com/tmknom/terraform-aws-ecs-scheduled-task.git?ref=tags/2.0.0" 42 | name = "example" 43 | schedule_expression = "rate(3 minutes)" 44 | container_definitions = var.container_definitions 45 | cluster_arn = var.cluster_arn 46 | subnets = var.subnets 47 | 48 | is_enabled = true 49 | task_count = 1 50 | platform_version = "LATEST" 51 | assign_public_ip = true 52 | security_groups = [] 53 | cpu = 256 54 | memory = 512 55 | requires_compatibilities = ["FARGATE"] 56 | iam_path = "/service_role/" 57 | description = "This is example" 58 | enabled = true 59 | 60 | create_ecs_events_role = false 61 | ecs_events_role_arn = var.ecs_events_role_arn 62 | 63 | create_ecs_task_execution_role = false 64 | ecs_task_execution_role_arn = var.ecs_events_role_arn 65 | 66 | tags = { 67 | Environment = "prod" 68 | } 69 | } 70 | ``` 71 | 72 | ## Examples 73 | 74 | - [Minimal](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/tree/master/examples/minimal) 75 | - [Complete](https://github.com/tmknom/terraform-aws-ecs-scheduled-task/tree/master/examples/complete) 76 | 77 | 78 | 79 | ## Requirements 80 | 81 | | Name | Version | 82 | | --------- | ------- | 83 | | terraform | >= 0.12 | 84 | 85 | ## Providers 86 | 87 | | Name | Version | 88 | | ---- | ------- | 89 | | aws | n/a | 90 | 91 | ## Inputs 92 | 93 | | Name | Description | Type | Default | Required | 94 | | ------------------------------ | --------------------------------------------------------------------------------- | -------------- | ------------------------------- | :------: | 95 | | cluster_arn | ARN of an ECS cluster. | `string` | n/a | yes | 96 | | container_definitions | A list of valid container definitions provided as a single valid JSON document. | `string` | n/a | yes | 97 | | name | The name of ecs task definition. | `string` | n/a | yes | 98 | | schedule_expression | The scheduling expression.For example, `cron(0 20 * * ? *)` or `rate(5 minutes)`. | `string` | n/a | yes | 99 | | subnets | The subnets associated with the task or service. | `list(string)` | n/a | yes | 100 | | assign_public_ip | Assign a public IP address to the ENI (Fargate launch type only). | `string` | `false` | no | 101 | | cpu | The number of cpu units used by the task. | `string` | `"256"` | no | 102 | | create_ecs_events_role | Specify true to indicate that CloudWatch Events IAM Role creation. | `string` | `true` | no | 103 | | create_ecs_task_execution_role | Specify true to indicate that ECS Task Execution IAM Role creation. | `string` | `true` | no | 104 | | description | The description of the all resources. | `string` | `"Managed by Terraform"` | no | 105 | | ecs_events_role_arn | The ARN of the CloudWatch Events IAM Role. | `string` | `""` | no | 106 | | ecs_task_execution_role_arn | The ARN of the ECS Task Execution IAM Role. | `string` | `""` | no | 107 | | enabled | Set to false to prevent the module from creating anything. | `bool` | `true` | no | 108 | | iam_path | Path in which to create the IAM Role and the IAM Policy. | `string` | `"/"` | no | 109 | | is_enabled | Whether the rule should be enabled. | `string` | `true` | no | 110 | | memory | The amount (in MiB) of memory used by the task. | `string` | `"512"` | no | 111 | | platform_version | Specifies the platform version for the task. | `string` | `"1.4.0"` | no | 112 | | requires_compatibilities | A set of launch types required by the task. The valid values are EC2 and FARGATE. | `list(string)` |
[
"FARGATE"
]
| no | 113 | | security_groups | The security groups associated with the task or service. | `list(string)` | `[]` | no | 114 | | tags | A mapping of tags to assign to all resources. | `map(string)` | `{}` | no | 115 | | task_count | The number of tasks to create based on the TaskDefinition. | `string` | `1` | no | 116 | 117 | ## Outputs 118 | 119 | | Name | Description | 120 | | ------------------------------------- | -------------------------------------------------------------------------- | 121 | | cloudwatch_event_rule_arn | The Amazon Resource Name (ARN) of the rule. | 122 | | ecs_events_policy_arn | The ARN assigned by AWS to this CloudWatch Events IAM Policy. | 123 | | ecs_events_policy_description | The description of the CloudWatch Events IAM Policy. | 124 | | ecs_events_policy_document | The policy document of the CloudWatch Events IAM Policy. | 125 | | ecs_events_policy_id | The CloudWatch Events IAM Policy's ID. | 126 | | ecs_events_policy_name | The name of the CloudWatch Events IAM Policy. | 127 | | ecs_events_policy_path | The path of the CloudWatch Events IAM Policy. | 128 | | ecs_events_role_arn | The Amazon Resource Name (ARN) specifying the CloudWatch Events IAM Role. | 129 | | ecs_events_role_create_date | The creation date of the IAM Role. | 130 | | ecs_events_role_description | The description of the CloudWatch Events IAM Role. | 131 | | ecs_events_role_name | The name of the CloudWatch Events IAM Role. | 132 | | ecs_events_role_unique_id | The stable and unique string identifying the CloudWatch Events IAM Role. | 133 | | ecs_task_definition_arn | Full ARN of the Task Definition (including both family and revision). | 134 | | ecs_task_definition_family | The family of the Task Definition. | 135 | | ecs_task_definition_revision | The revision of the task in a particular family. | 136 | | ecs_task_execution_policy_arn | The ARN assigned by AWS to this ECS Task Execution IAM Policy. | 137 | | ecs_task_execution_policy_description | The description of the ECS Task Execution IAM Policy. | 138 | | ecs_task_execution_policy_document | The policy document of the ECS Task Execution IAM Policy. | 139 | | ecs_task_execution_policy_id | The ECS Task Execution IAM Policy's ID. | 140 | | ecs_task_execution_policy_name | The name of the ECS Task Execution IAM Policy. | 141 | | ecs_task_execution_policy_path | The path of the ECS Task Execution IAM Policy. | 142 | | ecs_task_execution_role_arn | The Amazon Resource Name (ARN) specifying the ECS Task Execution IAM Role. | 143 | | ecs_task_execution_role_create_date | The creation date of the ECS Task Execution IAM Role. | 144 | | ecs_task_execution_role_description | The description of the ECS Task Execution IAM Role. | 145 | | ecs_task_execution_role_name | The name of the ECS Task Execution IAM Role. | 146 | | ecs_task_execution_role_unique_id | The stable and unique string identifying the ECS Task Execution IAM Role. | 147 | 148 | 149 | 150 | ## Development 151 | 152 | ### Development Requirements 153 | 154 | - [Docker](https://www.docker.com/) 155 | 156 | ### Configure environment variables 157 | 158 | ```shell 159 | export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE 160 | export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY 161 | export AWS_DEFAULT_REGION=ap-northeast-1 162 | ``` 163 | 164 | ### Installation 165 | 166 | ```shell 167 | git clone git@github.com:tmknom/terraform-aws-ecs-scheduled-task.git 168 | cd terraform-aws-ecs-scheduled-task 169 | make install 170 | ``` 171 | 172 | ### Makefile targets 173 | 174 | ```text 175 | apply-complete Run terraform apply examples/complete 176 | apply-minimal Run terraform apply examples/minimal 177 | bump-version Bump version (Required argument 'VERSION') 178 | check-format Check format code 179 | clean Clean .terraform 180 | destroy-complete Run terraform destroy examples/complete 181 | destroy-minimal Run terraform destroy examples/minimal 182 | diff Word diff 183 | docs Generate docs 184 | format Format code 185 | help Show help 186 | install Install requirements 187 | lint Lint code 188 | plan-complete Run terraform plan examples/complete 189 | plan-minimal Run terraform plan examples/minimal 190 | release Release GitHub and Terraform Module Registry 191 | upgrade Upgrade makefile 192 | ``` 193 | 194 | ### Releasing new versions 195 | 196 | Bump VERSION file, and run `make release`. 197 | 198 | ### Terraform Module Registry 199 | 200 | - 201 | 202 | ## License 203 | 204 | Apache 2 Licensed. See LICENSE for full details. 205 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2.0.0 2 | -------------------------------------------------------------------------------- /examples/complete/main.tf: -------------------------------------------------------------------------------- 1 | module "ecs_scheduled_task" { 2 | source = "../../" 3 | name = "example" 4 | schedule_expression = "rate(3 minutes)" 5 | cluster_arn = aws_ecs_cluster.example.arn 6 | subnets = module.vpc.public_subnet_ids 7 | 8 | container_definitions = jsonencode([ 9 | { 10 | name = "alpine" 11 | image = "alpine:latest" 12 | essential = true 13 | logConfiguration = { 14 | logDriver = "awslogs" 15 | options = { 16 | awslogs-group = local.awslogs_group 17 | awslogs-region = data.aws_region.current.name 18 | awslogs-stream-prefix = "date" 19 | } 20 | } 21 | command = ["/bin/date"] 22 | } 23 | ]) 24 | 25 | is_enabled = true 26 | task_count = 1 27 | platform_version = "LATEST" 28 | assign_public_ip = true 29 | security_groups = [] 30 | cpu = 256 31 | memory = 512 32 | requires_compatibilities = ["FARGATE"] 33 | iam_path = "/service_role/" 34 | description = "This is example" 35 | enabled = true 36 | 37 | create_ecs_events_role = false 38 | ecs_events_role_arn = aws_iam_role.ecs_events.arn 39 | 40 | create_ecs_task_execution_role = false 41 | ecs_task_execution_role_arn = aws_iam_role.ecs_task_execution.arn 42 | 43 | tags = { 44 | Environment = "prod" 45 | } 46 | } 47 | 48 | resource "aws_iam_role" "ecs_events" { 49 | name = "ecs-events-for-ecs-scheduled-task" 50 | assume_role_policy = data.aws_iam_policy_document.ecs_events_assume_role_policy.json 51 | } 52 | 53 | data "aws_iam_policy_document" "ecs_events_assume_role_policy" { 54 | statement { 55 | actions = ["sts:AssumeRole"] 56 | 57 | principals { 58 | type = "Service" 59 | identifiers = ["events.amazonaws.com"] 60 | } 61 | } 62 | } 63 | 64 | resource "aws_iam_policy" "ecs_events" { 65 | name = aws_iam_role.ecs_events.name 66 | policy = data.aws_iam_policy.ecs_events.policy 67 | } 68 | 69 | data "aws_iam_policy" "ecs_events" { 70 | arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole" 71 | } 72 | 73 | resource "aws_iam_role_policy_attachment" "ecs_events" { 74 | role = aws_iam_role.ecs_events.name 75 | policy_arn = aws_iam_policy.ecs_events.arn 76 | } 77 | 78 | resource "aws_iam_role" "ecs_task_execution" { 79 | name = "ecs-task-execution-for-ecs-scheduled-task" 80 | assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_assume_role_policy.json 81 | } 82 | 83 | data "aws_iam_policy_document" "ecs_task_execution_assume_role_policy" { 84 | statement { 85 | actions = ["sts:AssumeRole"] 86 | 87 | principals { 88 | type = "Service" 89 | identifiers = ["ecs-tasks.amazonaws.com"] 90 | } 91 | } 92 | } 93 | 94 | resource "aws_iam_policy" "ecs_task_execution" { 95 | name = aws_iam_role.ecs_task_execution.name 96 | policy = data.aws_iam_policy.ecs_task_execution.policy 97 | } 98 | 99 | data "aws_iam_policy" "ecs_task_execution" { 100 | arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" 101 | } 102 | 103 | resource "aws_iam_role_policy_attachment" "ecs_task_execution" { 104 | role = aws_iam_role.ecs_task_execution.name 105 | policy_arn = aws_iam_policy.ecs_task_execution.arn 106 | } 107 | 108 | resource "aws_cloudwatch_log_group" "example" { 109 | name = local.awslogs_group 110 | retention_in_days = 1 111 | } 112 | 113 | locals { 114 | awslogs_group = "/ecs-scheduled-task/example" 115 | } 116 | 117 | resource "aws_ecs_cluster" "example" { 118 | name = "ecs-scheduled-task" 119 | } 120 | 121 | module "vpc" { 122 | source = "git::https://github.com/tmknom/terraform-aws-vpc.git?ref=tags/2.0.1" 123 | cidr_block = local.cidr_block 124 | name = "ecs-scheduled-task" 125 | public_subnet_cidr_blocks = [cidrsubnet(local.cidr_block, 8, 0), cidrsubnet(local.cidr_block, 8, 1)] 126 | public_availability_zones = data.aws_availability_zones.available.names 127 | } 128 | 129 | locals { 130 | cidr_block = "10.255.0.0/16" 131 | } 132 | 133 | data "aws_region" "current" {} 134 | 135 | data "aws_availability_zones" "available" {} 136 | -------------------------------------------------------------------------------- /examples/complete/outputs.tf: -------------------------------------------------------------------------------- 1 | output "cloudwatch_event_rule_arn" { 2 | value = module.ecs_scheduled_task.cloudwatch_event_rule_arn 3 | } 4 | 5 | output "ecs_events_role_arn" { 6 | value = module.ecs_scheduled_task.ecs_events_role_arn 7 | } 8 | 9 | output "ecs_events_role_create_date" { 10 | value = module.ecs_scheduled_task.ecs_events_role_create_date 11 | } 12 | 13 | output "ecs_events_role_unique_id" { 14 | value = module.ecs_scheduled_task.ecs_events_role_unique_id 15 | } 16 | 17 | output "ecs_events_role_name" { 18 | value = module.ecs_scheduled_task.ecs_events_role_name 19 | } 20 | 21 | output "ecs_events_role_description" { 22 | value = module.ecs_scheduled_task.ecs_events_role_description 23 | } 24 | 25 | output "ecs_events_policy_id" { 26 | value = module.ecs_scheduled_task.ecs_events_policy_id 27 | } 28 | 29 | output "ecs_events_policy_arn" { 30 | value = module.ecs_scheduled_task.ecs_events_policy_arn 31 | } 32 | 33 | output "ecs_events_policy_description" { 34 | value = module.ecs_scheduled_task.ecs_events_policy_description 35 | } 36 | 37 | output "ecs_events_policy_name" { 38 | value = module.ecs_scheduled_task.ecs_events_policy_name 39 | } 40 | 41 | output "ecs_events_policy_path" { 42 | value = module.ecs_scheduled_task.ecs_events_policy_path 43 | } 44 | 45 | output "ecs_events_policy_document" { 46 | value = module.ecs_scheduled_task.ecs_events_policy_document 47 | } 48 | 49 | output "ecs_task_definition_arn" { 50 | value = module.ecs_scheduled_task.ecs_task_definition_arn 51 | } 52 | 53 | output "ecs_task_definition_family" { 54 | value = module.ecs_scheduled_task.ecs_task_definition_family 55 | } 56 | 57 | output "ecs_task_definition_revision" { 58 | value = module.ecs_scheduled_task.ecs_task_definition_revision 59 | } 60 | 61 | output "ecs_task_execution_role_arn" { 62 | value = module.ecs_scheduled_task.ecs_task_execution_role_arn 63 | } 64 | 65 | output "ecs_task_execution_role_create_date" { 66 | value = module.ecs_scheduled_task.ecs_task_execution_role_create_date 67 | } 68 | 69 | output "ecs_task_execution_role_unique_id" { 70 | value = module.ecs_scheduled_task.ecs_task_execution_role_unique_id 71 | } 72 | 73 | output "ecs_task_execution_role_name" { 74 | value = module.ecs_scheduled_task.ecs_task_execution_role_name 75 | } 76 | 77 | output "ecs_task_execution_role_description" { 78 | value = module.ecs_scheduled_task.ecs_task_execution_role_description 79 | } 80 | 81 | output "ecs_task_execution_policy_id" { 82 | value = module.ecs_scheduled_task.ecs_task_execution_policy_id 83 | } 84 | 85 | output "ecs_task_execution_policy_arn" { 86 | value = module.ecs_scheduled_task.ecs_task_execution_policy_arn 87 | } 88 | 89 | output "ecs_task_execution_policy_description" { 90 | value = module.ecs_scheduled_task.ecs_task_execution_policy_description 91 | } 92 | 93 | output "ecs_task_execution_policy_name" { 94 | value = module.ecs_scheduled_task.ecs_task_execution_policy_name 95 | } 96 | 97 | output "ecs_task_execution_policy_path" { 98 | value = module.ecs_scheduled_task.ecs_task_execution_policy_path 99 | } 100 | 101 | output "ecs_task_execution_policy_document" { 102 | value = module.ecs_scheduled_task.ecs_task_execution_policy_document 103 | } 104 | -------------------------------------------------------------------------------- /examples/complete/providers.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "ap-northeast-1" 3 | } 4 | -------------------------------------------------------------------------------- /examples/minimal/main.tf: -------------------------------------------------------------------------------- 1 | module "ecs_scheduled_task" { 2 | source = "../../" 3 | name = "example" 4 | schedule_expression = "rate(3 minutes)" 5 | cluster_arn = aws_ecs_cluster.example.arn 6 | subnets = module.vpc.public_subnet_ids 7 | 8 | container_definitions = jsonencode([ 9 | { 10 | name = "alpine" 11 | image = "alpine:latest" 12 | essential = true 13 | logConfiguration = { 14 | logDriver = "awslogs" 15 | options = { 16 | awslogs-group = local.awslogs_group 17 | awslogs-region = data.aws_region.current.name 18 | awslogs-stream-prefix = "date" 19 | } 20 | } 21 | command = ["/bin/date"] 22 | } 23 | ]) 24 | 25 | assign_public_ip = true 26 | } 27 | 28 | resource "aws_cloudwatch_log_group" "example" { 29 | name = local.awslogs_group 30 | retention_in_days = 1 31 | } 32 | 33 | locals { 34 | awslogs_group = "/ecs-scheduled-task/example" 35 | } 36 | 37 | resource "aws_ecs_cluster" "example" { 38 | name = "ecs-scheduled-task" 39 | } 40 | 41 | module "vpc" { 42 | source = "git::https://github.com/tmknom/terraform-aws-vpc.git?ref=tags/2.0.1" 43 | cidr_block = local.cidr_block 44 | name = "ecs-scheduled-task" 45 | public_subnet_cidr_blocks = [cidrsubnet(local.cidr_block, 8, 0), cidrsubnet(local.cidr_block, 8, 1)] 46 | public_availability_zones = data.aws_availability_zones.available.names 47 | } 48 | 49 | locals { 50 | cidr_block = "10.255.0.0/16" 51 | } 52 | 53 | data "aws_region" "current" {} 54 | 55 | data "aws_availability_zones" "available" {} 56 | -------------------------------------------------------------------------------- /examples/minimal/outputs.tf: -------------------------------------------------------------------------------- 1 | output "cloudwatch_event_rule_arn" { 2 | value = module.ecs_scheduled_task.cloudwatch_event_rule_arn 3 | } 4 | 5 | output "ecs_events_role_arn" { 6 | value = module.ecs_scheduled_task.ecs_events_role_arn 7 | } 8 | 9 | output "ecs_events_role_create_date" { 10 | value = module.ecs_scheduled_task.ecs_events_role_create_date 11 | } 12 | 13 | output "ecs_events_role_unique_id" { 14 | value = module.ecs_scheduled_task.ecs_events_role_unique_id 15 | } 16 | 17 | output "ecs_events_role_name" { 18 | value = module.ecs_scheduled_task.ecs_events_role_name 19 | } 20 | 21 | output "ecs_events_role_description" { 22 | value = module.ecs_scheduled_task.ecs_events_role_description 23 | } 24 | 25 | output "ecs_events_policy_id" { 26 | value = module.ecs_scheduled_task.ecs_events_policy_id 27 | } 28 | 29 | output "ecs_events_policy_arn" { 30 | value = module.ecs_scheduled_task.ecs_events_policy_arn 31 | } 32 | 33 | output "ecs_events_policy_description" { 34 | value = module.ecs_scheduled_task.ecs_events_policy_description 35 | } 36 | 37 | output "ecs_events_policy_name" { 38 | value = module.ecs_scheduled_task.ecs_events_policy_name 39 | } 40 | 41 | output "ecs_events_policy_path" { 42 | value = module.ecs_scheduled_task.ecs_events_policy_path 43 | } 44 | 45 | output "ecs_events_policy_document" { 46 | value = module.ecs_scheduled_task.ecs_events_policy_document 47 | } 48 | 49 | output "ecs_task_definition_arn" { 50 | value = module.ecs_scheduled_task.ecs_task_definition_arn 51 | } 52 | 53 | output "ecs_task_definition_family" { 54 | value = module.ecs_scheduled_task.ecs_task_definition_family 55 | } 56 | 57 | output "ecs_task_definition_revision" { 58 | value = module.ecs_scheduled_task.ecs_task_definition_revision 59 | } 60 | 61 | output "ecs_task_execution_role_arn" { 62 | value = module.ecs_scheduled_task.ecs_task_execution_role_arn 63 | } 64 | 65 | output "ecs_task_execution_role_create_date" { 66 | value = module.ecs_scheduled_task.ecs_task_execution_role_create_date 67 | } 68 | 69 | output "ecs_task_execution_role_unique_id" { 70 | value = module.ecs_scheduled_task.ecs_task_execution_role_unique_id 71 | } 72 | 73 | output "ecs_task_execution_role_name" { 74 | value = module.ecs_scheduled_task.ecs_task_execution_role_name 75 | } 76 | 77 | output "ecs_task_execution_role_description" { 78 | value = module.ecs_scheduled_task.ecs_task_execution_role_description 79 | } 80 | 81 | output "ecs_task_execution_policy_id" { 82 | value = module.ecs_scheduled_task.ecs_task_execution_policy_id 83 | } 84 | 85 | output "ecs_task_execution_policy_arn" { 86 | value = module.ecs_scheduled_task.ecs_task_execution_policy_arn 87 | } 88 | 89 | output "ecs_task_execution_policy_description" { 90 | value = module.ecs_scheduled_task.ecs_task_execution_policy_description 91 | } 92 | 93 | output "ecs_task_execution_policy_name" { 94 | value = module.ecs_scheduled_task.ecs_task_execution_policy_name 95 | } 96 | 97 | output "ecs_task_execution_policy_path" { 98 | value = module.ecs_scheduled_task.ecs_task_execution_policy_path 99 | } 100 | 101 | output "ecs_task_execution_policy_document" { 102 | value = module.ecs_scheduled_task.ecs_task_execution_policy_document 103 | } 104 | -------------------------------------------------------------------------------- /examples/minimal/providers.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "ap-northeast-1" 3 | } 4 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | # Terraform module which creates ECS Scheduled Task resources on AWS. 2 | # 3 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/scheduled_tasks.html 4 | 5 | # https://www.terraform.io/docs/providers/aws/r/cloudwatch_event_rule.html 6 | resource "aws_cloudwatch_event_rule" "default" { 7 | count = var.enabled ? 1 : 0 8 | 9 | name = var.name 10 | description = var.description 11 | is_enabled = var.is_enabled 12 | 13 | # All scheduled events use UTC time zone and the minimum precision for schedules is 1 minute. 14 | # CloudWatch Events supports Cron Expressions and Rate Expressions 15 | # For example, "cron(0 20 * * ? *)" or "rate(5 minutes)". 16 | # https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html 17 | schedule_expression = var.schedule_expression 18 | } 19 | 20 | # https://www.terraform.io/docs/providers/aws/r/cloudwatch_event_target.html 21 | resource "aws_cloudwatch_event_target" "default" { 22 | count = var.enabled ? 1 : 0 23 | 24 | target_id = var.name 25 | arn = var.cluster_arn 26 | rule = aws_cloudwatch_event_rule.default[0].name 27 | role_arn = var.create_ecs_events_role ? join("", aws_iam_role.ecs_events.*.arn) : var.ecs_events_role_arn 28 | 29 | # Contains the Amazon ECS task definition and task count to be used, if the event target is an Amazon ECS task. 30 | # https://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_EcsParameters.html 31 | ecs_target { 32 | launch_type = "FARGATE" 33 | task_count = var.task_count 34 | task_definition_arn = aws_ecs_task_definition.default[0].arn 35 | 36 | # Specifies the platform version for the task. Specify only the numeric portion of the platform version, such as 1.1.0. 37 | # This structure is used only if LaunchType is FARGATE. 38 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/platform_versions.html 39 | platform_version = var.platform_version 40 | 41 | # This structure specifies the VPC subnets and security groups for the task, and whether a public IP address is to be used. 42 | # This structure is relevant only for ECS tasks that use the awsvpc network mode. 43 | # https://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_AwsVpcConfiguration.html 44 | network_configuration { 45 | assign_public_ip = var.assign_public_ip 46 | 47 | # Specifies the security groups associated with the task. These security groups must all be in the same VPC. 48 | # You can specify as many as five security groups. If you do not specify a security group, 49 | # the default security group for the VPC is used. 50 | security_groups = var.security_groups 51 | 52 | # Specifies the subnets associated with the task. These subnets must all be in the same VPC. 53 | # You can specify as many as 16 subnets. 54 | subnets = var.subnets 55 | } 56 | } 57 | } 58 | 59 | # CloudWatch Events IAM Role 60 | # 61 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/CWE_IAM_role.html 62 | 63 | # https://www.terraform.io/docs/providers/aws/r/iam_role.html 64 | resource "aws_iam_role" "ecs_events" { 65 | count = local.enabled_ecs_events 66 | 67 | name = local.ecs_events_iam_name 68 | assume_role_policy = data.aws_iam_policy_document.ecs_events_assume_role_policy.json 69 | path = var.iam_path 70 | description = var.description 71 | tags = merge({ "Name" = local.ecs_events_iam_name }, var.tags) 72 | } 73 | 74 | data "aws_iam_policy_document" "ecs_events_assume_role_policy" { 75 | statement { 76 | actions = ["sts:AssumeRole"] 77 | 78 | principals { 79 | type = "Service" 80 | identifiers = ["events.amazonaws.com"] 81 | } 82 | } 83 | } 84 | 85 | # https://www.terraform.io/docs/providers/aws/r/iam_policy.html 86 | resource "aws_iam_policy" "ecs_events" { 87 | count = local.enabled_ecs_events 88 | 89 | name = local.ecs_events_iam_name 90 | policy = data.aws_iam_policy.ecs_events.policy 91 | path = var.iam_path 92 | description = var.description 93 | } 94 | 95 | data "aws_iam_policy" "ecs_events" { 96 | arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceEventsRole" 97 | } 98 | 99 | # https://www.terraform.io/docs/providers/aws/r/iam_role_policy_attachment.html 100 | resource "aws_iam_role_policy_attachment" "ecs_events" { 101 | count = local.enabled_ecs_events 102 | 103 | role = aws_iam_role.ecs_events[0].name 104 | policy_arn = aws_iam_policy.ecs_events[0].arn 105 | } 106 | 107 | locals { 108 | ecs_events_iam_name = "${var.name}-ecs-events" 109 | enabled_ecs_events = var.enabled && var.create_ecs_events_role ? 1 : 0 110 | } 111 | 112 | # ECS Task Definitions 113 | # 114 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html 115 | 116 | # https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html 117 | resource "aws_ecs_task_definition" "default" { 118 | count = var.enabled ? 1 : 0 119 | 120 | # A unique name for your task definition. 121 | family = var.name 122 | 123 | # The ARN of the task execution role that the Amazon ECS container agent and the Docker daemon can assume. 124 | execution_role_arn = var.create_ecs_task_execution_role ? join("", aws_iam_role.ecs_task_execution.*.arn) : var.ecs_task_execution_role_arn 125 | 126 | # A list of container definitions in JSON format that describe the different containers that make up your task. 127 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions 128 | container_definitions = var.container_definitions 129 | 130 | # The number of CPU units used by the task. 131 | # 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. 132 | # String values are converted to an integer indicating the CPU units when the task definition is registered. 133 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size 134 | cpu = var.cpu 135 | 136 | # The amount of memory (in MiB) used by the task. 137 | # It can be expressed as an integer using MiB, for example 1024, or as a string using GB, for example 1GB or 1 GB. 138 | # String values are converted to an integer indicating the MiB when the task definition is registered. 139 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size 140 | memory = var.memory 141 | 142 | # The launch type that the task is using. 143 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#requires_compatibilities 144 | requires_compatibilities = var.requires_compatibilities 145 | 146 | # Fargate infrastructure support the awsvpc network mode. 147 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#network_mode 148 | network_mode = "awsvpc" 149 | 150 | # A mapping of tags to assign to the resource. 151 | tags = merge({ "Name" = var.name }, var.tags) 152 | } 153 | 154 | # ECS Task Execution IAM Role 155 | # 156 | # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html 157 | 158 | # https://www.terraform.io/docs/providers/aws/r/iam_role.html 159 | resource "aws_iam_role" "ecs_task_execution" { 160 | count = local.enabled_ecs_task_execution 161 | 162 | name = local.ecs_task_execution_iam_name 163 | assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_assume_role_policy.json 164 | path = var.iam_path 165 | description = var.description 166 | tags = merge({ "Name" = local.ecs_task_execution_iam_name }, var.tags) 167 | } 168 | 169 | data "aws_iam_policy_document" "ecs_task_execution_assume_role_policy" { 170 | statement { 171 | actions = ["sts:AssumeRole"] 172 | 173 | principals { 174 | type = "Service" 175 | identifiers = ["ecs-tasks.amazonaws.com"] 176 | } 177 | } 178 | } 179 | 180 | # https://www.terraform.io/docs/providers/aws/r/iam_policy.html 181 | resource "aws_iam_policy" "ecs_task_execution" { 182 | count = local.enabled_ecs_task_execution 183 | 184 | name = local.ecs_task_execution_iam_name 185 | policy = data.aws_iam_policy.ecs_task_execution.policy 186 | path = var.iam_path 187 | description = var.description 188 | } 189 | 190 | # https://www.terraform.io/docs/providers/aws/r/iam_role_policy_attachment.html 191 | resource "aws_iam_role_policy_attachment" "ecs_task_execution" { 192 | count = local.enabled_ecs_task_execution 193 | 194 | role = aws_iam_role.ecs_task_execution[0].name 195 | policy_arn = aws_iam_policy.ecs_task_execution[0].arn 196 | } 197 | 198 | locals { 199 | ecs_task_execution_iam_name = "${var.name}-ecs-task-execution" 200 | enabled_ecs_task_execution = var.enabled && var.create_ecs_task_execution_role ? 1 : 0 201 | } 202 | 203 | data "aws_iam_policy" "ecs_task_execution" { 204 | arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" 205 | } 206 | -------------------------------------------------------------------------------- /modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmknom/terraform-aws-ecs-scheduled-task/9bcaab6e441a6d6ec33d35f685946d8f7ed88054/modules/.gitkeep -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "cloudwatch_event_rule_arn" { 2 | value = join("", aws_cloudwatch_event_rule.default.*.arn) 3 | description = "The Amazon Resource Name (ARN) of the rule." 4 | } 5 | 6 | output "ecs_events_role_arn" { 7 | value = join("", aws_iam_role.ecs_events.*.arn) 8 | description = "The Amazon Resource Name (ARN) specifying the CloudWatch Events IAM Role." 9 | } 10 | 11 | output "ecs_events_role_create_date" { 12 | value = join("", aws_iam_role.ecs_events.*.create_date) 13 | description = "The creation date of the IAM Role." 14 | } 15 | 16 | output "ecs_events_role_unique_id" { 17 | value = join("", aws_iam_role.ecs_events.*.unique_id) 18 | description = "The stable and unique string identifying the CloudWatch Events IAM Role." 19 | } 20 | 21 | output "ecs_events_role_name" { 22 | value = join("", aws_iam_role.ecs_events.*.name) 23 | description = "The name of the CloudWatch Events IAM Role." 24 | } 25 | 26 | output "ecs_events_role_description" { 27 | value = join("", aws_iam_role.ecs_events.*.description) 28 | description = "The description of the CloudWatch Events IAM Role." 29 | } 30 | 31 | output "ecs_events_policy_id" { 32 | value = join("", aws_iam_policy.ecs_events.*.id) 33 | description = "The CloudWatch Events IAM Policy's ID." 34 | } 35 | 36 | output "ecs_events_policy_arn" { 37 | value = join("", aws_iam_policy.ecs_events.*.arn) 38 | description = "The ARN assigned by AWS to this CloudWatch Events IAM Policy." 39 | } 40 | 41 | output "ecs_events_policy_description" { 42 | value = join("", aws_iam_policy.ecs_events.*.description) 43 | description = "The description of the CloudWatch Events IAM Policy." 44 | } 45 | 46 | output "ecs_events_policy_name" { 47 | value = join("", aws_iam_policy.ecs_events.*.name) 48 | description = "The name of the CloudWatch Events IAM Policy." 49 | } 50 | 51 | output "ecs_events_policy_path" { 52 | value = join("", aws_iam_policy.ecs_events.*.path) 53 | description = "The path of the CloudWatch Events IAM Policy." 54 | } 55 | 56 | output "ecs_events_policy_document" { 57 | value = join("", aws_iam_policy.ecs_events.*.policy) 58 | description = "The policy document of the CloudWatch Events IAM Policy." 59 | } 60 | 61 | output "ecs_task_definition_arn" { 62 | value = join("", aws_ecs_task_definition.default.*.arn) 63 | description = "Full ARN of the Task Definition (including both family and revision)." 64 | } 65 | 66 | output "ecs_task_definition_family" { 67 | value = join("", aws_ecs_task_definition.default.*.family) 68 | description = "The family of the Task Definition." 69 | } 70 | 71 | output "ecs_task_definition_revision" { 72 | value = join("", aws_ecs_task_definition.default.*.revision) 73 | description = "The revision of the task in a particular family." 74 | } 75 | 76 | output "ecs_task_execution_role_arn" { 77 | value = join("", aws_iam_role.ecs_task_execution.*.arn) 78 | description = "The Amazon Resource Name (ARN) specifying the ECS Task Execution IAM Role." 79 | } 80 | 81 | output "ecs_task_execution_role_create_date" { 82 | value = join("", aws_iam_role.ecs_task_execution.*.create_date) 83 | description = "The creation date of the ECS Task Execution IAM Role." 84 | } 85 | 86 | output "ecs_task_execution_role_unique_id" { 87 | value = join("", aws_iam_role.ecs_task_execution.*.unique_id) 88 | description = "The stable and unique string identifying the ECS Task Execution IAM Role." 89 | } 90 | 91 | output "ecs_task_execution_role_name" { 92 | value = join("", aws_iam_role.ecs_task_execution.*.name) 93 | description = "The name of the ECS Task Execution IAM Role." 94 | } 95 | 96 | output "ecs_task_execution_role_description" { 97 | value = join("", aws_iam_role.ecs_task_execution.*.description) 98 | description = "The description of the ECS Task Execution IAM Role." 99 | } 100 | 101 | output "ecs_task_execution_policy_id" { 102 | value = join("", aws_iam_policy.ecs_task_execution.*.id) 103 | description = "The ECS Task Execution IAM Policy's ID." 104 | } 105 | 106 | output "ecs_task_execution_policy_arn" { 107 | value = join("", aws_iam_policy.ecs_task_execution.*.arn) 108 | description = "The ARN assigned by AWS to this ECS Task Execution IAM Policy." 109 | } 110 | 111 | output "ecs_task_execution_policy_description" { 112 | value = join("", aws_iam_policy.ecs_task_execution.*.description) 113 | description = "The description of the ECS Task Execution IAM Policy." 114 | } 115 | 116 | output "ecs_task_execution_policy_name" { 117 | value = join("", aws_iam_policy.ecs_task_execution.*.name) 118 | description = "The name of the ECS Task Execution IAM Policy." 119 | } 120 | 121 | output "ecs_task_execution_policy_path" { 122 | value = join("", aws_iam_policy.ecs_task_execution.*.path) 123 | description = "The path of the ECS Task Execution IAM Policy." 124 | } 125 | 126 | output "ecs_task_execution_policy_document" { 127 | value = join("", aws_iam_policy.ecs_task_execution.*.policy) 128 | description = "The policy document of the ECS Task Execution IAM Policy." 129 | } 130 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | type = string 3 | description = "The name of ecs task definition." 4 | } 5 | 6 | variable "schedule_expression" { 7 | type = string 8 | description = "The scheduling expression.For example, `cron(0 20 * * ? *)` or `rate(5 minutes)`." 9 | } 10 | 11 | variable "cluster_arn" { 12 | type = string 13 | description = "ARN of an ECS cluster." 14 | } 15 | 16 | variable "subnets" { 17 | type = list(string) 18 | description = "The subnets associated with the task or service." 19 | } 20 | 21 | variable "container_definitions" { 22 | type = string 23 | description = "A list of valid container definitions provided as a single valid JSON document." 24 | } 25 | 26 | variable "is_enabled" { 27 | default = true 28 | type = string 29 | description = "Whether the rule should be enabled." 30 | } 31 | 32 | variable "task_count" { 33 | default = 1 34 | type = string 35 | description = "The number of tasks to create based on the TaskDefinition." 36 | } 37 | 38 | variable "platform_version" { 39 | default = "1.4.0" 40 | type = string 41 | description = "Specifies the platform version for the task." 42 | } 43 | 44 | variable "assign_public_ip" { 45 | default = false 46 | type = string 47 | description = "Assign a public IP address to the ENI (Fargate launch type only)." 48 | } 49 | 50 | variable "security_groups" { 51 | default = [] 52 | type = list(string) 53 | description = "The security groups associated with the task or service." 54 | } 55 | 56 | variable "cpu" { 57 | default = "256" 58 | type = string 59 | description = "The number of cpu units used by the task." 60 | } 61 | 62 | variable "memory" { 63 | default = "512" 64 | type = string 65 | description = "The amount (in MiB) of memory used by the task." 66 | } 67 | 68 | variable "requires_compatibilities" { 69 | default = ["FARGATE"] 70 | type = list(string) 71 | description = "A set of launch types required by the task. The valid values are EC2 and FARGATE." 72 | } 73 | 74 | variable "iam_path" { 75 | default = "/" 76 | type = string 77 | description = "Path in which to create the IAM Role and the IAM Policy." 78 | } 79 | 80 | variable "description" { 81 | default = "Managed by Terraform" 82 | type = string 83 | description = "The description of the all resources." 84 | } 85 | 86 | variable "tags" { 87 | default = {} 88 | type = map(string) 89 | description = "A mapping of tags to assign to all resources." 90 | } 91 | 92 | variable "enabled" { 93 | default = true 94 | type = bool 95 | description = "Set to false to prevent the module from creating anything." 96 | } 97 | 98 | variable "create_ecs_events_role" { 99 | default = true 100 | type = string 101 | description = "Specify true to indicate that CloudWatch Events IAM Role creation." 102 | } 103 | 104 | variable "ecs_events_role_arn" { 105 | default = "" 106 | type = string 107 | description = "The ARN of the CloudWatch Events IAM Role." 108 | } 109 | 110 | variable "create_ecs_task_execution_role" { 111 | default = true 112 | type = string 113 | description = "Specify true to indicate that ECS Task Execution IAM Role creation." 114 | } 115 | 116 | variable "ecs_task_execution_role_arn" { 117 | default = "" 118 | type = string 119 | description = "The ARN of the ECS Task Execution IAM Role." 120 | } 121 | -------------------------------------------------------------------------------- /versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 0.12" 3 | } 4 | --------------------------------------------------------------------------------