├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── _scripts ├── check-release-file.py ├── check_for_unused_variables.py ├── deploy.py ├── hypothesistooling.py ├── run_travis_format.py └── validate_interfaces.py ├── api_gateway ├── README.md ├── example │ ├── cognito.tf │ ├── locals.tf │ ├── main.tf │ ├── network.tf │ ├── nlb.tf │ ├── provider.tf │ ├── response.json │ ├── rest_service.tf │ ├── security_groups.tf │ └── static_resource.tf ├── modules │ ├── cors │ │ ├── main.tf │ │ └── variables.tf │ ├── domain │ │ ├── main.tf │ │ ├── ouputs.tf │ │ └── variables.tf │ ├── gateway │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── integration │ │ ├── proxy │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ └── static │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ ├── method │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── resource │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── stage │ │ ├── main.tf │ │ └── variables.tf └── prebuilt │ └── method │ └── static │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── autoscaling ├── alarms │ ├── asg_totalinstances │ │ ├── asg_totalinstances_alarm │ │ │ ├── main.tf │ │ │ └── variables.tf │ │ ├── main.tf │ │ └── variables.tf │ ├── cpureservation │ │ ├── cpureservation_alarm │ │ │ ├── main.tf │ │ │ └── variables.tf │ │ ├── main.tf │ │ └── variables.tf │ ├── custom │ │ ├── alarm │ │ │ ├── main.tf │ │ │ └── variables.tf │ │ ├── main.tf │ │ └── variables.tf │ └── queue │ │ ├── main.tf │ │ └── variables.tf ├── app │ └── ecs │ │ ├── locals.tf │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf ├── asg │ ├── autoscaling_policy │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf └── dynamodb │ ├── README.md │ ├── index_autoscaling.tf │ ├── table_autoscaling.tf │ ├── validation.tf │ └── variables.tf ├── cloudwatch ├── modules │ └── alb │ │ ├── main.tf │ │ └── variables.tf └── prebuilt │ └── alb_alarms │ ├── alarms.tf │ └── variables.tf ├── config ├── README.md ├── config-delivery-channel │ ├── config.tf │ └── variables.tf ├── config-recorder-status │ ├── config.tf │ └── variables.tf └── config-recorder │ ├── config.tf │ └── variables.tf ├── deploy_key.enc ├── ec2 ├── modules │ ├── asg │ │ ├── asg.json.template │ │ ├── asg.tf │ │ ├── iam.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── instance_profile │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── launch_config │ │ ├── ebs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── ondemand │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ └── spot │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ └── security_groups │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf └── prebuilt │ ├── bastion │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ ├── dlami │ ├── README.md │ ├── main.tf │ ├── outputs.tf │ ├── templates │ │ ├── jupyter_notebook_config.py.tpl │ │ ├── requirements.in │ │ ├── requirements.txt │ │ └── userdata.sh.tpl │ └── variables.tf │ ├── ebs │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ ├── ondemand │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ └── spot │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── ecr ├── outputs.tf ├── repository.tf └── variables.tf ├── ecs ├── example │ ├── modules │ │ ├── bastion_hosts.tf │ │ ├── cluster_hosts.tf │ │ ├── images.tf │ │ ├── main.tf │ │ ├── network.tf │ │ ├── provider.tf │ │ ├── security_groups.tf │ │ └── task_definitions.tf │ └── prebuilt │ │ ├── RELEASE.md │ │ ├── fake_metric_data.sh │ │ ├── main.tf │ │ ├── network.tf │ │ ├── provider.tf │ │ └── security_groups.tf ├── modules │ ├── ec2 │ │ ├── README.md │ │ ├── modules │ │ │ ├── instance_role_policy │ │ │ │ ├── main.tf │ │ │ │ └── variables.tf │ │ │ └── userdata │ │ │ │ ├── default.tpl │ │ │ │ ├── ebs+efs.tpl │ │ │ │ ├── ebs.tpl │ │ │ │ ├── efs.tpl │ │ │ │ ├── nvm.tpl │ │ │ │ └── spot.tpl │ │ └── prebuilt │ │ │ ├── ebs+efs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── ebs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── efs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── nvm │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── ondemand │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ └── spot │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ ├── images │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── service │ │ ├── modules │ │ │ ├── iam │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ │ ├── service_discovery │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ │ └── target_group │ │ │ │ ├── http │ │ │ │ ├── locals.tf │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ │ │ └── tcp │ │ │ │ ├── locals.tf │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ └── prebuilt │ │ │ ├── daemon │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── default │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── rest │ │ │ ├── http │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ │ └── tcp │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ └── variables.tf │ │ │ └── scaling │ │ │ ├── autoscaling.tf │ │ │ ├── ecs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ └── task │ │ ├── modules │ │ ├── container_definition │ │ │ ├── container_with_sidecar │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ ├── task_definition.json.template │ │ │ │ └── variables.tf │ │ │ └── single_container │ │ │ │ ├── main.tf │ │ │ │ ├── outputs.tf │ │ │ │ ├── task_definition.json.template │ │ │ │ └── variables.tf │ │ ├── env_vars │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── iam_roles │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── log_group │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── port_mappings │ │ │ └── main.tf │ │ ├── secrets │ │ │ ├── iam.tf │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ └── task_definition │ │ │ ├── default │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── ebs+efs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── ebs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ ├── efs │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ │ └── nvm │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ └── prebuilt │ │ ├── container_with_sidecar+ebs+efs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── container_with_sidecar+ebs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── container_with_sidecar+efs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── container_with_sidecar │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── single_container+ebs+efs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── single_container+ebs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── single_container+efs │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ ├── single_container+nvm │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ │ └── single_container │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf └── prebuilt │ ├── default │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ ├── scaling+nvm │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ └── scaling │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── efs ├── README.md ├── main.tf ├── outputs.tf └── variables.tf ├── iam ├── modules │ ├── assumable_role │ │ ├── aws │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ └── federated │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ └── roleset │ │ ├── main.tf │ │ └── variables.tf └── prebuilt │ ├── account │ ├── aws │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── federated │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── role_policies │ ├── admin │ │ ├── main.tf │ │ └── variables.tf │ ├── assume_role │ │ ├── main.tf │ │ └── variables.tf │ ├── billing │ │ ├── main.tf │ │ └── variables.tf │ ├── developer │ │ ├── main.tf │ │ ├── policies.tf │ │ └── variables.tf │ ├── monitoring │ │ ├── main.tf │ │ └── variables.tf │ ├── publisher │ │ ├── main.tf │ │ ├── policies.tf │ │ └── variables.tf │ └── read_only │ │ ├── main.tf │ │ └── variables.tf │ └── users │ ├── console_user │ ├── main.tf │ ├── outputs.tf │ └── variable.tf │ ├── list_roles_user │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ ├── machine │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ └── read_only │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── kms ├── README.md └── modules │ └── key │ ├── encryption_kms_key.tf │ ├── iam_policy_document.tf │ ├── outputs.tf │ └── variables.tf ├── lambda ├── README.md ├── example │ ├── MyExampleFunction.zip │ ├── main.tf │ ├── network.tf │ ├── provider.tf │ ├── security_groups.tf │ └── setup.tf ├── modules │ ├── iam │ │ ├── iam_policy_document.tf │ │ ├── iam_role.tf │ │ ├── outputs.tf │ │ └── variables.tf │ ├── monitoring │ │ ├── cloudwatch.tf │ │ ├── iam_policy_document.tf │ │ ├── iam_role_policy.tf │ │ ├── outputs.tf │ │ ├── sqs.tf │ │ └── variables.tf │ └── triggers │ │ ├── cloudwatch │ │ ├── cloudwatch.tf │ │ └── variables.tf │ │ ├── dynamo │ │ ├── iam.tf │ │ ├── trigger.tf │ │ └── variables.tf │ │ └── sns │ │ ├── sns.tf │ │ └── variables.tf └── prebuilt │ ├── public │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ └── vpc │ ├── iam_policy_document.tf │ ├── iam_role_policy.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── load_balancer └── network │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── network ├── example │ ├── locals.tf │ ├── main.tf │ └── provider.tf ├── modules │ ├── nat │ │ ├── main.tf │ │ └── variables.tf │ └── subnets │ │ ├── main.tf │ │ ├── output.tf │ │ └── variables.tf └── prebuilt │ ├── subnets │ └── public-igw │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── vpc │ ├── egress_security_group │ ├── main.tf │ ├── outputs.tf │ └── variables.tf │ ├── interface_endpoints │ ├── endpoint │ │ └── main.tf │ ├── main.tf │ └── variables.tf │ └── public-private-igw │ ├── gateway_endpoint │ └── main.tf │ ├── main.tf │ ├── outputs.tf │ ├── variables.tf │ └── vpc_endpoints.tf ├── rds ├── main.tf ├── outputs.tf ├── security_group.tf └── variables.tf ├── sns ├── cross_account_topic_policy.tf ├── outputs.tf ├── sns.tf ├── topic_policy.tf └── variables.tf ├── sqs ├── README.md ├── alarms.tf ├── outputs.tf ├── queue_policy.tf ├── sqs.tf ├── subscription.tf └── variables.tf ├── version.txt └── vhs ├── README.md └── modules ├── dynamo ├── iam_policy_document.tf ├── main.tf ├── outputs.tf └── variables.tf ├── example └── modules │ └── main.tf └── vhs ├── iam_policy_document.tf ├── main.tf ├── outputs.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Compiled files 4 | *.tfstate 5 | *.tfstate.backup 6 | 7 | # Module directory 8 | .terraform/ 9 | .idea/ 10 | 11 | *.pyc 12 | deploy_key 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: sh 2 | 3 | sudo: required 4 | 5 | services: 6 | - docker 7 | 8 | dist: trusty 9 | 10 | branches: 11 | only: 12 | - master 13 | 14 | jobs: 15 | include: 16 | - env: TASK=travis-format 17 | - env: TASK=check-release-file 18 | - env: TASK=deploy 19 | stage: deploy 20 | 21 | script: 22 | - make "$TASK" 23 | 24 | stages: 25 | - test 26 | - name: deploy 27 | if: type = push 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | By participating in this project, you agree to abide by the thoughtbot [code of conduct]. 4 | 5 | [code of conduct]: https://thoughtbot.com/open-source-code-of-conduct 6 | 7 | Fork, then clone the repo: 8 | 9 | git clone git@github.com/wellcometrust/terraform.git 10 | 11 | 12 | Make your change. Test your change! 13 | 14 | Push to your fork and [submit a pull request][pr]. 15 | 16 | [pr]: https://github.com/wellcometrust/terraform/compare/ 17 | 18 | At this point you're waiting on us. We like to at least comment on pull requests 19 | within three business days. We may suggest some changes or improvements or alternatives. 20 | 21 | Some things that will increase the chance that your pull request is accepted: 22 | 23 | * Ensure you `terraform fmt`! 24 | * Write a [good commit message][commit]. 25 | 26 | [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Wellcome Trust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | format: 2 | docker run --rm --tty --volume $$(pwd):/repo --workdir /repo \ 3 | hashicorp/terraform fmt 4 | 5 | check-format: format 6 | git diff --exit-code 7 | 8 | travis-format: 9 | python3 _scripts/check_for_unused_variables.py 10 | python3 _scripts/run_travis_format.py 11 | 12 | check-release-file: 13 | python3 _scripts/check-release-file.py 14 | 15 | deploy: 16 | python3 _scripts/deploy.py 17 | -------------------------------------------------------------------------------- /_scripts/check-release-file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # coding=utf-8 4 | # 5 | # This file is part of Hypothesis, which may be found at 6 | # https://github.com/HypothesisWorks/hypothesis-python 7 | # 8 | # Most of this work is copyright (C) 2013-2017 David R. MacIver 9 | # (david@drmaciver.com), but it contains contributions by others. See 10 | # CONTRIBUTING.rst for a full list of people who may hold copyright, and 11 | # consult the git log if you need to determine who owns an individual 12 | # contribution. 13 | # 14 | # This Source Code Form is subject to the terms of the Mozilla Public License, 15 | # v. 2.0. If a copy of the MPL was not distributed with this file, You can 16 | # obtain one at http://mozilla.org/MPL/2.0/. 17 | # 18 | # END HEADER 19 | 20 | from __future__ import division, print_function, absolute_import 21 | 22 | import os 23 | import sys 24 | 25 | import hypothesistooling as tools 26 | 27 | sys.path.append(os.path.dirname(__file__)) # noqa 28 | 29 | 30 | if __name__ == '__main__': 31 | if tools.has_source_changes(): 32 | if not tools.has_release(): 33 | print( 34 | 'There are source changes but no RELEASE.md. Please create ' 35 | 'one to describe your changes.' 36 | ) 37 | sys.exit(1) 38 | tools.parse_release_file() 39 | -------------------------------------------------------------------------------- /api_gateway/README.md: -------------------------------------------------------------------------------- 1 | # API Gateway 2 | 3 | ... -------------------------------------------------------------------------------- /api_gateway/example/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | vpc_cidr_block = "172.16.0.0/23" 3 | namespace = "api-gw-example" 4 | aws_region = "eu-west-1" 5 | 6 | namespace_id = "${aws_service_discovery_private_dns_namespace.namespace.id}" 7 | cluster_id = "${aws_ecs_cluster.cluster.id}" 8 | cluster_name = "${aws_ecs_cluster.cluster.name}" 9 | vpc_id = "${module.network.vpc_id}" 10 | 11 | nlb_listener_port = "80" 12 | nlb_listener_port_stage = "8080" 13 | 14 | container_port = "80" 15 | 16 | external_path = "example" 17 | 18 | scope_name = "example" 19 | scope_id = "${aws_cognito_resource_server.api.identifier}/${local.scope_name}" 20 | 21 | subnets = "${module.network.private_subnets}" 22 | } 23 | -------------------------------------------------------------------------------- /api_gateway/example/network.tf: -------------------------------------------------------------------------------- 1 | resource "aws_ecs_cluster" "cluster" { 2 | name = "${local.namespace}" 3 | } 4 | 5 | module "network" { 6 | source = "../../network/prebuilt/vpc/public-private-igw" 7 | name = "${local.namespace}" 8 | 9 | az_count = "1" 10 | 11 | cidr_block_public = "172.42.0.0/23" 12 | cidrsubnet_newbits_public = "1" 13 | 14 | cidr_block_private = "172.43.0.0/23" 15 | cidrsubnet_newbits_private = "1" 16 | 17 | cidr_block_vpc = "${local.vpc_cidr_block}" 18 | } 19 | 20 | resource "aws_service_discovery_private_dns_namespace" "namespace" { 21 | name = "${local.namespace}" 22 | vpc = "${module.network.vpc_id}" 23 | } 24 | -------------------------------------------------------------------------------- /api_gateway/example/nlb.tf: -------------------------------------------------------------------------------- 1 | # Load balancer 2 | 3 | module "nlb" { 4 | source = "../../load_balancer/network" 5 | 6 | namespace = "${local.namespace}" 7 | private_subnets = "${local.subnets}" 8 | } 9 | 10 | # Targetting example service 11 | 12 | data "aws_lb_target_group" "target_group" { 13 | name = "${module.example_rest_service.target_group_name}" 14 | } 15 | 16 | resource "aws_lb_listener" "tcp" { 17 | load_balancer_arn = "${module.nlb.arn}" 18 | port = "${local.nlb_listener_port}" 19 | protocol = "TCP" 20 | 21 | default_action { 22 | type = "forward" 23 | target_group_arn = "${data.aws_lb_target_group.target_group.arn}" 24 | } 25 | } 26 | 27 | # Targetting example service - stage 28 | 29 | data "aws_lb_target_group" "target_group_stage" { 30 | name = "${module.example_rest_service_stage.target_group_name}" 31 | } 32 | 33 | resource "aws_lb_listener" "tcp_stage" { 34 | load_balancer_arn = "${module.nlb.arn}" 35 | port = "${local.nlb_listener_port_stage}" 36 | protocol = "TCP" 37 | 38 | default_action { 39 | type = "forward" 40 | target_group_arn = "${data.aws_lb_target_group.target_group_stage.arn}" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /api_gateway/example/provider.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${local.aws_region}" 4 | 5 | version = "1.42.0" 6 | } 7 | 8 | data "aws_caller_identity" "current" {} 9 | -------------------------------------------------------------------------------- /api_gateway/example/response.json: -------------------------------------------------------------------------------- 1 | { 2 | "content": "Hello World!" 3 | } -------------------------------------------------------------------------------- /api_gateway/example/static_resource.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | bucket_name = "${local.namespace}-wellcome-tf-examples" 3 | key = "response.json" 4 | 5 | file = "response.json" 6 | } 7 | 8 | resource "aws_s3_bucket" "bucket" { 9 | bucket = "${local.bucket_name}" 10 | } 11 | 12 | resource "aws_s3_bucket_object" "object" { 13 | bucket = "${local.bucket_name}" 14 | key = "${local.key}" 15 | source = "${local.file}" 16 | etag = "${md5(file(local.file))}" 17 | } 18 | 19 | resource "aws_iam_role" "static_resource_role" { 20 | assume_role_policy = "${data.aws_iam_policy_document.api_gateway_assume_role.json}" 21 | } 22 | 23 | data "aws_iam_policy_document" "api_gateway_assume_role" { 24 | statement { 25 | actions = [ 26 | "sts:AssumeRole", 27 | ] 28 | 29 | principals { 30 | type = "Service" 31 | identifiers = ["apigateway.amazonaws.com"] 32 | } 33 | } 34 | } 35 | 36 | resource "aws_iam_role_policy" "allow_gateway_s3_access" { 37 | policy = "${data.aws_iam_policy_document.static_content_get.json}" 38 | role = "${aws_iam_role.static_resource_role.id}" 39 | } 40 | 41 | data "aws_iam_policy_document" "static_content_get" { 42 | statement { 43 | actions = [ 44 | "s3:GetObject*", 45 | ] 46 | 47 | resources = [ 48 | "${aws_s3_bucket.bucket.arn}/${local.key}", 49 | ] 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /api_gateway/modules/cors/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | variable "api_resource_id" {} 3 | variable "http_method" {} 4 | variable "allowed_headers" {} 5 | variable "allowed_methods" {} 6 | variable "allowed_origin" {} 7 | variable "allowed_max_age" {} 8 | -------------------------------------------------------------------------------- /api_gateway/modules/domain/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_acm_certificate" "certificate" { 2 | domain = "${var.cert_domain_name}" 3 | statuses = ["ISSUED"] 4 | } 5 | 6 | resource "aws_api_gateway_domain_name" "stage" { 7 | domain_name = "${var.domain_name}" 8 | 9 | regional_certificate_arn = "${data.aws_acm_certificate.certificate.arn}" 10 | 11 | endpoint_configuration = { 12 | types = ["REGIONAL"] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /api_gateway/modules/domain/ouputs.tf: -------------------------------------------------------------------------------- 1 | output "domain_name" { 2 | value = "${aws_api_gateway_domain_name.stage.domain_name}" 3 | } 4 | -------------------------------------------------------------------------------- /api_gateway/modules/domain/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cert_domain_name" {} 2 | variable "domain_name" {} 3 | -------------------------------------------------------------------------------- /api_gateway/modules/gateway/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_api_gateway_rest_api" "api" { 2 | name = "${var.name}" 3 | 4 | endpoint_configuration = { 5 | types = ["${var.endpoint_config_types}"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /api_gateway/modules/gateway/outputs.tf: -------------------------------------------------------------------------------- 1 | output "id" { 2 | value = "${aws_api_gateway_rest_api.api.id}" 3 | } 4 | 5 | output "root_resource_id" { 6 | value = "${module.root_resource.resource_id}" 7 | } 8 | -------------------------------------------------------------------------------- /api_gateway/modules/gateway/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | 3 | variable "endpoint_config_types" { 4 | type = "list" 5 | default = ["REGIONAL"] 6 | } 7 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/proxy/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | domain = "${var.hostname}:${var.forward_port}" 3 | uri = "http://${local.domain}/${var.forward_path}" 4 | } 5 | 6 | resource "aws_api_gateway_integration" "proxy" { 7 | rest_api_id = "${var.api_id}" 8 | resource_id = "${var.resource_id}" 9 | http_method = "${var.http_method}" 10 | 11 | integration_http_method = "${var.integration_method}" 12 | type = "HTTP_PROXY" 13 | connection_type = "VPC_LINK" 14 | connection_id = "${var.connection_id}" 15 | uri = "${local.uri}" 16 | 17 | request_parameters = "${var.request_parameters}" 18 | } 19 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/proxy/outputs.tf: -------------------------------------------------------------------------------- 1 | output "uri" { 2 | value = "${aws_api_gateway_integration.proxy.uri}" 3 | } 4 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/proxy/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | variable "resource_id" {} 3 | 4 | variable "http_method" {} 5 | 6 | variable "integration_method" { 7 | default = "ANY" 8 | } 9 | 10 | variable "connection_id" {} 11 | 12 | variable "forward_port" {} 13 | 14 | variable "forward_path" {} 15 | 16 | variable "hostname" {} 17 | 18 | variable "request_parameters" { 19 | type = "map" 20 | default = {} 21 | } 22 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/static/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_api_gateway_integration" "resource_s3_integration" { 2 | rest_api_id = "${var.api_id}" 3 | resource_id = "${var.resource_id}" 4 | http_method = "${var.http_method}" 5 | integration_http_method = "GET" 6 | type = "AWS" 7 | uri = "arn:aws:apigateway:${var.aws_region}:s3:path//${var.bucket_name}/${var.s3_key}" 8 | 9 | credentials = "${var.static_resource_role_arn}" 10 | } 11 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/static/outputs.tf: -------------------------------------------------------------------------------- 1 | output "id" { 2 | value = "${aws_api_gateway_integration.resource_s3_integration.id}" 3 | } 4 | -------------------------------------------------------------------------------- /api_gateway/modules/integration/static/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | variable "resource_id" {} 3 | variable "http_method" {} 4 | 5 | variable "aws_region" { 6 | default = "eu-west-1" 7 | } 8 | 9 | variable "bucket_name" {} 10 | variable "s3_key" {} 11 | variable "static_resource_role_arn" {} 12 | -------------------------------------------------------------------------------- /api_gateway/modules/method/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | auth_count = "${var.authorization == "" ? 0 : 1}" 3 | no_auth_count = "${var.authorization == "" ? 1 : 0}" 4 | } 5 | 6 | resource "aws_api_gateway_method" "auth" { 7 | count = "${local.auth_count}" 8 | 9 | rest_api_id = "${var.api_id}" 10 | resource_id = "${var.resource_id}" 11 | http_method = "${var.http_method}" 12 | 13 | authorization = "${var.authorization}" 14 | authorizer_id = "${var.authorizer_id}" 15 | authorization_scopes = ["${var.authorization_scopes}"] 16 | 17 | request_parameters = "${var.request_parameters}" 18 | } 19 | 20 | resource "aws_api_gateway_method" "no_auth" { 21 | count = "${local.no_auth_count}" 22 | 23 | rest_api_id = "${var.api_id}" 24 | resource_id = "${var.resource_id}" 25 | http_method = "${var.http_method}" 26 | 27 | authorization = "NONE" 28 | 29 | request_parameters = "${var.request_parameters}" 30 | } 31 | -------------------------------------------------------------------------------- /api_gateway/modules/method/outputs.tf: -------------------------------------------------------------------------------- 1 | output "http_method" { 2 | value = "${var.http_method}" 3 | } 4 | -------------------------------------------------------------------------------- /api_gateway/modules/method/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | 3 | variable "http_method" { 4 | default = "ANY" 5 | } 6 | 7 | variable "request_parameters" { 8 | type = "map" 9 | default = {} 10 | } 11 | 12 | variable "authorization" { 13 | default = "" 14 | } 15 | 16 | variable "authorizer_id" { 17 | default = "not_real" 18 | } 19 | 20 | variable "authorization_scopes" { 21 | type = "list" 22 | default = [] 23 | } 24 | 25 | variable "resource_id" {} 26 | -------------------------------------------------------------------------------- /api_gateway/modules/resource/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_api_gateway_resource" "resource" { 2 | rest_api_id = "${var.api_id}" 3 | parent_id = "${var.parent_id}" 4 | path_part = "${var.path_part}" 5 | } 6 | 7 | module "method" { 8 | source = "../method" 9 | 10 | api_id = "${var.api_id}" 11 | resource_id = "${aws_api_gateway_resource.resource.id}" 12 | 13 | authorization = "${var.authorization}" 14 | authorizer_id = "${var.authorizer_id}" 15 | authorization_scopes = ["${var.auth_scopes}"] 16 | 17 | http_method = "${var.http_method}" 18 | 19 | request_parameters = "${var.request_parameters}" 20 | } 21 | -------------------------------------------------------------------------------- /api_gateway/modules/resource/outputs.tf: -------------------------------------------------------------------------------- 1 | output "http_method" { 2 | value = "${var.http_method}" 3 | } 4 | 5 | output "resource_id" { 6 | value = "${aws_api_gateway_resource.resource.id}" 7 | } 8 | -------------------------------------------------------------------------------- /api_gateway/modules/resource/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | 3 | variable "http_method" { 4 | default = "ANY" 5 | } 6 | 7 | variable "request_parameters" { 8 | type = "map" 9 | default = {} 10 | } 11 | 12 | variable "authorization" { 13 | default = "" 14 | } 15 | 16 | variable "authorizer_id" { 17 | default = "not_real" 18 | } 19 | 20 | variable "auth_scopes" { 21 | type = "list" 22 | default = [] 23 | } 24 | 25 | variable "path_part" {} 26 | variable "parent_id" {} 27 | -------------------------------------------------------------------------------- /api_gateway/modules/stage/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | dependencies_md5 = "${md5(join(",", var.depends_on))}" 3 | 4 | // Add hash of dependencies to the variables block to force 5 | // new deployment if dependencies change 6 | variables = "${merge(var.variables, map("dependencies_md5", local.dependencies_md5))}" 7 | } 8 | 9 | resource "aws_api_gateway_deployment" "stage" { 10 | rest_api_id = "${var.api_id}" 11 | stage_name = "${var.stage_name}" 12 | 13 | variables = "${local.variables}" 14 | 15 | lifecycle { 16 | create_before_destroy = true 17 | } 18 | } 19 | 20 | resource "aws_api_gateway_stage" "stage" { 21 | stage_name = "${var.stage_name}" 22 | rest_api_id = "${var.api_id}" 23 | deployment_id = "${aws_api_gateway_deployment.stage.id}" 24 | 25 | variables = "${local.variables}" 26 | } 27 | -------------------------------------------------------------------------------- /api_gateway/modules/stage/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | 3 | variable "variables" { 4 | type = "map" 5 | default = {} 6 | } 7 | 8 | variable "depends_on" { 9 | type = "list" 10 | } 11 | 12 | variable "stage_name" {} 13 | -------------------------------------------------------------------------------- /api_gateway/prebuilt/method/static/main.tf: -------------------------------------------------------------------------------- 1 | module "method" { 2 | source = "../../../modules/method" 3 | 4 | http_method = "${var.http_method}" 5 | 6 | api_id = "${var.api_id}" 7 | resource_id = "${var.resource_id}" 8 | } 9 | 10 | module "static_integration" { 11 | source = "../../../modules/integration/static" 12 | 13 | resource_id = "${var.resource_id}" 14 | 15 | aws_region = "${var.aws_region}" 16 | bucket_name = "${var.bucket_name}" 17 | s3_key = "${var.s3_key}" 18 | 19 | api_id = "${var.api_id}" 20 | http_method = "${module.method.http_method}" 21 | 22 | static_resource_role_arn = "${var.static_resource_role_arn}" 23 | } 24 | 25 | resource "aws_api_gateway_method_response" "200" { 26 | rest_api_id = "${var.api_id}" 27 | resource_id = "${var.resource_id}" 28 | http_method = "${module.method.http_method}" 29 | status_code = "200" 30 | } 31 | 32 | resource "aws_api_gateway_integration_response" "200" { 33 | rest_api_id = "${var.api_id}" 34 | resource_id = "${var.resource_id}" 35 | http_method = "${module.method.http_method}" 36 | status_code = "${aws_api_gateway_method_response.200.status_code}" 37 | } 38 | -------------------------------------------------------------------------------- /api_gateway/prebuilt/method/static/outputs.tf: -------------------------------------------------------------------------------- 1 | output "http_method" { 2 | value = "${module.method.http_method}" 3 | } 4 | 5 | output "integration_id" { 6 | value = "${module.static_integration.id}" 7 | } 8 | 9 | output "integration_response_resource_id" { 10 | value = "${aws_api_gateway_integration_response.200.resource_id}" 11 | } 12 | -------------------------------------------------------------------------------- /api_gateway/prebuilt/method/static/variables.tf: -------------------------------------------------------------------------------- 1 | variable "api_id" {} 2 | variable "resource_id" {} 3 | 4 | variable "http_method" { 5 | default = "GET" 6 | } 7 | 8 | variable "aws_region" {} 9 | variable "bucket_name" {} 10 | variable "s3_key" {} 11 | 12 | variable "static_resource_role_arn" {} 13 | -------------------------------------------------------------------------------- /autoscaling/alarms/asg_totalinstances/asg_totalinstances_alarm/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_metric_alarm" "asg_totalinstances" { 2 | alarm_name = "${var.name}-asg_totalinstances_${var.comparison_operator}" 3 | comparison_operator = "${var.comparison_operator}" 4 | evaluation_periods = "1" 5 | metric_name = "GroupTotalInstances" 6 | 7 | dimensions { 8 | AutoScalingGroupName = "${var.asg_name}" 9 | } 10 | 11 | statistic = "Average" 12 | namespace = "AWS/AutoScaling" 13 | 14 | period = "${var.period}" 15 | threshold = "${var.threshold}" 16 | 17 | treat_missing_data = "${var.treat_missing_data}" 18 | 19 | alarm_actions = [ 20 | "${var.target_arn}", 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /autoscaling/alarms/asg_totalinstances/asg_totalinstances_alarm/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "comparison_operator" {} 3 | variable "asg_name" {} 4 | variable "period" {} 5 | variable "threshold" {} 6 | 7 | variable "treat_missing_data" { 8 | default = "missing" 9 | } 10 | 11 | variable "target_arn" {} 12 | -------------------------------------------------------------------------------- /autoscaling/alarms/asg_totalinstances/main.tf: -------------------------------------------------------------------------------- 1 | module "asg_totalinstances_high" { 2 | source = "./asg_totalinstances_alarm" 3 | name = "${var.name}-aws_totalinstances_high" 4 | 5 | asg_name = "${var.asg_name}" 6 | 7 | period = "${var.high_period}" 8 | threshold = "${var.high_threshold}" 9 | 10 | comparison_operator = "GreaterThanOrEqualToThreshold" 11 | treat_missing_data = "${var.treat_missing_data_high}" 12 | 13 | target_arn = "${var.scale_down_arn}" 14 | } 15 | 16 | module "asg_totalinstances_low" { 17 | source = "./asg_totalinstances_alarm" 18 | name = "${var.name}-aws_totalinstances_low" 19 | 20 | asg_name = "${var.asg_name}" 21 | 22 | period = "${var.low_period}" 23 | threshold = "${var.low_threshold}" 24 | 25 | comparison_operator = "LessThanThreshold" 26 | treat_missing_data = "${var.treat_missing_data_low}" 27 | 28 | target_arn = "${var.scale_up_arn}" 29 | } 30 | -------------------------------------------------------------------------------- /autoscaling/alarms/asg_totalinstances/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | 3 | variable "asg_name" {} 4 | 5 | variable "scale_up_arn" {} 6 | variable "scale_down_arn" {} 7 | 8 | variable "treat_missing_data_high" { 9 | default = "missing" 10 | } 11 | 12 | variable "treat_missing_data_low" { 13 | default = "missing" 14 | } 15 | 16 | variable "high_period" { 17 | default = "60" 18 | } 19 | 20 | variable "high_threshold" { 21 | default = "1" 22 | } 23 | 24 | variable "low_period" { 25 | default = "600" 26 | } 27 | 28 | variable "low_threshold" { 29 | default = "1" 30 | } 31 | -------------------------------------------------------------------------------- /autoscaling/alarms/cpureservation/cpureservation_alarm/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_metric_alarm" "ecs_cpureservation_high" { 2 | alarm_name = "${var.name}-ecs_cpureservation_${var.comparison_operator}" 3 | comparison_operator = "${var.comparison_operator}" 4 | 5 | // Actual period during which the threshold is evaluated 6 | // It depends on the size of the periods over which statistics 7 | // datapoints are generated. 8 | // Our datapoints are hardcoded to represent statistics 9 | // over one minute (see below), so the evaluation period 10 | // is defined in minutes 11 | evaluation_periods = "${var.period_in_minutes}" 12 | 13 | datapoints_to_alarm = "${var.period_in_minutes}" 14 | metric_name = "CPUReservation" 15 | 16 | dimensions { 17 | ClusterName = "${var.cluster_name}" 18 | } 19 | 20 | statistic = "Average" 21 | namespace = "AWS/ECS" 22 | 23 | // This is the period over which the statistic is calculated 24 | // An evaluation over this period produces one datapoint 25 | // This is NOT the period during which the threshold is evaluated 26 | period = "60" 27 | 28 | threshold = "${var.threshold}" 29 | 30 | treat_missing_data = "${var.treat_missing_data}" 31 | 32 | alarm_actions = [ 33 | "${var.target_arn}", 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /autoscaling/alarms/cpureservation/cpureservation_alarm/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "comparison_operator" {} 3 | variable "cluster_name" {} 4 | variable "period_in_minutes" {} 5 | variable "threshold" {} 6 | 7 | variable "treat_missing_data" { 8 | default = "missing" 9 | } 10 | 11 | variable "target_arn" {} 12 | -------------------------------------------------------------------------------- /autoscaling/alarms/cpureservation/main.tf: -------------------------------------------------------------------------------- 1 | module "cpureservation_high" { 2 | source = "./cpureservation_alarm" 3 | name = "${var.name}-cpureservation_high" 4 | 5 | cluster_name = "${var.cluster_name}" 6 | 7 | period_in_minutes = "${var.high_period_in_minutes}" 8 | threshold = "${var.high_threshold}" 9 | 10 | comparison_operator = "GreaterThanOrEqualToThreshold" 11 | treat_missing_data = "${var.treat_missing_data_high}" 12 | 13 | target_arn = "${var.scale_up_arn}" 14 | } 15 | 16 | module "cpureservation_low" { 17 | source = "./cpureservation_alarm" 18 | name = "${var.name}-cpureservation_low" 19 | 20 | cluster_name = "${var.cluster_name}" 21 | 22 | period_in_minutes = "${var.low_period_in_minutes}" 23 | threshold = "${var.low_threshold}" 24 | 25 | comparison_operator = "LessThanThreshold" 26 | treat_missing_data = "${var.treat_missing_data_low}" 27 | 28 | target_arn = "${var.scale_down_arn}" 29 | } 30 | -------------------------------------------------------------------------------- /autoscaling/alarms/cpureservation/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | 3 | variable "cluster_name" {} 4 | 5 | variable "scale_up_arn" {} 6 | variable "scale_down_arn" {} 7 | 8 | variable "treat_missing_data_high" { 9 | default = "missing" 10 | } 11 | 12 | variable "treat_missing_data_low" { 13 | default = "missing" 14 | } 15 | 16 | variable "high_period_in_minutes" {} 17 | 18 | variable "high_threshold" { 19 | default = "80" 20 | } 21 | 22 | variable "low_period_in_minutes" {} 23 | 24 | variable "low_threshold" { 25 | default = "80" 26 | } 27 | -------------------------------------------------------------------------------- /autoscaling/alarms/custom/alarm/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_metric_alarm" "alarm" { 2 | alarm_name = "${var.name}_${var.comparison_operator}" 3 | comparison_operator = "${var.comparison_operator}" 4 | 5 | evaluation_periods = "${var.period_in_minutes}" 6 | 7 | datapoints_to_alarm = "${var.period_in_minutes}" 8 | metric_name = "${var.metric_name}" 9 | 10 | statistic = "${var.statistic}" 11 | namespace = "${var.namespace}" 12 | 13 | // This is the period over which the statistic is calculated 14 | // An evaluation over this period produces one datapoint 15 | // This is NOT the period during which the threshold is evaluated 16 | period = "${var.period}" 17 | 18 | threshold = "${var.threshold}" 19 | 20 | treat_missing_data = "${var.treat_missing_data}" 21 | 22 | alarm_actions = [ 23 | "${var.target_arn}", 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /autoscaling/alarms/custom/alarm/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "comparison_operator" {} 3 | variable "period_in_minutes" {} 4 | variable "threshold" {} 5 | variable "target_arn" {} 6 | variable "metric_name" {} 7 | variable "statistic" {} 8 | 9 | variable "treat_missing_data" { 10 | default = "missing" 11 | } 12 | 13 | variable "namespace" {} 14 | 15 | variable "period" { 16 | default = "60" 17 | } 18 | -------------------------------------------------------------------------------- /autoscaling/alarms/custom/main.tf: -------------------------------------------------------------------------------- 1 | module "high" { 2 | source = "./alarm" 3 | name = "${var.name}_high" 4 | 5 | period_in_minutes = "${var.high_period_in_minutes}" 6 | threshold = "${var.high_threshold}" 7 | 8 | comparison_operator = "GreaterThanOrEqualToThreshold" 9 | 10 | target_arn = "${var.scale_up_arn}" 11 | metric_name = "${var.high_metric_name}" 12 | statistic = "Maximum" 13 | 14 | namespace = "${var.namespace}" 15 | } 16 | 17 | module "low" { 18 | source = "./alarm" 19 | name = "${var.name}_low" 20 | 21 | period_in_minutes = "${var.low_period_in_minutes}" 22 | threshold = "${var.low_threshold}" 23 | 24 | comparison_operator = "LessThanThreshold" 25 | 26 | target_arn = "${var.scale_down_arn}" 27 | metric_name = "${var.low_metric_name}" 28 | statistic = "Sum" 29 | 30 | namespace = "${var.namespace}" 31 | } 32 | -------------------------------------------------------------------------------- /autoscaling/alarms/custom/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | 3 | variable "scale_up_arn" {} 4 | variable "scale_down_arn" {} 5 | 6 | variable "high_period_in_minutes" { 7 | default = 1 8 | } 9 | 10 | variable "high_threshold" { 11 | default = 1 12 | } 13 | 14 | variable "low_period_in_minutes" { 15 | default = 1 16 | } 17 | 18 | variable "low_threshold" { 19 | default = 1 20 | } 21 | 22 | variable "high_metric_name" {} 23 | variable "low_metric_name" {} 24 | 25 | variable "namespace" {} 26 | -------------------------------------------------------------------------------- /autoscaling/alarms/queue/variables.tf: -------------------------------------------------------------------------------- 1 | variable "queue_name" {} 2 | 3 | variable "queue_low_actions" { 4 | type = "list" 5 | } 6 | 7 | variable "queue_high_actions" { 8 | type = "list" 9 | } 10 | -------------------------------------------------------------------------------- /autoscaling/app/ecs/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_id = "service/${var.cluster_name}/${var.service_name}" 3 | } 4 | -------------------------------------------------------------------------------- /autoscaling/app/ecs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "scale_down_arn" { 2 | value = "${aws_appautoscaling_policy.scale_down.arn}" 3 | } 4 | 5 | output "scale_up_arn" { 6 | value = "${aws_appautoscaling_policy.scale_up.arn}" 7 | } 8 | -------------------------------------------------------------------------------- /autoscaling/app/ecs/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "cluster_name" {} 3 | variable "service_name" {} 4 | 5 | variable "scale_up_adjustment" { 6 | default = 1 7 | } 8 | 9 | variable "scale_down_adjustment" { 10 | default = -1 11 | } 12 | 13 | variable "min_capacity" { 14 | default = 0 15 | } 16 | 17 | variable "max_capacity" { 18 | default = 3 19 | } 20 | 21 | variable "metric_interval_lower_bound_scale_up" { 22 | default = 0 23 | } 24 | 25 | variable "metric_interval_upper_bound_scale_down" { 26 | default = 0 27 | } 28 | -------------------------------------------------------------------------------- /autoscaling/asg/autoscaling_policy/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_autoscaling_policy" "policy" { 2 | name = "${var.name}-scale(${var.scaling_adjustment})" 3 | 4 | scaling_adjustment = "${var.scaling_adjustment}" 5 | adjustment_type = "ChangeInCapacity" 6 | 7 | cooldown = "${var.cooldown}" 8 | 9 | autoscaling_group_name = "${var.scalegroup_name}" 10 | } 11 | -------------------------------------------------------------------------------- /autoscaling/asg/autoscaling_policy/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_scale_arn" { 2 | value = "${aws_autoscaling_policy.policy.arn}" 3 | } 4 | -------------------------------------------------------------------------------- /autoscaling/asg/autoscaling_policy/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "scaling_adjustment" {} 3 | variable "scalegroup_name" {} 4 | 5 | variable "cooldown" { 6 | default = 300 7 | } 8 | -------------------------------------------------------------------------------- /autoscaling/asg/main.tf: -------------------------------------------------------------------------------- 1 | module "scale_up" { 2 | source = "./autoscaling_policy" 3 | name = "${var.name}-scale-up" 4 | 5 | scalegroup_name = "${var.scalegroup_name}" 6 | scaling_adjustment = "${var.scale_up_adjustment}" 7 | } 8 | 9 | module "scale_down" { 10 | source = "./autoscaling_policy" 11 | name = "${var.name}-scale-down" 12 | 13 | scalegroup_name = "${var.scalegroup_name}" 14 | scaling_adjustment = "${var.scale_down_adjustment}" 15 | } 16 | -------------------------------------------------------------------------------- /autoscaling/asg/outputs.tf: -------------------------------------------------------------------------------- 1 | output "scale_down_arn" { 2 | value = "${module.scale_down.asg_scale_arn}" 3 | } 4 | 5 | output "scale_up_arn" { 6 | value = "${module.scale_up.asg_scale_arn}" 7 | } 8 | -------------------------------------------------------------------------------- /autoscaling/asg/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" {} 2 | variable "scalegroup_name" {} 3 | 4 | variable "scale_up_adjustment" { 5 | default = 1 6 | } 7 | 8 | variable "scale_down_adjustment" { 9 | default = -1 10 | } 11 | -------------------------------------------------------------------------------- /autoscaling/dynamodb/README.md: -------------------------------------------------------------------------------- 1 | # autoscaling/dynamodb 2 | 3 | This module allows you to apply autoscaling to a DynamoDB table. 4 | 5 | ## Usage 6 | 7 | Here's an example that auto scales both read and write capacity: 8 | 9 | ```hcl 10 | module "dynamo_autoscaling" { 11 | source = "git::https://github.com/wellcometrust/terraform.git//autoscaling/dynamodb?ref=v6.3.0" 12 | 13 | table_name = "my_table" 14 | 15 | enable_read_scaling = true 16 | read_target_utilization = 70 17 | read_min_capacity = 1 18 | read_max_capacity = 100 19 | 20 | enable_write_scaling = true 21 | write_target_utilization = 80 22 | write_min_capacity = 1 23 | write_max_capacity = 200 24 | } 25 | ``` 26 | 27 | If you only want auto scaling in one dimension, you can omit the parameters for the other dimension. 28 | For example, a table which only has reads scaling: 29 | 30 | ```hcl 31 | module "readonly_dynamo_autoscaling" { 32 | source = "git::https://github.com/wellcometrust/terraform.git//autoscaling/dynamodb?ref=v6.3.0" 33 | 34 | table_name = "my_readonly_table" 35 | 36 | enable_read_scaling = true 37 | read_target_utilization = 70 38 | read_min_capacity = 1 39 | read_max_capacity = 100 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /autoscaling/dynamodb/variables.tf: -------------------------------------------------------------------------------- 1 | variable "table_name" { 2 | description = "Name of the DynamoDB table to auto scale" 3 | } 4 | 5 | variable "enable_read_scaling" { 6 | description = "Whether to enable auto scaling for read capacity" 7 | default = false 8 | } 9 | 10 | variable "read_target_utilization" { 11 | description = "Target utilization percent for read capacity" 12 | default = "" 13 | } 14 | 15 | variable "read_min_capacity" { 16 | description = "Minimum provisioned read capacity" 17 | default = "" 18 | } 19 | 20 | variable "read_max_capacity" { 21 | description = "Maximum provisioned read capacity" 22 | default = "" 23 | } 24 | 25 | variable "enable_write_scaling" { 26 | description = "Whether to enable auto scaling for write capacity" 27 | default = false 28 | } 29 | 30 | variable "write_target_utilization" { 31 | description = "Target utilization percent for write capacity" 32 | default = "" 33 | } 34 | 35 | variable "write_min_capacity" { 36 | description = "Minimum provisioned write capacity" 37 | default = "" 38 | } 39 | 40 | variable "write_max_capacity" { 41 | description = "Maximum provisioned write capacity" 42 | default = "" 43 | } 44 | 45 | variable "index_name" { 46 | default = "" 47 | } 48 | -------------------------------------------------------------------------------- /cloudwatch/modules/alb/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_metric_alarm" "alb_alarm" { 2 | count = "${var.enable_alarm}" 3 | 4 | alarm_name = "${var.name}" 5 | comparison_operator = "${var.comparison_operator}" 6 | evaluation_periods = "1" 7 | metric_name = "${var.metric}" 8 | namespace = "AWS/ApplicationELB" 9 | period = "60" 10 | statistic = "Sum" 11 | threshold = "${var.threshold}" 12 | treat_missing_data = "${var.treat_missing_data}" 13 | 14 | dimensions { 15 | LoadBalancer = "${var.lb_dimension}" 16 | TargetGroup = "${var.tg_dimension}" 17 | } 18 | 19 | alarm_description = "This metric monitors ${var.name}" 20 | alarm_actions = ["${var.topic_arn}"] 21 | } 22 | -------------------------------------------------------------------------------- /cloudwatch/modules/alb/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "Name of the alarm" 3 | } 4 | 5 | variable "lb_dimension" { 6 | description = "LoadBalancer ARN Suffix" 7 | } 8 | 9 | variable "tg_dimension" { 10 | description = "TargetGroup ARN Suffix" 11 | } 12 | 13 | variable "topic_arn" { 14 | description = "SNS Topic to publish alarm state changes" 15 | } 16 | 17 | variable "enable_alarm" {} 18 | 19 | variable "metric" {} 20 | 21 | variable "threshold" { 22 | default = 1 23 | } 24 | 25 | variable "comparison_operator" { 26 | default = "GreaterThanOrEqualToThreshold" 27 | } 28 | 29 | variable "treat_missing_data" { 30 | default = "missing" 31 | } 32 | -------------------------------------------------------------------------------- /cloudwatch/prebuilt/alb_alarms/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | 3 | variable "server_error_alarm_topic_arn" {} 4 | 5 | variable "target_group_id" {} 6 | 7 | variable "loadbalancer_cloudwatch_id" {} 8 | 9 | variable "client_error_alarm_topic_arn" {} 10 | 11 | variable "healthy_host_threshold" {} 12 | 13 | variable "enable_alb_alarm" { 14 | default = 1 15 | } 16 | -------------------------------------------------------------------------------- /config/config-delivery-channel/config.tf: -------------------------------------------------------------------------------- 1 | resource "aws_config_delivery_channel" "config-recorder" { 2 | name = "${var.name}" 3 | s3_bucket_name = "${var.s3_bucket_name}" 4 | s3_key_prefix = "${var.s3_key_prefix}" 5 | depends_on = "${var.depends_on}" 6 | 7 | snapshot_delivery_properties { 8 | delivery_frequency = "${var.delivery_frequency}" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /config/config-delivery-channel/variables.tf: -------------------------------------------------------------------------------- 1 | # Variables for Config Delivery channel 2 | variable "name" {} 3 | 4 | variable "s3_bucket_name" {} 5 | variable "s3_key_prefix" {} 6 | variable "delivery_frequency" {} 7 | variable "depends_on" {} 8 | -------------------------------------------------------------------------------- /config/config-recorder-status/config.tf: -------------------------------------------------------------------------------- 1 | resource "aws_config_configuration_recorder_status" "config-recorder" { 2 | name = "${var.name}" 3 | is_enabled = "${var.is_enabled}" 4 | } 5 | -------------------------------------------------------------------------------- /config/config-recorder-status/variables.tf: -------------------------------------------------------------------------------- 1 | # Variables for AWS config recorder status 2 | variable "name" {} 3 | variable "is_enabled" {} 4 | -------------------------------------------------------------------------------- /config/config-recorder/config.tf: -------------------------------------------------------------------------------- 1 | resource "aws_config_configuration_recorder" "config-recorder" { 2 | name = "${var.name}" 3 | role_arn = "${var.role_arn}" 4 | 5 | recording_group { 6 | all_supported = "${var.all_supported}" 7 | include_global_resource_types = "${var.include_global_resource_types}" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/config-recorder/variables.tf: -------------------------------------------------------------------------------- 1 | # Variables for Config Recorder 2 | variable "name" {} 3 | 4 | variable "role_arn" {} 5 | variable "all_supported" {} 6 | variable "include_global_resource_types" {} 7 | -------------------------------------------------------------------------------- /deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wellcometrust/terraform-modules/e1db61b5f44cfd662576f58e37a019cbf8cd34e6/deploy_key.enc -------------------------------------------------------------------------------- /ec2/modules/asg/asg.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudformation_stack" "ecs_asg" { 2 | name = "${var.asg_name}" 3 | template_body = "${data.template_file.cluster_ecs_asg.rendered}" 4 | 5 | lifecycle { 6 | create_before_destroy = true 7 | } 8 | } 9 | 10 | data "template_file" "cluster_ecs_asg" { 11 | template = "${file("${path.module}/asg.json.template")}" 12 | 13 | vars { 14 | launch_config_name = "${var.launch_config_name}" 15 | vpc_zone_identifier = "${jsonencode(var.subnet_list)}" 16 | asg_min_size = "${var.asg_min}" 17 | asg_desired_size = "${var.asg_desired}" 18 | asg_max_size = "${var.asg_max}" 19 | asg_name = "${var.asg_name}" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ec2/modules/asg/iam.tf: -------------------------------------------------------------------------------- 1 | data "aws_iam_policy_document" "assume_autoscaling_role" { 2 | statement { 3 | actions = [ 4 | "sts:AssumeRole", 5 | ] 6 | 7 | principals { 8 | type = "Service" 9 | identifiers = ["autoscaling.amazonaws.com"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ec2/modules/asg/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${aws_cloudformation_stack.ecs_asg.outputs["AsgName"]}" 3 | } 4 | 5 | output "asg_desired" { 6 | value = "${var.asg_desired}" 7 | } 8 | 9 | output "asg_max" { 10 | value = "${var.asg_max}" 11 | } 12 | -------------------------------------------------------------------------------- /ec2/modules/asg/variables.tf: -------------------------------------------------------------------------------- 1 | variable "asg_name" { 2 | description = "Name of the ASG to create" 3 | } 4 | 5 | variable "asg_min" { 6 | description = "Minimum number of instances" 7 | } 8 | 9 | variable "asg_desired" { 10 | description = "Desired number of instances" 11 | } 12 | 13 | variable "asg_max" { 14 | description = "Max number of instances" 15 | } 16 | 17 | variable "subnet_list" { 18 | type = "list" 19 | } 20 | 21 | variable "launch_config_name" {} 22 | -------------------------------------------------------------------------------- /ec2/modules/instance_profile/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_instance_profile" "instance_profile" { 2 | name = "${var.name}_instance_profile" 3 | role = "${aws_iam_role.role.name}" 4 | } 5 | 6 | data "aws_iam_policy_document" "instance_policy" { 7 | statement { 8 | sid = "allowLoggingToCloudWatch" 9 | 10 | actions = [ 11 | "logs:CreateLogStream", 12 | "logs:PutLogEvents", 13 | ] 14 | 15 | resources = [ 16 | "*", 17 | ] 18 | } 19 | } 20 | 21 | resource "aws_iam_role_policy" "instance" { 22 | name = "${var.name}_instance_role_policy" 23 | 24 | role = "${aws_iam_role.role.name}" 25 | policy = "${data.aws_iam_policy_document.instance_policy.json}" 26 | } 27 | 28 | data "aws_iam_policy_document" "assume_ec2_role" { 29 | statement { 30 | actions = [ 31 | "sts:AssumeRole", 32 | ] 33 | 34 | principals { 35 | type = "Service" 36 | identifiers = ["ec2.amazonaws.com"] 37 | } 38 | } 39 | } 40 | 41 | resource "aws_iam_role" "role" { 42 | name = "${var.name}_instance_role" 43 | assume_role_policy = "${data.aws_iam_policy_document.assume_ec2_role.json}" 44 | } 45 | -------------------------------------------------------------------------------- /ec2/modules/instance_profile/outputs.tf: -------------------------------------------------------------------------------- 1 | output "role_name" { 2 | value = "${aws_iam_role.role.name}" 3 | } 4 | 5 | output "name" { 6 | value = "${aws_iam_instance_profile.instance_profile.name}" 7 | } 8 | -------------------------------------------------------------------------------- /ec2/modules/instance_profile/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "Name of the instance profile" 3 | } 4 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ebs/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_launch_configuration" "launch_config" { 2 | security_groups = ["${var.instance_security_groups}"] 3 | 4 | key_name = "${var.key_name}" 5 | image_id = "${var.image_id}" 6 | instance_type = "${var.instance_type}" 7 | iam_instance_profile = "${var.instance_profile_name}" 8 | user_data = "${var.user_data}" 9 | associate_public_ip_address = "${var.associate_public_ip_address}" 10 | 11 | ebs_block_device { 12 | volume_size = "${var.ebs_size}" 13 | device_name = "${var.ebs_device_name}" 14 | volume_type = "${var.ebs_volume_type}" 15 | } 16 | 17 | lifecycle { 18 | create_before_destroy = true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ebs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_launch_configuration.launch_config.name}" 3 | } 4 | 5 | output "ebs_volume_id" { 6 | value = "${var.ebs_device_name}" 7 | } 8 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ebs/variables.tf: -------------------------------------------------------------------------------- 1 | variable "key_name" { 2 | description = "SSH key pair name for instance sign-in" 3 | } 4 | 5 | variable "image_id" { 6 | description = "ID of the AMI to use on the instances" 7 | } 8 | 9 | variable "instance_type" { 10 | description = "AWS instance type" 11 | } 12 | 13 | variable "instance_profile_name" { 14 | description = "Instance profile for ec2 container hosts" 15 | } 16 | 17 | variable "user_data" { 18 | description = "User data for ec2 container hosts" 19 | default = "" 20 | } 21 | 22 | variable "associate_public_ip_address" { 23 | description = "Associate public IP address?" 24 | } 25 | 26 | variable "instance_security_groups" { 27 | type = "list" 28 | default = [] 29 | } 30 | 31 | variable "ebs_size" {} 32 | 33 | variable "ebs_device_name" { 34 | default = "/dev/xvdb" 35 | } 36 | 37 | variable "ebs_volume_type" { 38 | default = "standard" 39 | } 40 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ondemand/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_launch_configuration" "launch_config" { 2 | security_groups = ["${var.instance_security_groups}"] 3 | 4 | key_name = "${var.key_name}" 5 | image_id = "${var.image_id}" 6 | instance_type = "${var.instance_type}" 7 | iam_instance_profile = "${var.instance_profile_name}" 8 | user_data = "${var.user_data}" 9 | associate_public_ip_address = "${var.associate_public_ip_address}" 10 | 11 | lifecycle { 12 | create_before_destroy = true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ondemand/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_launch_configuration.launch_config.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/ondemand/variables.tf: -------------------------------------------------------------------------------- 1 | variable "key_name" { 2 | description = "SSH key pair name for instance sign-in" 3 | } 4 | 5 | variable "image_id" { 6 | description = "ID of the AMI to use on the instances" 7 | } 8 | 9 | variable "instance_type" { 10 | description = "AWS instance type" 11 | } 12 | 13 | variable "instance_profile_name" { 14 | description = "Instance profile for ec2 container hosts" 15 | } 16 | 17 | variable "user_data" { 18 | description = "User data for ec2 container hosts" 19 | default = "" 20 | } 21 | 22 | variable "associate_public_ip_address" { 23 | description = "Associate public IP address?" 24 | } 25 | 26 | variable "instance_security_groups" { 27 | type = "list" 28 | default = [] 29 | } 30 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/spot/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_launch_configuration" "launch_config" { 2 | security_groups = ["${var.instance_security_groups}"] 3 | 4 | key_name = "${var.key_name}" 5 | image_id = "${var.image_id}" 6 | instance_type = "${var.instance_type}" 7 | iam_instance_profile = "${var.instance_profile_name}" 8 | user_data = "${var.user_data}" 9 | associate_public_ip_address = "${var.associate_public_ip_address}" 10 | 11 | spot_price = "${var.spot_price}" 12 | 13 | lifecycle { 14 | create_before_destroy = true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/spot/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_launch_configuration.launch_config.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ec2/modules/launch_config/spot/variables.tf: -------------------------------------------------------------------------------- 1 | variable "key_name" { 2 | description = "SSH key pair name for instance sign-in" 3 | } 4 | 5 | variable "image_id" { 6 | description = "ID of the AMI to use on the instances" 7 | } 8 | 9 | variable "instance_type" { 10 | description = "AWS instance type" 11 | } 12 | 13 | variable "instance_profile_name" { 14 | description = "Instance profile for ec2 container hosts" 15 | } 16 | 17 | variable "user_data" { 18 | description = "User data for ec2 container hosts" 19 | default = "" 20 | } 21 | 22 | variable "associate_public_ip_address" { 23 | description = "Associate public IP address?" 24 | } 25 | 26 | variable "instance_security_groups" { 27 | type = "list" 28 | default = [] 29 | } 30 | 31 | variable "spot_price" {} 32 | -------------------------------------------------------------------------------- /ec2/modules/security_groups/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_security_groups" { 2 | value = ["${local.instance_security_groups}"] 3 | } 4 | 5 | output "ssh_controlled_ingress" { 6 | value = ["${aws_security_group.ssh_controlled_ingress.*.id}"] 7 | } 8 | -------------------------------------------------------------------------------- /ec2/modules/security_groups/variables.tf: -------------------------------------------------------------------------------- 1 | variable "custom_security_groups" { 2 | type = "list" 3 | default = [] 4 | } 5 | 6 | variable "vpc_id" {} 7 | variable "name" {} 8 | 9 | variable "controlled_access_cidr_ingress" { 10 | type = "list" 11 | default = [] 12 | } 13 | 14 | variable "controlled_access_security_groups" { 15 | type = "list" 16 | default = [] 17 | } 18 | -------------------------------------------------------------------------------- /ec2/prebuilt/bastion/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${module.cloudformation_stack.asg_name}" 3 | } 4 | 5 | output "instance_profile_name" { 6 | value = "${module.instance_profile.name}" 7 | } 8 | 9 | output "instance_profile_role_name" { 10 | value = "${module.instance_profile.role_name}" 11 | } 12 | 13 | output "ssh_controlled_ingress_sg" { 14 | value = "${module.security_groups.ssh_controlled_ingress}" 15 | } 16 | -------------------------------------------------------------------------------- /ec2/prebuilt/dlami/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${module.cloudformation_stack.asg_name}" 3 | } 4 | 5 | output "instance_profile_name" { 6 | value = "${module.instance_profile.name}" 7 | } 8 | 9 | output "instance_profile_role_name" { 10 | value = "${module.instance_profile.role_name}" 11 | } 12 | 13 | output "ssh_controlled_ingress_sg" { 14 | value = "${module.security_groups.ssh_controlled_ingress}" 15 | } 16 | -------------------------------------------------------------------------------- /ec2/prebuilt/dlami/templates/jupyter_notebook_config.py.tpl: -------------------------------------------------------------------------------- 1 | from s3contents import S3ContentsManager 2 | 3 | c = get_config() 4 | 5 | # Tell Jupyter to use S3ContentsManager for all storage. 6 | c.NotebookApp.contents_manager_class = S3ContentsManager 7 | c.S3ContentsManager.bucket = "${bucket_name}" 8 | 9 | c.NotebookApp.notebook_dir = u"/home/${notebook_user}/" 10 | c.NotebookApp.ip = "*" 11 | c.NotebookApp.port = ${notebook_port} 12 | c.NotebookApp.open_browser = False 13 | c.NotebookApp.password = u'${hashed_password}' -------------------------------------------------------------------------------- /ec2/prebuilt/dlami/templates/requirements.in: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.6.0 2 | networkx==2.1 3 | pillow==5.1.0 4 | scikit-learn==0.19.1 5 | seaborn==0.8.1 6 | tqdm==4.19.7 -------------------------------------------------------------------------------- /ec2/prebuilt/dlami/templates/requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements.txt requirements.in 6 | # 7 | beautifulsoup4==4.6.0 8 | cycler==0.10.0 # via matplotlib 9 | decorator==4.3.0 # via networkx 10 | kiwisolver==1.0.1 # via matplotlib 11 | matplotlib==2.2.2 # via seaborn 12 | networkx==2.1 13 | numpy==1.14.5 # via matplotlib, pandas, scipy, seaborn 14 | pandas==0.23.1 # via seaborn 15 | pillow==5.1.0 16 | pyparsing==2.2.0 # via matplotlib 17 | python-dateutil==2.7.3 # via matplotlib, pandas 18 | pytz==2018.4 # via matplotlib, pandas 19 | scikit-learn==0.19.1 20 | scipy==1.1.0 # via seaborn 21 | seaborn==0.8.1 22 | six==1.11.0 # via cycler, matplotlib, python-dateutil 23 | tqdm==4.19.7 -------------------------------------------------------------------------------- /ec2/prebuilt/ebs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${module.cloudformation_stack.asg_name}" 3 | } 4 | 5 | output "instance_profile_name" { 6 | value = "${module.instance_profile.name}" 7 | } 8 | 9 | output "instance_profile_role_name" { 10 | value = "${module.instance_profile.role_name}" 11 | } 12 | 13 | output "ssh_controlled_ingress_sg" { 14 | value = "${module.security_groups.ssh_controlled_ingress}" 15 | } 16 | 17 | output "ebs_volume_id" { 18 | value = "${module.launch_config.ebs_volume_id}" 19 | } 20 | -------------------------------------------------------------------------------- /ec2/prebuilt/ondemand/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${module.cloudformation_stack.asg_name}" 3 | } 4 | 5 | output "instance_profile_name" { 6 | value = "${module.instance_profile.name}" 7 | } 8 | 9 | output "instance_profile_role_name" { 10 | value = "${module.instance_profile.role_name}" 11 | } 12 | 13 | output "ssh_controlled_ingress_sg" { 14 | value = "${module.security_groups.ssh_controlled_ingress}" 15 | } 16 | -------------------------------------------------------------------------------- /ec2/prebuilt/spot/outputs.tf: -------------------------------------------------------------------------------- 1 | output "asg_name" { 2 | value = "${module.cloudformation_stack.asg_name}" 3 | } 4 | 5 | output "instance_profile_name" { 6 | value = "${module.instance_profile.name}" 7 | } 8 | 9 | output "instance_profile_role_name" { 10 | value = "${module.instance_profile.role_name}" 11 | } 12 | 13 | output "ssh_controlled_ingress_sg" { 14 | value = "${module.security_groups.ssh_controlled_ingress}" 15 | } 16 | -------------------------------------------------------------------------------- /ecr/outputs.tf: -------------------------------------------------------------------------------- 1 | output "repository_url" { 2 | value = "${aws_ecr_repository.repository.repository_url}" 3 | } 4 | 5 | output "name" { 6 | value = "${aws_ecr_repository.repository.name}" 7 | } 8 | -------------------------------------------------------------------------------- /ecr/repository.tf: -------------------------------------------------------------------------------- 1 | resource "aws_ecr_repository" "repository" { 2 | name = "${var.namespace}/${var.id}" 3 | } 4 | -------------------------------------------------------------------------------- /ecr/variables.tf: -------------------------------------------------------------------------------- 1 | variable "id" { 2 | description = "ID of the ECR repository" 3 | } 4 | 5 | variable "namespace" { 6 | description = "Namespace prefix to ECR repository" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/example/modules/bastion_hosts.tf: -------------------------------------------------------------------------------- 1 | # EC2 Bastion hosts 2 | 3 | module "ec2_bastion" { 4 | source = "../../../ec2/prebuilt/bastion" 5 | 6 | vpc_id = "${module.network.vpc_id}" 7 | 8 | name = "ecsV2-bastion-host" 9 | 10 | controlled_access_cidr_ingress = ["195.143.129.128/25"] 11 | 12 | key_name = "wellcomedigitalplatform" 13 | subnet_list = "${module.network.public_subnets}" 14 | } 15 | -------------------------------------------------------------------------------- /ecs/example/modules/images.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | project_id = "my_project" 3 | release_label = "latest" 4 | } 5 | 6 | module "images" { 7 | source = "../../modules/images" 8 | 9 | project = "${local.project_id}" 10 | label = "${local.release_label}" 11 | 12 | services = [ 13 | "service_one", 14 | "service_two", 15 | ] 16 | } 17 | 18 | resource "aws_ssm_parameter" "service_one_image" { 19 | name = "/my_project/images/latest/service_one" 20 | type = "String" 21 | value = "strm/helloworld-http" 22 | } 23 | 24 | resource "aws_ssm_parameter" "service_two_image" { 25 | name = "/my_project/images/latest/service_two" 26 | type = "String" 27 | value = "strm/helloworld-http" 28 | } 29 | 30 | locals { 31 | service_one = "${module.images.services["service_one"]}" 32 | service_two = "${module.images.services["service_two"]}" 33 | } 34 | 35 | // module.images.services: 36 | //{ 37 | // "/my_project/images/latest/service_one": "123412341234.dkr.ecr.eu-west-1.amazonaws.com/foo:abc", 38 | // "/my_project/images/latest/service_two": "123412341234.dkr.ecr.eu-west-1.amazonaws.com/bar:abc" 39 | //} 40 | 41 | -------------------------------------------------------------------------------- /ecs/example/modules/network.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | vpc_cidr_block = "10.120.0.0/16" 3 | namespace = "ecs-example" 4 | aws_region = "eu-west-1" 5 | 6 | cidr_block_public = "10.120.1.0/23" 7 | cidr_block_private = "10.120.2.0/23" 8 | } 9 | 10 | resource "aws_ecs_cluster" "cluster" { 11 | name = "ecsV2" 12 | } 13 | 14 | module "network" { 15 | source = "../../../network/prebuilt/vpc/public-private-igw" 16 | name = "${local.namespace}" 17 | 18 | cidr_block_vpc = "172.17.0.0/24" 19 | 20 | cidr_block_public = "172.17.0.0/25" 21 | cidrsubnet_newbits_public = "3" 22 | 23 | cidr_block_private = "172.17.0.128/25" 24 | cidrsubnet_newbits_private = "3" 25 | 26 | public_az_count = "3" 27 | private_az_count = "3" 28 | } 29 | 30 | resource "aws_service_discovery_private_dns_namespace" "namespace" { 31 | name = "${local.namespace}" 32 | vpc = "${module.network.vpc_id}" 33 | } 34 | -------------------------------------------------------------------------------- /ecs/example/modules/provider.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${local.aws_region}" 4 | 5 | version = "1.42.0" 6 | } 7 | 8 | data "aws_caller_identity" "current" {} 9 | -------------------------------------------------------------------------------- /ecs/example/modules/task_definitions.tf: -------------------------------------------------------------------------------- 1 | module "task" { 2 | source = "../../modules/task/prebuilt/single_container" 3 | 4 | aws_region = "${local.aws_region}" 5 | task_name = "${local.namespace}" 6 | 7 | container_image = "strm/helloworld-http" 8 | container_port = "80" 9 | } 10 | 11 | module "task_with_sidecar" { 12 | source = "../../modules/task/prebuilt/container_with_sidecar" 13 | 14 | aws_region = "${local.aws_region}" 15 | task_name = "${local.namespace}_with_sidecar" 16 | 17 | memory = "2048" 18 | cpu = "1024" 19 | 20 | app_container_image = "${module.images.services["service_one"]}" 21 | app_container_port = "80" 22 | 23 | app_cpu = "512" 24 | app_memory = "1024" 25 | 26 | sidecar_container_image = "memcached" 27 | sidecar_container_port = "11211" 28 | 29 | sidecar_cpu = "512" 30 | sidecar_memory = "1024" 31 | } 32 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/RELEASE.md: -------------------------------------------------------------------------------- 1 | RELEASE_TYPE: major 2 | 3 | Deprecate sqs scaling module in favour of generic scaling 4 | Normalise prebuilt ecs service w/task 5 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/fake_metric_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while sleep 10; 4 | do 5 | aws cloudwatch put-metric-data --namespace MyCustomMetric --metric-data MetricName=SomeValue,Value=2 6 | done 7 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/main.tf: -------------------------------------------------------------------------------- 1 | module "example_scaling_service" { 2 | source = "../../prebuilt/scaling" 3 | 4 | service_name = "example_scaling_service" 5 | container_image = "strm/helloworld-http" 6 | 7 | namespace_id = "${local.namespace_id}" 8 | cluster_name = "${local.cluster_name}" 9 | 10 | subnets = "${local.private_subnets}" 11 | 12 | container_port = "80" 13 | 14 | env_vars = {} 15 | env_vars_length = 0 16 | 17 | security_group_ids = [ 18 | "${aws_security_group.interservice_security_group.id}", 19 | "${aws_security_group.service_egress_security_group.id}", 20 | ] 21 | 22 | metric_namespace = "MyCustomMetric" 23 | 24 | high_metric_name = "SomeValue" 25 | low_metric_name = "SomeOtherValue" 26 | 27 | secret_env_vars = {} 28 | secret_env_vars_length = 0 29 | 30 | cluster_id = "${aws_ecs_cluster.cluster.id}" 31 | } 32 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/network.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | vpc_cidr_block = "172.16.0.0/23" 3 | namespace = "ecs-example" 4 | aws_region = "eu-west-1" 5 | 6 | namespace_id = "${aws_service_discovery_private_dns_namespace.namespace.id}" 7 | cluster_id = "${aws_ecs_cluster.cluster.id}" 8 | cluster_name = "${aws_ecs_cluster.cluster.name}" 9 | vpc_id = "${module.network.vpc_id}" 10 | 11 | private_subnets = "${module.network.private_subnets}" 12 | } 13 | 14 | resource "aws_ecs_cluster" "cluster" { 15 | name = "${local.namespace}" 16 | } 17 | 18 | module "network" { 19 | source = "../../../network/prebuilt/vpc/public-private-igw" 20 | 21 | name = "${local.namespace}" 22 | 23 | cidr_block_vpc = "172.17.0.0/24" 24 | 25 | cidr_block_public = "172.17.0.0/25" 26 | cidrsubnet_newbits_public = "3" 27 | 28 | cidr_block_private = "172.17.0.128/25" 29 | cidrsubnet_newbits_private = "3" 30 | 31 | public_az_count = "3" 32 | private_az_count = "3" 33 | } 34 | 35 | resource "aws_service_discovery_private_dns_namespace" "namespace" { 36 | name = "${local.namespace}" 37 | vpc = "${module.network.vpc_id}" 38 | } 39 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/provider.tf: -------------------------------------------------------------------------------- 1 | # Specify the provider and access details 2 | provider "aws" { 3 | region = "${local.aws_region}" 4 | 5 | version = "1.42.0" 6 | } 7 | 8 | data "aws_caller_identity" "current" {} 9 | -------------------------------------------------------------------------------- /ecs/example/prebuilt/security_groups.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "service_egress_security_group" { 2 | name = "${local.namespace}-service_egress_security_group" 3 | description = "Allow traffic between services" 4 | vpc_id = "${module.network.vpc_id}" 5 | 6 | egress { 7 | from_port = 0 8 | to_port = 0 9 | protocol = "-1" 10 | cidr_blocks = ["0.0.0.0/0"] 11 | } 12 | 13 | tags { 14 | Name = "${local.namespace}-egress" 15 | } 16 | } 17 | 18 | resource "aws_security_group" "interservice_security_group" { 19 | name = "${local.namespace}-interservice_security_group" 20 | description = "Allow traffic between services" 21 | vpc_id = "${module.network.vpc_id}" 22 | 23 | ingress { 24 | from_port = 0 25 | to_port = 0 26 | protocol = "-1" 27 | self = true 28 | } 29 | 30 | tags { 31 | Name = "${local.namespace}-interservice" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ecs/modules/ec2/README.md: -------------------------------------------------------------------------------- 1 | Modules for running ECS cluster hosts on EC2. 2 | -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/instance_role_policy/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_iam_policy_document" "instance_policy" { 2 | statement { 3 | actions = [ 4 | "ecr:BatchGetImage", 5 | "ecr:GetAuthorizationToken", 6 | "ecr:GetDownloadUrlForLayer", 7 | "ecs:DeregisterContainerInstance", 8 | "ecs:DiscoverPollEndpoint", 9 | "ecs:Poll", 10 | "ecs:RegisterContainerInstance", 11 | "ecs:StartTelemetrySession", 12 | "ecs:Submit*", 13 | ] 14 | 15 | resources = [ 16 | "*", 17 | ] 18 | } 19 | } 20 | 21 | resource "aws_iam_role_policy" "instance" { 22 | name = "${var.cluster_name}_instance_role_policy_ecs" 23 | 24 | role = "${var.instance_profile_role_name}" 25 | policy = "${data.aws_iam_policy_document.instance_policy.json}" 26 | } 27 | -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/instance_role_policy/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" {} 2 | variable "instance_profile_role_name" {} 3 | -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/default.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/x-shellscript; charset="us-ascii" 6 | 7 | #!/bin/bash 8 | # Set any ECS agent configuration options 9 | cat << EOF > /etc/ecs/ecs.config 10 | 11 | ECS_CLUSTER=${cluster_name} 12 | 13 | EOF 14 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/ebs+efs.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/cloud-boothook; charset="us-ascii" 6 | 7 | # Install nfs-utils 8 | cloud-init-per once yum_update yum update -y 9 | cloud-init-per once install_efs_utils yum install -y amazon-efs-utils 10 | 11 | # Create /efs folder 12 | cloud-init-per once mkdir_efs mkdir /efs 13 | 14 | # Mount /efs 15 | cloud-init-per once mount_efs echo -e '${efs_fs_id}:/ ${efs_host_path} efs defaults,_netdev 0 0' >> /etc/fstab 16 | 17 | # Create /ebs folder 18 | cloud-init-per once mkdir_ebs mkdir /ebs 19 | 20 | # Format ebs volume 21 | cloud-init-per once format_ebs mkfs -t ext4 ${ebs_volume_id} 22 | 23 | # Add /ebs to fstab 24 | cloud-init-per once mount_ebs echo -e '${ebs_volume_id} ${ebs_host_path} ext4 defaults,nofail 0 2' >> /etc/fstab 25 | 26 | # Mount all 27 | mount -a 28 | 29 | --==BOUNDARY== 30 | Content-Type: text/x-shellscript; charset="us-ascii" 31 | 32 | cat << EOF > /etc/ecs/ecs.config 33 | 34 | ECS_CLUSTER=${cluster_name} 35 | ECS_INSTANCE_ATTRIBUTES={"ebs.volume":"${ebs_volume_id}", "efs.volume":"${efs_fs_id}"} 36 | 37 | EOF 38 | 39 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/ebs.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/cloud-boothook; charset="us-ascii" 6 | 7 | # Create /ebs folder 8 | cloud-init-per once mkdir_ebs mkdir -p ${ebs_host_path} 9 | 10 | # Format ebs volume 11 | cloud-init-per once format_ebs mkfs -t ext4 ${ebs_volume_id} 12 | 13 | # Add /ebs to fstab 14 | cloud-init-per once mount_ebs echo -e '${ebs_volume_id} ${ebs_host_path} ext4 defaults,nofail 0 2' >> /etc/fstab 15 | 16 | # Mount all 17 | mount -a 18 | 19 | --==BOUNDARY== 20 | Content-Type: text/x-shellscript; charset="us-ascii" 21 | 22 | #!/bin/bash 23 | # Set any ECS agent configuration options 24 | cat << EOF > /etc/ecs/ecs.config 25 | 26 | ECS_CLUSTER=${cluster_name} 27 | ECS_INSTANCE_ATTRIBUTES={"ebs.volume":"${ebs_volume_id}"} 28 | 29 | EOF 30 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/efs.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/cloud-boothook; charset="us-ascii" 6 | 7 | # Install nfs-utils 8 | cloud-init-per once yum_update yum update -y 9 | cloud-init-per once install_efs_utils yum install -y amazon-efs-utils 10 | 11 | # Create /efs folder 12 | cloud-init-per once mkdir_efs mkdir -p ${efs_host_path} 13 | 14 | # Add /efs to fstab 15 | cloud-init-per once mount_efs echo -e '${efs_fs_id}:/ ${efs_host_path} efs defaults,_netdev 0 0' >> /etc/fstab 16 | 17 | # Mount all 18 | mount -a 19 | 20 | --==BOUNDARY== 21 | Content-Type: text/x-shellscript; charset="us-ascii" 22 | 23 | #!/bin/bash 24 | # Set any ECS agent configuration options 25 | cat << EOF > /etc/ecs/ecs.config 26 | 27 | ECS_CLUSTER=${cluster_name} 28 | ECS_INSTANCE_ATTRIBUTES={"efs.volume":"${efs_fs_id}"} 29 | 30 | EOF 31 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/nvm.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/cloud-boothook; charset="us-ascii" 6 | 7 | # Create /nvm folder 8 | cloud-init-per once mkdir_nvm mkdir -p ${nvm_host_path} 9 | 10 | # Format nvm volume 11 | cloud-init-per once format_nvm mkfs -t ext4 ${nvm_volume_id} 12 | 13 | # Add /nvm to fstab 14 | cloud-init-per once mount_nvm echo -e '${nvm_volume_id} ${nvm_host_path} ext4 defaults,nofail 0 2' >> /etc/fstab 15 | 16 | # Mount all 17 | mount -a 18 | 19 | --==BOUNDARY== 20 | Content-Type: text/x-shellscript; charset="us-ascii" 21 | 22 | #!/bin/bash 23 | # Set any ECS agent configuration options 24 | cat << EOF > /etc/ecs/ecs.config 25 | 26 | ECS_CLUSTER=${cluster_name} 27 | ECS_INSTANCE_ATTRIBUTES={"nvm.volume":"${nvm_volume_id}"} 28 | 29 | EOF 30 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/modules/userdata/spot.tpl: -------------------------------------------------------------------------------- 1 | Content-Type: multipart/mixed; boundary="==BOUNDARY==" 2 | MIME-Version: 1.0 3 | 4 | --==BOUNDARY== 5 | Content-Type: text/x-shellscript; charset="us-ascii" 6 | 7 | #!/bin/bash 8 | # Set any ECS agent configuration options 9 | cat << EOF > /etc/ecs/ecs.config 10 | 11 | ECS_CLUSTER=${cluster_name} 12 | ECS_INSTANCE_ATTRIBUTES={"ecs.spot":true} 13 | 14 | EOF 15 | --==BOUNDARY==-- -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/ebs+efs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | 5 | output "ebs_host_path" { 6 | value = "${var.ebs_host_path}" 7 | } 8 | 9 | output "efs_host_path" { 10 | value = "${var.efs_host_path}" 11 | } 12 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/ebs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | 5 | output "ebs_host_path" { 6 | value = "${var.ebs_host_path}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/efs/main.tf: -------------------------------------------------------------------------------- 1 | module "asg" { 2 | source = "../../../../../ec2/prebuilt/ondemand" 3 | 4 | name = "${var.asg_name}" 5 | 6 | image_id = "${var.image_id}" 7 | 8 | controlled_access_cidr_ingress = ["${var.controlled_access_cidr_ingress}"] 9 | 10 | custom_security_groups = ["${var.custom_security_groups}"] 11 | ssh_ingress_security_groups = ["${var.ssh_ingress_security_groups}"] 12 | 13 | subnet_list = ["${var.subnets}"] 14 | vpc_id = "${var.vpc_id}" 15 | key_name = "${var.key_name}" 16 | user_data = "${data.template_file.userdata.rendered}" 17 | 18 | asg_max = "${var.asg_max}" 19 | asg_desired = "${var.asg_desired}" 20 | asg_min = "${var.asg_min}" 21 | 22 | instance_type = "${var.instance_type}" 23 | } 24 | 25 | data "template_file" "userdata" { 26 | template = "${file("${path.module}/../../modules/userdata/efs.tpl")}" 27 | 28 | vars { 29 | cluster_name = "${var.cluster_name}" 30 | efs_fs_id = "${var.efs_fs_id}" 31 | efs_host_path = "${var.efs_host_path}" 32 | region = "${var.region}" 33 | } 34 | } 35 | 36 | module "instance_policy" { 37 | source = "../../modules/instance_role_policy" 38 | 39 | cluster_name = "${var.cluster_name}" 40 | instance_profile_role_name = "${module.asg.instance_profile_role_name}" 41 | } 42 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/efs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | 5 | output "efs_host_path" { 6 | value = "${var.efs_host_path}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/nvm/main.tf: -------------------------------------------------------------------------------- 1 | module "asg" { 2 | source = "../../../../../ec2/prebuilt/ondemand" 3 | 4 | name = "${var.asg_name}" 5 | 6 | image_id = "${var.image_id}" 7 | 8 | controlled_access_cidr_ingress = ["${var.controlled_access_cidr_ingress}"] 9 | 10 | custom_security_groups = ["${var.custom_security_groups}"] 11 | ssh_ingress_security_groups = ["${var.ssh_ingress_security_groups}"] 12 | 13 | subnet_list = ["${var.subnets}"] 14 | vpc_id = "${var.vpc_id}" 15 | key_name = "${var.key_name}" 16 | user_data = "${data.template_file.userdata.rendered}" 17 | 18 | asg_max = "${var.asg_max}" 19 | asg_desired = "${var.asg_desired}" 20 | asg_min = "${var.asg_min}" 21 | 22 | instance_type = "${var.instance_type}" 23 | } 24 | 25 | data "template_file" "userdata" { 26 | template = "${file("${path.module}/../../modules/userdata/nvm.tpl")}" 27 | 28 | vars { 29 | cluster_name = "${var.cluster_name}" 30 | nvm_host_path = "${var.nvm_host_path}" 31 | nvm_volume_id = "${var.nvm_volume_id}" 32 | } 33 | } 34 | 35 | module "instance_policy" { 36 | source = "../../modules/instance_role_policy" 37 | 38 | cluster_name = "${var.cluster_name}" 39 | instance_profile_role_name = "${module.asg.instance_profile_role_name}" 40 | } 41 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/nvm/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | 5 | output "nvm_host_path" { 6 | value = "${var.nvm_host_path}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/nvm/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" {} 2 | 3 | variable "asg_name" { 4 | description = "Name of the ASG" 5 | } 6 | 7 | variable "asg_min" { 8 | description = "Minimum number of instances" 9 | default = "1" 10 | } 11 | 12 | variable "asg_desired" { 13 | description = "Desired number of instances" 14 | default = "1" 15 | } 16 | 17 | variable "asg_max" { 18 | description = "Max number of instances" 19 | default = "2" 20 | } 21 | 22 | variable "subnets" { 23 | type = "list" 24 | } 25 | 26 | variable "vpc_id" {} 27 | 28 | variable "image_id" { 29 | default = "ami-0627e141ce928067c" 30 | } 31 | 32 | variable "instance_type" { 33 | default = "i3.2xlarge" 34 | } 35 | 36 | variable "key_name" { 37 | description = "SSH key name for SSH access. Leave blank if not using SSH." 38 | default = "" 39 | } 40 | 41 | variable "controlled_access_cidr_ingress" { 42 | type = "list" 43 | default = [] 44 | description = "CIDR for SSH access to EC2 instances" 45 | } 46 | 47 | variable "custom_security_groups" { 48 | type = "list" 49 | default = [] 50 | } 51 | 52 | variable "ssh_ingress_security_groups" { 53 | type = "list" 54 | default = [] 55 | } 56 | 57 | variable "nvm_host_path" { 58 | default = "/nvm" 59 | } 60 | 61 | variable "nvm_volume_id" { 62 | default = "/dev/nvme0n1" 63 | } 64 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/ondemand/main.tf: -------------------------------------------------------------------------------- 1 | module "asg" { 2 | source = "../../../../../ec2/prebuilt/ondemand" 3 | 4 | name = "${var.asg_name}" 5 | 6 | image_id = "${var.image_id}" 7 | 8 | controlled_access_cidr_ingress = ["${var.controlled_access_cidr_ingress}"] 9 | 10 | custom_security_groups = ["${var.custom_security_groups}"] 11 | ssh_ingress_security_groups = ["${var.ssh_ingress_security_groups}"] 12 | 13 | subnet_list = ["${var.subnets}"] 14 | vpc_id = "${var.vpc_id}" 15 | key_name = "${var.key_name}" 16 | user_data = "${data.template_file.userdata.rendered}" 17 | 18 | asg_max = "${var.asg_max}" 19 | asg_desired = "${var.asg_desired}" 20 | asg_min = "${var.asg_min}" 21 | 22 | instance_type = "${var.instance_type}" 23 | } 24 | 25 | data "template_file" "userdata" { 26 | template = "${file("${path.module}/../../modules/userdata/default.tpl")}" 27 | 28 | vars { 29 | cluster_name = "${var.cluster_name}" 30 | } 31 | } 32 | 33 | module "instance_policy" { 34 | source = "../../modules/instance_role_policy" 35 | 36 | cluster_name = "${var.cluster_name}" 37 | instance_profile_role_name = "${module.asg.instance_profile_role_name}" 38 | } 39 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/ondemand/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/ondemand/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" {} 2 | 3 | variable "asg_name" { 4 | description = "Name of the ASG" 5 | } 6 | 7 | variable "asg_min" { 8 | description = "Minimum number of instances" 9 | default = "1" 10 | } 11 | 12 | variable "asg_desired" { 13 | description = "Desired number of instances" 14 | default = "1" 15 | } 16 | 17 | variable "asg_max" { 18 | description = "Max number of instances" 19 | default = "2" 20 | } 21 | 22 | variable "instance_type" { 23 | default = "t2.small" 24 | description = "AWS instance type" 25 | } 26 | 27 | variable "subnets" { 28 | type = "list" 29 | } 30 | 31 | variable "vpc_id" {} 32 | 33 | variable "image_id" { 34 | default = "ami-c91624b0" 35 | } 36 | 37 | variable "key_name" { 38 | description = "SSH key name for SSH access. Leave blank if not using SSH." 39 | default = "" 40 | } 41 | 42 | variable "controlled_access_cidr_ingress" { 43 | type = "list" 44 | default = [] 45 | description = "CIDR for SSH access to EC2 instances" 46 | } 47 | 48 | variable "custom_security_groups" { 49 | type = "list" 50 | default = [] 51 | } 52 | 53 | variable "ssh_ingress_security_groups" { 54 | type = "list" 55 | default = [] 56 | } 57 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/spot/main.tf: -------------------------------------------------------------------------------- 1 | module "asg" { 2 | source = "../../../../../ec2/prebuilt/spot" 3 | 4 | name = "${var.asg_name}" 5 | 6 | image_id = "${var.image_id}" 7 | 8 | controlled_access_cidr_ingress = ["${var.controlled_access_cidr_ingress}"] 9 | 10 | custom_security_groups = ["${var.custom_security_groups}"] 11 | ssh_ingress_security_groups = ["${var.ssh_ingress_security_groups}"] 12 | 13 | subnet_list = ["${var.subnets}"] 14 | vpc_id = "${var.vpc_id}" 15 | key_name = "${var.key_name}" 16 | user_data = "${data.template_file.userdata.rendered}" 17 | 18 | asg_max = "${var.asg_max}" 19 | asg_desired = "${var.asg_desired}" 20 | asg_min = "${var.asg_min}" 21 | 22 | instance_type = "${var.instance_type}" 23 | 24 | spot_price = "${var.spot_price}" 25 | } 26 | 27 | data "template_file" "userdata" { 28 | template = "${file("${path.module}/../../modules/userdata/spot.tpl")}" 29 | 30 | vars { 31 | cluster_name = "${var.cluster_name}" 32 | } 33 | } 34 | 35 | module "instance_policy" { 36 | source = "../../modules/instance_role_policy" 37 | 38 | cluster_name = "${var.cluster_name}" 39 | instance_profile_role_name = "${module.asg.instance_profile_role_name}" 40 | } 41 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/spot/outputs.tf: -------------------------------------------------------------------------------- 1 | output "ssh_controlled_ingress_sg" { 2 | value = "${module.asg.ssh_controlled_ingress_sg}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/ec2/prebuilt/spot/variables.tf: -------------------------------------------------------------------------------- 1 | variable "cluster_name" {} 2 | 3 | variable "asg_name" { 4 | description = "Name of the ASG" 5 | } 6 | 7 | variable "asg_min" { 8 | description = "Minimum number of instances" 9 | default = "1" 10 | } 11 | 12 | variable "asg_desired" { 13 | description = "Desired number of instances" 14 | default = "1" 15 | } 16 | 17 | variable "asg_max" { 18 | description = "Max number of instances" 19 | default = "2" 20 | } 21 | 22 | variable "instance_type" { 23 | default = "t2.small" 24 | description = "AWS instance type" 25 | } 26 | 27 | variable "subnets" { 28 | type = "list" 29 | } 30 | 31 | variable "vpc_id" {} 32 | 33 | variable "image_id" { 34 | default = "ami-c91624b0" 35 | } 36 | 37 | variable "key_name" { 38 | description = "SSH key name for SSH access. Leave blank if not using SSH." 39 | default = "" 40 | } 41 | 42 | variable "controlled_access_cidr_ingress" { 43 | type = "list" 44 | default = [] 45 | description = "CIDR for SSH access to EC2 instances" 46 | } 47 | 48 | variable "custom_security_groups" { 49 | type = "list" 50 | default = [] 51 | } 52 | 53 | variable "ssh_ingress_security_groups" { 54 | type = "list" 55 | default = [] 56 | } 57 | 58 | variable "spot_price" {} 59 | -------------------------------------------------------------------------------- /ecs/modules/images/main.tf: -------------------------------------------------------------------------------- 1 | data "aws_ssm_parameter" "image" { 2 | count = "${length(var.services)}" 3 | 4 | name = "/${var.project}/images/${var.label}/${var.services[count.index]}" 5 | } 6 | 7 | variable "services" { 8 | type = "list" 9 | } 10 | 11 | // This is a map of SSM param paths to some value 12 | // SSM Params are used to hold ECR image URIs 13 | // That can then be fed to ECS config 14 | // See: https://github.com/wellcometrust/platform/tree/master/docs/rfcs/013-release_deployment_tracking 15 | 16 | locals { 17 | images = "${zipmap(var.services, data.aws_ssm_parameter.image.*.value)}" 18 | } 19 | -------------------------------------------------------------------------------- /ecs/modules/images/outputs.tf: -------------------------------------------------------------------------------- 1 | output "services" { 2 | value = "${local.images}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/images/variables.tf: -------------------------------------------------------------------------------- 1 | variable "label" {} 2 | variable "project" {} 3 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/iam/outputs.tf: -------------------------------------------------------------------------------- 1 | output "role_name" { 2 | value = "${aws_iam_role.ecs_service.name}" 3 | } 4 | 5 | output "role_arn" { 6 | value = "${aws_iam_role.ecs_service.arn}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/iam/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/service_discovery/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_service_discovery_service" "service_discovery" { 2 | name = "${var.service_name}" 3 | 4 | health_check_custom_config { 5 | failure_threshold = "${var.service_discovery_failure_threshold}" 6 | } 7 | 8 | dns_config { 9 | namespace_id = "${var.namespace_id}" 10 | 11 | dns_records { 12 | ttl = 5 13 | type = "A" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/service_discovery/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | value = "${aws_service_discovery_service.service_discovery.arn}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/service_discovery/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "namespace_id" {} 3 | 4 | variable "service_discovery_failure_threshold" { 5 | default = 1 6 | } 7 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/http/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | target_group_name = "${replace(var.service_name, "_", "-")}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/http/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_alb_target_group" "http" { 2 | # Must only contain alphanumerics and hyphens. 3 | name = "${local.target_group_name}" 4 | 5 | target_type = "ip" 6 | 7 | protocol = "HTTP" 8 | port = "${var.container_port}" 9 | vpc_id = "${var.vpc_id}" 10 | deregistration_delay = "${var.deregistration_delay}" 11 | 12 | health_check { 13 | protocol = "HTTP" 14 | path = "${var.healthcheck_path}" 15 | matcher = "200" 16 | } 17 | } 18 | 19 | resource "aws_lb_listener" "http" { 20 | load_balancer_arn = "${var.lb_arn}" 21 | port = "${var.listener_port}" 22 | protocol = "HTTP" 23 | 24 | default_action { 25 | type = "forward" 26 | target_group_arn = "${aws_alb_target_group.http.arn}" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/http/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | value = "${aws_alb_target_group.http.arn}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/http/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "container_port" {} 3 | variable "vpc_id" {} 4 | variable "lb_arn" {} 5 | variable "listener_port" {} 6 | 7 | variable "healthcheck_path" { 8 | default = "/" 9 | } 10 | variable "deregistration_delay" { 11 | default = 300 12 | } 13 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/tcp/locals.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | target_group_name = "${replace(var.service_name, "_", "-")}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/tcp/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "tcp" { 2 | # Must only contain alphanumerics and hyphens. 3 | name = "${local.target_group_name}" 4 | 5 | target_type = "ip" 6 | 7 | protocol = "TCP" 8 | port = "${var.container_port}" 9 | vpc_id = "${var.vpc_id}" 10 | deregistration_delay = "${var.deregistration_delay}" 11 | 12 | health_check { 13 | protocol = "TCP" 14 | } 15 | } 16 | 17 | resource "aws_lb_listener" "tcp" { 18 | load_balancer_arn = "${var.lb_arn}" 19 | port = "${var.listener_port}" 20 | protocol = "TCP" 21 | 22 | default_action { 23 | type = "forward" 24 | target_group_arn = "${aws_lb_target_group.tcp.arn}" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/tcp/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | value = "${aws_lb_target_group.tcp.arn}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/modules/target_group/tcp/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "container_port" {} 3 | variable "vpc_id" {} 4 | variable "lb_arn" {} 5 | variable "listener_port" {} 6 | 7 | variable "deregistration_delay" { 8 | default = 300 9 | } 10 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/daemon/main.tf: -------------------------------------------------------------------------------- 1 | module "iam" { 2 | source = "../../modules/iam" 3 | 4 | service_name = "${aws_ecs_service.service.name}" 5 | } 6 | 7 | resource "aws_ecs_service" "service" { 8 | name = "${var.service_name}_daemon" 9 | cluster = "${var.ecs_cluster_id}" 10 | task_definition = "${var.task_definition_arn}" 11 | 12 | launch_type = "EC2" 13 | scheduling_strategy = "DAEMON" 14 | 15 | deployment_minimum_healthy_percent = "0" 16 | deployment_maximum_percent = "100" 17 | 18 | network_configuration = { 19 | subnets = ["${var.subnets}"] 20 | security_groups = ["${var.security_group_ids}"] 21 | assign_public_ip = false 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/daemon/outputs.tf: -------------------------------------------------------------------------------- 1 | output "service_name" { 2 | value = "${aws_ecs_service.service.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/daemon/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "ecs_cluster_id" {} 3 | variable "task_definition_arn" {} 4 | 5 | variable "subnets" { 6 | type = "list" 7 | } 8 | 9 | variable "security_group_ids" { 10 | type = "list" 11 | default = [] 12 | } 13 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/default/main.tf: -------------------------------------------------------------------------------- 1 | module "iam" { 2 | source = "../../modules/iam" 3 | 4 | service_name = "${aws_ecs_service.service.name}" 5 | } 6 | 7 | resource "aws_ecs_service" "service" { 8 | name = "${var.service_name}" 9 | cluster = "${var.cluster_id}" 10 | task_definition = "${var.task_definition_arn}" 11 | desired_count = "${var.task_desired_count}" 12 | 13 | deployment_minimum_healthy_percent = "${var.deployment_minimum_healthy_percent}" 14 | deployment_maximum_percent = "${var.deployment_maximum_percent}" 15 | 16 | launch_type = "${var.launch_type}" 17 | 18 | network_configuration = { 19 | subnets = ["${var.subnets}"] 20 | security_groups = ["${var.security_group_ids}"] 21 | assign_public_ip = false 22 | } 23 | 24 | service_registries { 25 | registry_arn = "${aws_service_discovery_service.service_discovery.arn}" 26 | } 27 | } 28 | 29 | resource "aws_service_discovery_service" "service_discovery" { 30 | name = "${var.service_name}" 31 | 32 | health_check_custom_config { 33 | failure_threshold = "${var.service_discovery_failure_threshold}" 34 | } 35 | 36 | dns_config { 37 | namespace_id = "${var.namespace_id}" 38 | 39 | dns_records { 40 | ttl = 5 41 | type = "A" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/default/outputs.tf: -------------------------------------------------------------------------------- 1 | output "service_name" { 2 | value = "${aws_ecs_service.service.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/default/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "cluster_id" {} 3 | 4 | variable "task_desired_count" { 5 | default = 1 6 | } 7 | 8 | variable "task_definition_arn" {} 9 | 10 | variable "subnets" { 11 | type = "list" 12 | } 13 | 14 | variable "namespace_id" { 15 | default = "ecs" 16 | } 17 | 18 | variable "security_group_ids" { 19 | type = "list" 20 | default = [] 21 | } 22 | 23 | variable "deployment_minimum_healthy_percent" { 24 | default = "100" 25 | } 26 | 27 | variable "deployment_maximum_percent" { 28 | default = "200" 29 | } 30 | 31 | variable service_discovery_failure_threshold { 32 | default = 1 33 | } 34 | 35 | variable "launch_type" { 36 | default = "FARGATE" 37 | } 38 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/rest/http/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_ecs_service.service.name}" 3 | } 4 | 5 | output "target_group_arn" { 6 | value = "${module.target_group.arn}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/rest/http/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_id" {} 2 | 3 | variable "subnets" { 4 | type = "list" 5 | } 6 | 7 | variable "ecs_cluster_id" {} 8 | variable "service_name" {} 9 | variable "task_definition_arn" {} 10 | variable "container_port" {} 11 | 12 | variable "launch_type" { 13 | default = "FARGATE" 14 | } 15 | 16 | variable "task_desired_count" { 17 | default = "1" 18 | } 19 | 20 | variable "deployment_minimum_healthy_percent" { 21 | default = "100" 22 | } 23 | 24 | variable "deployment_maximum_percent" { 25 | default = "200" 26 | } 27 | 28 | variable "security_group_ids" { 29 | type = "list" 30 | } 31 | 32 | variable "container_name" {} 33 | variable "lb_arn" {} 34 | variable "listener_port" {} 35 | variable "healthcheck_path" {} 36 | variable "namespace_id" {} 37 | 38 | variable "target_group_deregistration_delay" { 39 | default = 300 40 | } 41 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/rest/tcp/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_ecs_service.service.name}" 3 | } 4 | 5 | output "target_group_arn" { 6 | value = "${module.target_group.arn}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/rest/tcp/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_id" {} 2 | 3 | variable "subnets" { 4 | type = "list" 5 | } 6 | 7 | variable "ecs_cluster_id" {} 8 | variable "service_name" {} 9 | variable "task_definition_arn" {} 10 | variable "container_port" {} 11 | 12 | variable "launch_type" { 13 | default = "FARGATE" 14 | } 15 | 16 | variable "task_desired_count" { 17 | default = "1" 18 | } 19 | 20 | variable "deployment_minimum_healthy_percent" { 21 | default = "100" 22 | } 23 | 24 | variable "deployment_maximum_percent" { 25 | default = "200" 26 | } 27 | 28 | variable "security_group_ids" { 29 | type = "list" 30 | } 31 | 32 | variable "assign_public_ip" { 33 | default = false 34 | } 35 | 36 | variable "container_name" {} 37 | variable "lb_arn" {} 38 | variable "listener_port" {} 39 | variable "namespace_id" {} 40 | 41 | variable "target_group_deregistration_delay" { 42 | default = 300 43 | } 44 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/autoscaling.tf: -------------------------------------------------------------------------------- 1 | module "appautoscaling" { 2 | source = "../../../../../autoscaling/app/ecs" 3 | name = "${module.service.name}" 4 | 5 | cluster_name = "${var.cluster_name}" 6 | service_name = "${module.service.name}" 7 | 8 | min_capacity = "${var.min_capacity}" 9 | max_capacity = "${var.max_capacity}" 10 | } 11 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/ecs/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_ecs_service.service.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/ecs/variables.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" {} 2 | variable "ecs_cluster_id" {} 3 | 4 | variable "task_desired_count" { 5 | default = 1 6 | } 7 | 8 | variable "task_definition_arn" {} 9 | 10 | variable "subnets" { 11 | type = "list" 12 | } 13 | 14 | variable "namespace_id" { 15 | default = "ecs" 16 | } 17 | 18 | variable "security_group_ids" { 19 | type = "list" 20 | default = [] 21 | } 22 | 23 | variable "deployment_minimum_healthy_percent" { 24 | default = "100" 25 | } 26 | 27 | variable "deployment_maximum_percent" { 28 | default = "200" 29 | } 30 | 31 | variable service_discovery_failure_threshold { 32 | default = 1 33 | } 34 | 35 | variable "launch_type" { 36 | default = "FARGATE" 37 | } 38 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/main.tf: -------------------------------------------------------------------------------- 1 | module "service" { 2 | source = "ecs" 3 | 4 | service_name = "${var.service_name}" 5 | 6 | task_definition_arn = "${var.task_definition_arn}" 7 | 8 | security_group_ids = ["${var.security_group_ids}"] 9 | subnets = ["${var.subnets}"] 10 | 11 | ecs_cluster_id = "${var.cluster_id}" 12 | 13 | task_desired_count = "${var.task_desired_count}" 14 | namespace_id = "${var.namespace_id}" 15 | 16 | launch_type = "${var.launch_type}" 17 | } 18 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/outputs.tf: -------------------------------------------------------------------------------- 1 | output "service_name" { 2 | value = "${module.service.name}" 3 | } 4 | 5 | output "scale_up_arn" { 6 | value = "${module.appautoscaling.scale_up_arn}" 7 | } 8 | 9 | output "scale_down_arn" { 10 | value = "${module.appautoscaling.scale_down_arn}" 11 | } 12 | -------------------------------------------------------------------------------- /ecs/modules/service/prebuilt/scaling/variables.tf: -------------------------------------------------------------------------------- 1 | variable "min_capacity" { 2 | default = 0 3 | } 4 | 5 | variable "max_capacity" { 6 | default = 3 7 | } 8 | 9 | variable "cluster_id" {} 10 | variable "cluster_name" {} 11 | 12 | variable "service_name" {} 13 | 14 | variable "subnets" { 15 | type = "list" 16 | } 17 | 18 | variable "launch_type" { 19 | default = "FARGATE" 20 | } 21 | 22 | variable "task_desired_count" { 23 | default = 1 24 | } 25 | 26 | variable "security_group_ids" { 27 | type = "list" 28 | default = [] 29 | } 30 | 31 | variable "task_definition_arn" {} 32 | 33 | variable "namespace_id" { 34 | default = "ecs" 35 | } 36 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/container_definition/container_with_sidecar/outputs.tf: -------------------------------------------------------------------------------- 1 | output "rendered" { 2 | value = "${data.template_file.definition.rendered}" 3 | } 4 | 5 | output "app_container_name" { 6 | value = "${local.app_container_name}" 7 | } 8 | 9 | output "sidecar_container_name" { 10 | value = "${local.sidecar_container_name}" 11 | } 12 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/container_definition/single_container/outputs.tf: -------------------------------------------------------------------------------- 1 | output "rendered" { 2 | value = "${data.template_file.definition.rendered}" 3 | } 4 | 5 | output "container_name" { 6 | value = "${local.container_name}" 7 | } 8 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/container_definition/single_container/task_definition.json.template: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "cpu": ${cpu}, 4 | "memory": ${memory}, 5 | "essential": true, 6 | "image": "${container_image}", 7 | "name": "${container_name}", 8 | "environment": ${environment_vars}, 9 | "secrets": ${secrets}, 10 | "networkMode": "awsvpc", 11 | "portMappings": ${port_mappings}, 12 | "command": ${command}, 13 | "logConfiguration": { 14 | "logDriver": "awslogs", 15 | "options": { 16 | "awslogs-group": "${log_group_name}", 17 | "awslogs-region": "${log_group_region}", 18 | "awslogs-stream-prefix": "${log_group_prefix}" 19 | } 20 | }, 21 | "user": "${user}", 22 | "mountPoints": ${mount_points} 23 | } 24 | ] -------------------------------------------------------------------------------- /ecs/modules/task/modules/container_definition/single_container/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region" {} 2 | 3 | variable "task_name" {} 4 | 5 | variable "task_port" { 6 | default = "false" 7 | } 8 | 9 | variable "log_group_prefix" { 10 | description = "Cloudwatch log group name prefix" 11 | default = "ecs" 12 | } 13 | 14 | variable "container_image" {} 15 | 16 | variable "cpu" {} 17 | variable "memory" {} 18 | 19 | variable "mount_points" { 20 | type = "list" 21 | default = [] 22 | } 23 | 24 | variable "command" { 25 | type = "list" 26 | default = [] 27 | } 28 | 29 | variable "execution_role_name" {} 30 | 31 | variable "env_vars" { 32 | description = "Environment variables to pass to the container" 33 | type = "map" 34 | default = {} 35 | } 36 | 37 | variable "env_vars_length" { 38 | default = 0 39 | } 40 | 41 | variable "secret_env_vars" { 42 | description = "Secure environment variables to pass to the container" 43 | type = "map" 44 | default = {} 45 | } 46 | 47 | variable "secret_env_vars_length" { 48 | default = 0 49 | } 50 | 51 | variable "user" { 52 | default = "root" 53 | } 54 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/env_vars/outputs.tf: -------------------------------------------------------------------------------- 1 | output "env_vars_string" { 2 | value = "${local.env_var_string}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/env_vars/variables.tf: -------------------------------------------------------------------------------- 1 | variable "env_vars" { 2 | description = "Environment variables to pass to the container" 3 | type = "map" 4 | } 5 | 6 | variable "env_vars_length" {} 7 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/iam_roles/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_role" "task_role" { 2 | name = "${var.task_name}_task_role" 3 | assume_role_policy = "${data.aws_iam_policy_document.assume_ecs_role.json}" 4 | } 5 | 6 | data "aws_iam_policy_document" "assume_ecs_role" { 7 | statement { 8 | actions = [ 9 | "sts:AssumeRole", 10 | ] 11 | 12 | principals { 13 | type = "Service" 14 | identifiers = ["ecs-tasks.amazonaws.com"] 15 | } 16 | } 17 | } 18 | 19 | resource "aws_iam_role" "execution_role" { 20 | name = "${var.task_name}_execution_role" 21 | assume_role_policy = "${data.aws_iam_policy_document.assume_ecs_role.json}" 22 | } 23 | 24 | resource "aws_iam_role_policy" "execution_role_policy" { 25 | role = "${aws_iam_role.execution_role.name}" 26 | policy = "${data.aws_iam_policy_document.task_execution_role.json}" 27 | } 28 | 29 | data "aws_iam_policy_document" "task_execution_role" { 30 | statement { 31 | actions = [ 32 | "ecr:GetAuthorizationToken", 33 | "ecr:BatchCheckLayerAvailability", 34 | "ecr:GetDownloadUrlForLayer", 35 | "ecr:BatchGetImage", 36 | "logs:CreateLogStream", 37 | "logs:PutLogEvents", 38 | ] 39 | 40 | resources = [ 41 | "*", 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/iam_roles/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_iam_role.task_role.name}" 3 | } 4 | 5 | output "task_role_arn" { 6 | value = "${aws_iam_role.task_role.arn}" 7 | } 8 | 9 | output "task_execution_role_name" { 10 | value = "${aws_iam_role.execution_role.name}" 11 | } 12 | 13 | output "task_execution_role_arn" { 14 | value = "${aws_iam_role.execution_role.arn}" 15 | } 16 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/iam_roles/variables.tf: -------------------------------------------------------------------------------- 1 | variable "task_name" { 2 | description = "Name of task role" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/log_group/main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_cloudwatch_log_group" "task" { 2 | name = "${var.log_group_prefix}/${var.task_name}" 3 | 4 | retention_in_days = "${var.log_retention_in_days}" 5 | } 6 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/log_group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | value = "${aws_cloudwatch_log_group.task.name}" 3 | } 4 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/log_group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "log_group_prefix" { 2 | description = "Cloudwatch log group name prefix" 3 | default = "ecs" 4 | } 5 | 6 | variable "log_retention_in_days" { 7 | description = "The number of days to keep CloudWatch logs" 8 | default = 7 9 | } 10 | 11 | variable "task_name" {} 12 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/port_mappings/main.tf: -------------------------------------------------------------------------------- 1 | variable "container_port" { 2 | default = "false" 3 | } 4 | 5 | variable "host_port" { 6 | default = "0" 7 | } 8 | 9 | variable "protocol" { 10 | description = "Valid values are 'tcp' or 'udp'" 11 | default = "tcp" 12 | } 13 | 14 | locals { 15 | host_port = "${var.host_port == "0" ? var.container_port : var.host_port}" 16 | 17 | port_mapping_with_host = { 18 | ContainerPort = "${var.container_port}" 19 | HostPort = "${local.host_port}" 20 | Protocol = "${var.protocol}" 21 | } 22 | 23 | port_mapping_with_host_string = "[${replace(jsonencode(local.port_mapping_with_host), "/\"([0-9]+\\.?[0-9]*)\"/", "$1")}]" 24 | 25 | port_mapping_string = "${var.container_port == "false" ? "[]" : local.port_mapping_with_host_string}" 26 | } 27 | 28 | output "port_mappings_string" { 29 | value = "${local.port_mapping_string}" 30 | } 31 | 32 | output "container_port" { 33 | value = "${var.container_port}" 34 | } 35 | 36 | output "host_port" { 37 | value = "${var.host_port}" 38 | } 39 | 40 | output "protocol" { 41 | value = "${var.protocol}" 42 | } 43 | -------------------------------------------------------------------------------- /ecs/modules/task/modules/secrets/main.tf: -------------------------------------------------------------------------------- 1 | data "template_file" "name_val_pair" { 2 | # This module constructs a JSON string in the same way as the `env_vars` 3 | # module, and has the same issue that requires us to pass the length of 4 | # the env_vars map as a variable. 5 | count = "${var.secret_env_vars_length}" 6 | 7 | template = <