├── .gitignore ├── LICENSE ├── README.md ├── load-balancer.tf ├── main.tf ├── outputs.tf ├── test.sh ├── test ├── .terraform-version ├── ecs.tf ├── init.sh ├── main.tf ├── outputs.tf ├── roles-ecs-task-execution.tf ├── service_ecs.tf ├── service_fargate.tf ├── task-definition │ └── blog.json └── variables.tf └── variables.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.tfstate 3 | *.tfstate.* 4 | 5 | # Module directory 6 | .terraform/ 7 | 8 | # keys 9 | *id_rsa* 10 | 11 | .idea 12 | .DS_Store 13 | *envrc 14 | atlassian-ide-plugin.xml 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Niek Palm 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS Terraform module to create Fargate / ECS service 2 | 3 | This modules creates a Fargate or ECS service optionally with a application load balancer. 4 | - Supports network modes: "awsvpc" and "bridge" 5 | - Supports ECS and FARGATE 6 | - Optionally a ALB can be created. (HTTP or HTTPS) 7 | 8 | 9 | 10 | ## Example usages: 11 | Below an example for deloy a service to Fargate. See the test directroy for more and complete examples. 12 | 13 | All variables prefix with: 14 | - `awsvpc` : should only be required in case of network mode awsvpc (FARGATE as well). 15 | - `lb` : should only be required in case enable_lb is set to true. 16 | 17 | ``` 18 | resource "aws_security_group" "awsvpc_sg" { 19 | name = "${var.environment}-awsvpc-cluster-sg" 20 | vpc_id = "${module.vpc.vpc_id}" 21 | 22 | ingress { 23 | protocol = "tcp" 24 | from_port = 0 25 | to_port = 65535 26 | 27 | cidr_blocks = [ 28 | "${module.vpc.vpc_cidr}", 29 | ] 30 | } 31 | 32 | egress { 33 | from_port = 0 34 | to_port = 65535 35 | protocol = "tcp" 36 | cidr_blocks = ["0.0.0.0/0"] 37 | } 38 | 39 | tags { 40 | Name = "${var.environment}-ecs-cluster-sg" 41 | Environment = "${var.environment}" 42 | } 43 | } 44 | 45 | locals { 46 | container_name = "blog" 47 | container_port = "80" 48 | } 49 | 50 | data "template_file" "blog" { 51 | template = <` | no | 133 | | awsvpc_service_subnetids | List of subnet ids to which a service is deployed in fargate mode. | string | `` | no | 134 | | awsvpc_task_execution_role_arn | The role arn used for task execution. Required for network mode awsvpc. | string | `` | no | 135 | | ecs_cluster_id | The id of the ECS cluster | string | - | yes | 136 | | ecs_service_role | | string | `` | no | 137 | | enable_alb | Enable or disable the load balancer. | string | `true` | no | 138 | | environment | Logical name of the environment, will be used as prefix and in tags. | string | - | yes | 139 | | lb_health_check | A health check block for the load balancer, see https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_CreateTargetGroup.html more for details. | list | `` | no | 140 | | lb_internal | Indicates if the load balancer should be internal or external. | string | `true` | no | 141 | | lb_listener | The listner for the load balancer, SSL in only applied once a certificate arn is provided. | map | `` | no | 142 | | lb_subnetids | List of subnets to which the load balancer needs to be attached. Mandatory when enable_alb = true. | list | `` | no | 143 | | lb_target_group | The target group to connectect the container to the load balancer listerner. | map | `` | no | 144 | | lb_security_group_ids | Custom Load Balancer security group ids | list | `[]` | no | 145 | | lb_health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 2147483647 | string | `0` | no | 146 | | service_desired_count | The number of instances of the task definition to place and keep running. | string | `1` | no | 147 | | service_launch_type | The launch type, can be EC2 or FARGATE. | string | `EC2` | no | 148 | | service_name | Logical name of the service. | string | - | yes | 149 | | task_cpu | CPU value for the task, required for FARGATE. | string | `` | no | 150 | | task_definition | The AWS task definition of the containers to be created. | string | - | yes | 151 | | task_memory | Memory value for the task, required for FARGATE. | string | `` | no | 152 | | task_network_mode | The network mode to be used in the task definiton. Supported modes are awsvpc and bridge. | string | `awsvpc` | no | 153 | | task_role_arn | The AWS IAM role that will be provided to the task to perform AWS actions. | string | `` | no | 154 | | task_volumes | List of volume blocks for task definition | list | `[]` | no | 155 | | vpc_cidr | CIDR for the VPC. | string | - | yes | 156 | | vpc_id | ID of the VPC. | string | - | yes | 157 | | public_alb_whitelist | Whitelists IP to be able to access ALB | list | ["0.0.0.0/0","::/0"] | no | 158 | 159 | ## Outputs 160 | 161 | | Name | Description | 162 | |------|-------------| 163 | | service_url | Service urls. | 164 | | lb_dns_name | Load Balancer DNS Name. | 165 | | task_definition_arn | Task definition ARN. | 166 | | lb_target_group_arn | Load Balancer Target Group ARN. | 167 | | lb_arn | Load Balancer ARN. | 168 | | lb_listener_arn | Load Balancer Listener ARN. | 169 | | lb_security_group_id | Load Balancer Security Group ID. | 170 | -------------------------------------------------------------------------------- /load-balancer.tf: -------------------------------------------------------------------------------- 1 | resource "aws_alb" "main" { 2 | count = "${var.enable_lb ? 1 : 0}" ## Load Balancer 3 | 4 | name = "${var.environment}-${var.service_name}" 5 | 6 | internal = "${var.lb_internal}" 7 | subnets = ["${var.lb_subnetids}"] 8 | security_groups = ["${concat(list(aws_security_group.alb_sg.id), var.lb_security_group_ids)}"] 9 | 10 | tags { 11 | Name = "${var.environment}-${var.service_name}" 12 | Environment = "${var.environment}" 13 | Application = "${var.service_name}" 14 | } 15 | } 16 | 17 | resource "aws_alb_listener" "main" { 18 | count = "${var.enable_lb ? 1 : 0 }" 19 | 20 | load_balancer_arn = "${aws_alb.main.id}" 21 | port = "${lookup(var.lb_listener, "port")}" 22 | protocol = "${lookup(var.lb_listener, "protocol", "HTTP")}" 23 | certificate_arn = "${lookup(var.lb_listener, "certificate_arn", "")}" 24 | ssl_policy = "${lookup(var.lb_listener, "certificate_arn", "") == "" ? "" : lookup(var.lb_listener, "ssl_policy", "ELBSecurityPolicy-TLS-1-1-2017-01")}" 25 | 26 | default_action { 27 | target_group_arn = "${aws_alb_target_group.main.id}" 28 | type = "forward" 29 | } 30 | } 31 | 32 | resource "aws_alb_target_group" "main" { 33 | count = "${var.enable_lb ? 1 : 0}" 34 | 35 | name = "${var.environment}-${var.service_name}" 36 | 37 | port = "${lookup(var.lb_target_group, "host_port", 80)}" 38 | protocol = "${upper(lookup(var.lb_target_group, "protocol", "HTTP"))}" 39 | vpc_id = "${var.vpc_id}" 40 | target_type = "${lookup(var.lb_target_group, "target_type", "ip")}" 41 | 42 | health_check = "${var.lb_health_check}" 43 | 44 | deregistration_delay = "${lookup(var.lb_target_group, "deregistration_delay", 300)}" 45 | 46 | tags { 47 | Name = "${var.environment}-${var.service_name}" 48 | Environment = "${var.environment}" 49 | Application = "${var.service_name}" 50 | } 51 | } 52 | 53 | resource "aws_security_group" "alb_sg" { 54 | count = "${var.enable_lb ? 1 : 0}" 55 | 56 | name = "${var.environment}-${var.service_name}-alb-sg" 57 | description = "controls access to the application LB" 58 | 59 | vpc_id = "${var.vpc_id}" 60 | 61 | ingress { 62 | protocol = "tcp" 63 | from_port = "${lookup(var.lb_listener, "port", 80)}" 64 | to_port = "${lookup(var.lb_listener, "port", 80)}" 65 | cidr_blocks = ["${split(",",var.lb_internal ? var.vpc_cidr : join(",",var.public_alb_whitelist))}"] 66 | } 67 | 68 | egress { 69 | from_port = 0 70 | to_port = 0 71 | protocol = "-1" 72 | 73 | cidr_blocks = ["0.0.0.0/0"] 74 | } 75 | 76 | tags { 77 | Name = "${var.environment}-${var.service_name}-alb-sg" 78 | Environment = "${var.environment}" 79 | Application = "${var.service_name}" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | resource "aws_ecs_task_definition" "main" { 2 | family = "${var.environment}-${var.service_name}" 3 | container_definitions = "${var.task_definition}" 4 | task_role_arn = "${var.task_role_arn}" 5 | network_mode = "${var.task_network_mode}" 6 | cpu = "${var.task_cpu}" 7 | memory = "${var.task_memory}" 8 | requires_compatibilities = ["${var.service_launch_type}"] 9 | execution_role_arn = "${var.awsvpc_task_execution_role_arn}" 10 | volume = ["${var.task_volumes}"] 11 | } 12 | 13 | # Service for awsvpc networking and ALB 14 | resource "aws_ecs_service" "awsvpc_alb" { 15 | count = "${var.task_network_mode == "awsvpc" && var.enable_lb ? 1 : 0 }" 16 | 17 | name = "${var.service_name}" 18 | cluster = "${var.ecs_cluster_id}" 19 | task_definition = "${aws_ecs_task_definition.main.arn}" 20 | desired_count = "${var.service_desired_count}" 21 | 22 | load_balancer = { 23 | target_group_arn = "${aws_alb_target_group.main.arn}" 24 | container_name = "${lookup(var.lb_target_group, "container_name", var.service_name)}" 25 | container_port = "${lookup(var.lb_target_group, "container_port", 8080)}" 26 | } 27 | 28 | health_check_grace_period_seconds = "${var.lb_health_check_grace_period_seconds}" 29 | 30 | launch_type = "${var.service_launch_type}" 31 | 32 | network_configuration { 33 | security_groups = ["${var.awsvpc_service_security_groups}"] 34 | subnets = ["${var.awsvpc_service_subnetids}"] 35 | } 36 | 37 | depends_on = ["aws_alb_listener.main"] 38 | } 39 | 40 | # Service for bridge networking and ALB 41 | resource "aws_ecs_service" "bridge_alb" { 42 | count = "${var.task_network_mode == "bridge" && var.enable_lb ? 1 : 0 }" 43 | depends_on = ["aws_alb_listener.main"] 44 | 45 | name = "${var.service_name}" 46 | cluster = "${var.ecs_cluster_id}" 47 | task_definition = "${aws_ecs_task_definition.main.arn}" 48 | desired_count = "${var.service_desired_count}" 49 | 50 | load_balancer = { 51 | target_group_arn = "${aws_alb_target_group.main.arn}" 52 | container_name = "${lookup(var.lb_target_group, "container_name", var.service_name)}" 53 | container_port = "${lookup(var.lb_target_group, "container_port", 8080)}" 54 | } 55 | 56 | health_check_grace_period_seconds = "${var.lb_health_check_grace_period_seconds}" 57 | 58 | launch_type = "${var.service_launch_type}" 59 | 60 | iam_role = "${var.ecs_service_role}" 61 | } 62 | 63 | # Service for awsvpc networking and no ALB 64 | resource "aws_ecs_service" "awsvpc_nolb" { 65 | count = "${var.task_network_mode == "awsvpc" && !var.enable_lb ? 1 : 0 }" 66 | depends_on = ["aws_alb_listener.main"] 67 | 68 | name = "${var.service_name}" 69 | cluster = "${var.ecs_cluster_id}" 70 | task_definition = "${aws_ecs_task_definition.main.arn}" 71 | desired_count = "${var.service_desired_count}" 72 | 73 | network_configuration { 74 | security_groups = ["${var.awsvpc_service_security_groups}"] 75 | subnets = ["${var.awsvpc_service_subnetids}"] 76 | } 77 | 78 | launch_type = "${var.service_launch_type}" 79 | } 80 | 81 | # Service for bridge networking and no ALB 82 | resource "aws_ecs_service" "bridge_noalb" { 83 | count = "${var.task_network_mode == "bridge" && !var.enable_lb ? 1 : 0 }" 84 | depends_on = ["aws_alb_listener.main"] 85 | 86 | name = "${var.service_name}" 87 | cluster = "${var.ecs_cluster_id}" 88 | task_definition = "${aws_ecs_task_definition.main.arn}" 89 | desired_count = "${var.service_desired_count}" 90 | 91 | launch_type = "${var.service_launch_type}" 92 | } 93 | -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "service_url" { 2 | description = "Service urls." 3 | 4 | value = "${var.enable_lb ? 5 | lower(join(",", formatlist( 6 | "%s://%s:%s", 7 | aws_alb_listener.main.*.protocol, 8 | element(concat(aws_alb.main.*.dns_name, list("")), 0), 9 | aws_alb_listener.main.*.port 10 | ))) : ""}" 11 | } 12 | 13 | output "lb_dns_name" { 14 | description = "Loadbalancer DNS Name" 15 | 16 | value = "${var.enable_lb ? 17 | element(concat(aws_alb.main.*.dns_name, list("")), 0) : "" 18 | }" 19 | } 20 | 21 | output "lb_arn" { 22 | description = "Loadbalancer ARN" 23 | 24 | value = "${var.enable_lb ? 25 | element(concat(aws_alb.main.*.arn, list("")), 0) : "" 26 | }" 27 | } 28 | 29 | output "lb_zone_id" { 30 | description = "Loadbalancer Zone ID" 31 | 32 | value = "${var.enable_lb ? 33 | element(concat(aws_alb.main.*.zone_id, list("")), 0) : "" 34 | }" 35 | } 36 | 37 | output "task_definition_arn" { 38 | description = "Task definition ARN" 39 | 40 | value = "${aws_ecs_task_definition.main.arn}" 41 | } 42 | 43 | output "lb_target_group_arn" { 44 | description = "Loadbalancer Target Group ARN" 45 | 46 | value = "${var.enable_lb ? 47 | element(concat(aws_alb_target_group.main.*.arn, list("")), 0) : "" 48 | }" 49 | } 50 | 51 | output "lb_listener_arn" { 52 | description = "Loadbalancer Listener ARN" 53 | 54 | value = "${var.enable_lb ? 55 | element(concat(aws_alb_listener.main.*.arn, list("")), 0) : "" 56 | }" 57 | } 58 | 59 | output "lb_security_group_id" { 60 | description = "Loadbalancer Security Group id" 61 | 62 | value = "${var.enable_lb ? 63 | element(concat(aws_security_group.alb_sg.*.id, list("")), 0) : "" 64 | }" 65 | } 66 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # exit on failures 4 | set -e 5 | set -o pipefail 6 | 7 | terraform fmt -check -diff 8 | -------------------------------------------------------------------------------- /test/.terraform-version: -------------------------------------------------------------------------------- 1 | 0.11.2 2 | -------------------------------------------------------------------------------- /test/ecs.tf: -------------------------------------------------------------------------------- 1 | resource "aws_key_pair" "key" { 2 | key_name = "${var.key_name}" 3 | public_key = "${file("${var.ssh_key_file_ecs}")}" 4 | } 5 | 6 | module "ecs_instances" { 7 | source = "npalm/ecs-instances/aws" 8 | version = "0.3.0" 9 | 10 | ecs_cluster_name = "${aws_ecs_cluster.cluster.name}" 11 | aws_region = "${var.aws_region}" 12 | environment = "${var.environment}" 13 | key_name = "${var.key_name}" 14 | vpc_id = "${module.vpc.vpc_id}" 15 | vpc_cidr = "${module.vpc.vpc_cidr}" 16 | subnets = "${module.vpc.private_subnets}" 17 | } 18 | -------------------------------------------------------------------------------- /test/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p generated 4 | ssh-keygen -t rsa -C "demo" -P '' -f generated/id_rsa 5 | -------------------------------------------------------------------------------- /test/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "${var.aws_region}" 3 | version = "1.7.1" 4 | } 5 | 6 | module "vpc" { 7 | source = "npalm/vpc/aws" 8 | version = "1.1.0" 9 | 10 | environment = "${var.environment}" 11 | aws_region = "${var.aws_region}" 12 | 13 | create_private_hosted_zone = "false" 14 | 15 | availability_zones = { 16 | us-east-1 = ["us-east-1a", "us-east-1b", "us-east-1c"] 17 | } 18 | } 19 | 20 | resource "aws_cloudwatch_log_group" "log_group" { 21 | name = "${var.environment}" 22 | } 23 | 24 | resource "aws_ecs_cluster" "cluster" { 25 | name = "${var.environment}-ecs-cluster" 26 | } 27 | 28 | resource "aws_security_group" "awsvpc_sg" { 29 | name = "${var.environment}-awsvpc-cluster-sg" 30 | vpc_id = "${module.vpc.vpc_id}" 31 | 32 | ingress { 33 | protocol = "tcp" 34 | from_port = 0 35 | to_port = 65535 36 | 37 | cidr_blocks = [ 38 | "${module.vpc.vpc_cidr}", 39 | ] 40 | } 41 | 42 | egress { 43 | from_port = 0 44 | to_port = 65535 45 | protocol = "tcp" 46 | cidr_blocks = ["0.0.0.0/0"] 47 | } 48 | 49 | tags { 50 | Name = "${var.environment}-ecs-cluster-sg" 51 | Environment = "${var.environment}" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/outputs.tf: -------------------------------------------------------------------------------- 1 | output "blog-fg-url" { 2 | value = "${module.blog-fg.service_url}" 3 | } 4 | 5 | output "blog-ecs-url" { 6 | value = "${module.blog-ecs.service_url}" 7 | } 8 | -------------------------------------------------------------------------------- /test/roles-ecs-task-execution.tf: -------------------------------------------------------------------------------- 1 | data "aws_iam_policy_document" "ecs_tasks_execution_role" { 2 | statement { 3 | actions = ["sts:AssumeRole"] 4 | 5 | principals { 6 | type = "Service" 7 | identifiers = ["ecs-tasks.amazonaws.com"] 8 | } 9 | } 10 | } 11 | 12 | resource "aws_iam_role" "ecs_tasks_execution_role" { 13 | name = "${var.environment}-ecs-task-execution-role" 14 | assume_role_policy = "${data.aws_iam_policy_document.ecs_tasks_execution_role.json}" 15 | } 16 | 17 | resource "aws_iam_role_policy_attachment" "ecs_tasks_execution_role" { 18 | role = "${aws_iam_role.ecs_tasks_execution_role.name}" 19 | policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" 20 | } 21 | -------------------------------------------------------------------------------- /test/service_ecs.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | ecs_container_name = "blog" 3 | ecs_container_port = "80" 4 | } 5 | 6 | data "template_file" "blog_ecs" { 7 | template = "${file("${path.root}/task-definition/blog.json")}" 8 | 9 | vars { 10 | container_name = "${local.ecs_container_name}" 11 | container_port = "${local.ecs_container_port}" 12 | log_group_name = "${aws_cloudwatch_log_group.log_group.name}" 13 | log_group_region = "${var.aws_region}" 14 | log_group_prefix = "blog-040" 15 | } 16 | } 17 | 18 | module "blog-ecs" { 19 | source = ".." 20 | 21 | service_name = "blog-040-ecs" 22 | service_desired_count = 1 23 | 24 | environment = "${var.environment}" 25 | 26 | vpc_id = "${module.vpc.vpc_id}" 27 | vpc_cidr = "${module.vpc.vpc_cidr}" 28 | lb_subnetids = "${module.vpc.public_subnets}" 29 | 30 | ecs_cluster_id = "${aws_ecs_cluster.cluster.id}" 31 | 32 | lb_internal = false 33 | 34 | task_definition = "${data.template_file.blog_ecs.rendered}" 35 | task_cpu = "256" 36 | task_memory = "512" 37 | 38 | service_launch_type = "EC2" 39 | 40 | awsvpc_task_execution_role_arn = "${aws_iam_role.ecs_tasks_execution_role.arn}" 41 | awsvpc_service_security_groups = ["${aws_security_group.awsvpc_sg.id}"] 42 | awsvpc_service_subnetids = "${module.vpc.private_subnets}" 43 | 44 | lb_target_group = { 45 | container_name = "${local.ecs_container_name}" 46 | container_port = "${local.ecs_container_port}" 47 | } 48 | 49 | lb_listener = { 50 | port = 80 51 | protocol = "HTTP" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/service_fargate.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | fg_container_name = "blog" 3 | fg_container_port = "80" 4 | } 5 | 6 | data "template_file" "blog" { 7 | template = "${file("${path.root}/task-definition/blog.json")}" 8 | 9 | vars { 10 | container_name = "${local.fg_container_name}" 11 | container_port = "${local.fg_container_port}" 12 | log_group_name = "${aws_cloudwatch_log_group.log_group.name}" 13 | log_group_region = "${var.aws_region}" 14 | log_group_prefix = "blog-040" 15 | } 16 | } 17 | 18 | module "blog-fg" { 19 | source = ".." 20 | 21 | service_name = "blog-040-fg" 22 | service_desired_count = 1 23 | 24 | environment = "${var.environment}" 25 | 26 | vpc_id = "${module.vpc.vpc_id}" 27 | vpc_cidr = "${module.vpc.vpc_cidr}" 28 | lb_subnetids = "${module.vpc.public_subnets}" 29 | 30 | ecs_cluster_id = "${aws_ecs_cluster.cluster.id}" 31 | 32 | lb_internal = false 33 | 34 | task_definition = "${data.template_file.blog.rendered}" 35 | task_cpu = "256" 36 | task_memory = "512" 37 | 38 | service_launch_type = "FARGATE" 39 | 40 | awsvpc_task_execution_role_arn = "${aws_iam_role.ecs_tasks_execution_role.arn}" 41 | awsvpc_service_security_groups = ["${aws_security_group.awsvpc_sg.id}"] 42 | awsvpc_service_subnetids = "${module.vpc.private_subnets}" 43 | 44 | lb_target_group = { 45 | container_name = "${local.fg_container_name}" 46 | container_port = "${local.fg_container_port}" 47 | } 48 | 49 | lb_listener = { 50 | port = 80 51 | protocol = "HTTP" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/task-definition/blog.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "essential": true, 4 | "memoryReservation": null, 5 | "image": "npalm/040code.github.io:latest", 6 | "name": "${container_name}", 7 | "portMappings": [ 8 | { 9 | "hostPort": ${container_port}, 10 | "protocol": "tcp", 11 | "containerPort": ${container_port} 12 | } 13 | ], 14 | "environment": [], 15 | "logConfiguration": { 16 | "logDriver": "awslogs", 17 | "options": { 18 | "awslogs-group": "${log_group_name}", 19 | "awslogs-region": "${log_group_region}", 20 | "awslogs-stream-prefix": "${log_group_prefix}" 21 | } 22 | } 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /test/variables.tf: -------------------------------------------------------------------------------- 1 | variable "aws_region" { 2 | description = "The Amazon region" 3 | type = "string" 4 | default = "us-east-1" 5 | } 6 | 7 | variable "environment" { 8 | type = "string" 9 | default = "module-test" 10 | } 11 | 12 | variable "ssh_key_file_ecs" { 13 | default = "generated/id_rsa.pub" 14 | } 15 | 16 | variable "key_name" { 17 | type = "string" 18 | default = "module-test" 19 | } 20 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_id" { 2 | description = "ID of the VPC." 3 | type = "string" 4 | } 5 | 6 | variable "vpc_cidr" { 7 | description = "CIDR for the VPC." 8 | type = "string" 9 | } 10 | 11 | variable "environment" { 12 | description = "Logical name of the environment, will be used as prefix and in tags." 13 | type = "string" 14 | } 15 | 16 | variable "lb_subnetids" { 17 | description = "List of subnets to which the load balancer needs to be attached. Mandatory when enable_lb = true." 18 | type = "list" 19 | default = [] 20 | } 21 | 22 | variable "task_role_arn" { 23 | description = "The AWS IAM role that will be provided to the task to perform AWS actions." 24 | type = "string" 25 | default = "" 26 | } 27 | 28 | variable "ecs_cluster_id" { 29 | description = "The id of the ECS cluster" 30 | type = "string" 31 | } 32 | 33 | variable "task_network_mode" { 34 | description = "The network mode to be used in the task definiton. Supported modes are awsvpc and bridge." 35 | default = "awsvpc" 36 | } 37 | 38 | variable "service_name" { 39 | description = "Logical name of the service." 40 | type = "string" 41 | } 42 | 43 | variable "lb_target_group" { 44 | description = "The target group to connectect the container to the load balancer listerner." 45 | type = "map" 46 | 47 | default = { 48 | container_port = 8080 49 | host_port = 80 50 | protocol = "http" 51 | deregistration_delay = 300 52 | } 53 | } 54 | 55 | variable "lb_listener" { 56 | description = "The listner for the load balancer, SSL in only applied once a certificate arn is provided." 57 | type = "map" 58 | 59 | default = { 60 | port = "80" 61 | certificate_arn = "" 62 | ssl_policy = "ELBSecurityPolicy-TLS-1-1-2017-01" 63 | } 64 | } 65 | 66 | variable "awsvpc_service_security_groups" { 67 | description = "List of security groups to be attached to service running in awsvpc network mode." 68 | default = [] 69 | } 70 | 71 | variable "awsvpc_service_subnetids" { 72 | description = "List of subnet ids to which a service is deployed in fargate mode." 73 | default = [] 74 | } 75 | 76 | variable "lb_internal" { 77 | description = "Indicates if the load balancer should be internal or external." 78 | default = "true" 79 | } 80 | 81 | variable "task_definition" { 82 | description = "The AWS task definition of the containers to be created." 83 | type = "string" 84 | } 85 | 86 | variable "service_desired_count" { 87 | description = "The number of instances of the task definition to place and keep running." 88 | default = "1" 89 | } 90 | 91 | variable "lb_health_check" { 92 | description = "A health check block for the load balancer, see https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_CreateTargetGroup.html more for details." 93 | type = "list" 94 | default = [{}] 95 | } 96 | 97 | variable "awsvpc_task_execution_role_arn" { 98 | description = "The role arn used for task execution. Required for network mode awsvpc." 99 | type = "string" 100 | default = "" 101 | } 102 | 103 | variable "service_launch_type" { 104 | description = "The launch type, can be EC2 or FARGATE." 105 | type = "string" 106 | default = "EC2" 107 | } 108 | 109 | variable "task_cpu" { 110 | description = "CPU value for the task, required for FARGATE." 111 | type = "string" 112 | default = "" 113 | } 114 | 115 | variable "task_memory" { 116 | description = "Memory value for the task, required for FARGATE." 117 | type = "string" 118 | default = "" 119 | } 120 | 121 | variable "task_volumes" { 122 | description = "List of volume blocks for task definition" 123 | type = "list" 124 | default = [] 125 | } 126 | 127 | variable "enable_lb" { 128 | description = "Enable or disable the load balancer." 129 | default = true 130 | } 131 | 132 | variable "ecs_service_role" { 133 | default = "" 134 | } 135 | 136 | variable "public_alb_whitelist" { 137 | type = "list" 138 | description = "Enables to limit the ips that can access the ALB over public network" 139 | default = ["0.0.0.0/0"] 140 | } 141 | 142 | variable "lb_security_group_ids" { 143 | description = "Custom Load Balancer security group ids" 144 | type = "list" 145 | default = [] 146 | } 147 | 148 | variable "lb_health_check_grace_period_seconds" { 149 | description = "Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 2147483647" 150 | type = "string" 151 | default = "0" 152 | } 153 | --------------------------------------------------------------------------------