Skip to content

Commit 2af04d4

Browse files
author
Eugene Dementiev
committed
initial cut
0 parents  commit 2af04d4

File tree

8 files changed

+253
-0
lines changed

8 files changed

+253
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.terraform/

data.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
data "aws_ecs_cluster" "main" {
2+
cluster_name = var.cluster_name
3+
}
4+
5+
data "aws_region" "current" {}
6+
7+
8+
data "aws_lb_target_group" "TG" {
9+
count = local.balanced ? 1 : 0
10+
11+
name = local.target_group_name
12+
}

iam.tf

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
data "aws_iam_policy_document" "ecs-assume" {
2+
statement {
3+
actions = ["sts:AssumeRole"]
4+
5+
principals {
6+
type = "Service"
7+
identifiers = ["ecs.amazonaws.com"]
8+
}
9+
}
10+
}
11+
12+
resource "aws_iam_role" "task-role-alb" {
13+
count = local.balanced ? 1 : 0
14+
15+
name = "${var.cluster_name}-${var.service_name}-alb"
16+
17+
assume_role_policy = data.aws_iam_policy_document.ecs-assume.json
18+
}
19+
20+
21+
data "aws_iam_policy_document" "service_policy_alb" {
22+
count = local.balanced ? 1 : 0
23+
24+
statement {
25+
actions = [
26+
"elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
27+
"elasticloadbalancing:RegisterInstancesWithLoadBalancer",
28+
]
29+
30+
resources = [
31+
data.aws_lb_target_group.TG[0].arn,
32+
]
33+
}
34+
35+
statement {
36+
actions = [
37+
"elasticloadbalancing:DeregisterTargets",
38+
"elasticloadbalancing:RegisterTargets",
39+
]
40+
41+
resources = [
42+
"*",
43+
]
44+
}
45+
46+
statement {
47+
actions = [
48+
"elasticloadbalancing:Describe*",
49+
"ec2:Describe*",
50+
"ec2:AuthorizeSecurityGroupIngress",
51+
]
52+
53+
resources = [
54+
"*",
55+
]
56+
}
57+
}
58+
59+
resource "aws_iam_role_policy" "service_policy_alb" {
60+
count = local.balanced ? 1 : 0
61+
62+
name = "${var.cluster_name}-${var.service_name}-alb"
63+
role = aws_iam_role.task-role-alb[0].name
64+
policy = data.aws_iam_policy_document.service_policy_alb[0].json
65+
}
66+

logs.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resource "aws_cloudwatch_log_group" "main" {
2+
count = local.log_awslogs ? 1 : 0
3+
4+
name = "awslogs-${var.cluster_name}-${var.service_name}"
5+
}
6+

main.tf

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
resource "aws_ecs_task_definition" "task" {
2+
family = "${var.cluster_name}-${var.service_name}"
3+
container_definitions = jsonencode([
4+
{
5+
name = var.service_name
6+
image = var.image
7+
cpu = var.cpu
8+
essential = var.essential
9+
memory = var.memory
10+
memoryReservation = var.memory_reservation
11+
portMappings = local.balanced ? coalescelist(var.port_mappings, local.defaultPortMappings) : []
12+
mountPoints = []
13+
logConfiguration = local.log_configuration
14+
environment = [for k in sort(keys(var.environment)) : { "name" : k, "value" : var.environment[k] }]
15+
volumesFrom = []
16+
}
17+
])
18+
19+
task_role_arn = var.task_role_arn
20+
21+
}
22+
23+
24+
resource "aws_ecs_service" "service" {
25+
name = var.service_name
26+
cluster = data.aws_ecs_cluster.main.cluster_name
27+
task_definition = "${aws_ecs_task_definition.task.family}:${aws_ecs_task_definition.task.revision}"
28+
desired_count = var.desired_count
29+
deployment_minimum_healthy_percent = var.deployment_minimum_healthy_percent
30+
deployment_maximum_percent = var.deployment_maximum_percent
31+
32+
iam_role = local.balanced ? aws_iam_role.task-role-alb[0].arn : ""
33+
34+
ordered_placement_strategy {
35+
type = "spread"
36+
field = "attribute:ecs.availability-zone"
37+
}
38+
39+
ordered_placement_strategy {
40+
type = "spread"
41+
field = "instanceId"
42+
}
43+
44+
dynamic "load_balancer" {
45+
for_each = local.balanced ? [1] : []
46+
47+
content {
48+
target_group_arn = data.aws_lb_target_group.TG[0].arn
49+
container_name = var.service_name
50+
container_port = var.container_port
51+
}
52+
}
53+
}
54+

outputs.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
output "task-definition-arn" {
2+
description = "Arn of the task definition"
3+
value = aws_ecs_task_definition.task.arn
4+
}
5+
output "task-definition-family" {
6+
description = "Family of the task definition"
7+
value = aws_ecs_task_definition.task.family
8+
}

variables.tf

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
variable "cluster_name" {
2+
description = "Name of the ECS cluster"
3+
}
4+
5+
variable "service_name" {
6+
description = "Name of the ECS service"
7+
}
8+
9+
variable "target_group_name" {
10+
description = "Name of the ALB target group. Defaults to the `cluster_name` if not set"
11+
default = ""
12+
}
13+
14+
variable "environment" {
15+
description = "Enviropnment vars to pass to the container. Note: they will be visible in the task definition, so please don't pass any secrets here."
16+
type = map
17+
default = {}
18+
19+
}
20+
21+
variable "image" {
22+
description = "The image to use"
23+
}
24+
25+
variable "cpu" {
26+
description = "Amount of CPU to use"
27+
default = 0
28+
}
29+
30+
variable "essential" {
31+
description = "Exit the task if contaner exits"
32+
default = true
33+
}
34+
35+
variable "memory" {
36+
description = "Amount of maximum memory the container can use"
37+
default = 512
38+
}
39+
40+
variable "memory_reservation" {
41+
description = "Amount of reserved memory for the container"
42+
default = 256
43+
}
44+
45+
variable "container_port" {
46+
default = 0
47+
}
48+
49+
variable "task_role_arn" {
50+
type = string
51+
default = ""
52+
}
53+
54+
variable "port_mappings" {
55+
type = list
56+
default = []
57+
}
58+
59+
variable "log_configuration" {
60+
type = object({
61+
logDriver = string
62+
options = map(any)
63+
})
64+
default = { logDriver = "", options = {} }
65+
}
66+
67+
variable "deployment_minimum_healthy_percent" {
68+
description = "Minimum number of healty contianers during deployments"
69+
default = 50
70+
}
71+
72+
variable "deployment_maximum_percent" {
73+
description = "Maximum number of healty contianers during deployments"
74+
default = 200
75+
}
76+
77+
variable "desired_count" {
78+
default = 1
79+
}
80+
81+
locals {
82+
balanced = var.container_port > 0
83+
target_group_name = coalesce(var.target_group_name, var.cluster_name)
84+
85+
default_log_configuration = {
86+
"logDriver" = "awslogs"
87+
"options" = {
88+
"awslogs-group" = aws_cloudwatch_log_group.main[0].name
89+
"awslogs-region" = data.aws_region.current.name
90+
"awslogs-stream-prefix" = var.service_name
91+
}
92+
}
93+
log_awslogs = var.log_configuration["logDriver"] == ""
94+
log_configuration = local.log_awslogs ? local.default_log_configuration : var.log_configuration
95+
96+
defaultPortMappings = [
97+
{
98+
containerPort = var.container_port
99+
}
100+
]
101+
}
102+

versions.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
terraform {
3+
required_version = ">= 0.12"
4+
}

0 commit comments

Comments
 (0)