-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow for DMP-specific ECS Task definitions
- Loading branch information
1 parent
e5e336c
commit 132fcd7
Showing
6 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# DMP ECS Task Definition | ||
|
||
Collection of resources to specify a Task Definition in Elastic Container Service. This version differs slightly from [the original ECS Task Definition resource group](../ecs-fargate-task-definition) in ways which are designed to make it easier to adopt within the already mature DMP Terraform environments. | ||
|
||
Includes (non-exhaustive): | ||
|
||
* Task Definition | ||
* Task Role and JSON document describing the IAM permission to pass the Task Role | ||
|
||
There is a lot of commonality with the original ECS Task Definition resource group but the decision was taken _not_ to refactor them into a single module because it would introduce a lot of tightly-structured logic into a construct which (tbh) already stretches the idea of clear declarative code a little bit. | ||
|
||
So we're bolting this module alongside that and when (if?) DMP is ever shut down, it can safely be removed. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
locals { | ||
/* Note that in the cases of interval, retries, hostPort, protocol and volumesFrom we have added these even | ||
though they are implicitly inferred by AWS. Reason being that Terraform forces a cycle of the ECS Service | ||
definition each time if they are omitted, and this is expensive in lots of ways. | ||
*/ | ||
container_definitions = [ | ||
for name, vars in var.container_definitions : { | ||
name = name | ||
command = vars.override_command # If null, does not override Dockerfile original command | ||
cpu = vars.cpu | ||
entrypoint = lookup(var.override_entrypoints, name, null) | ||
environment = vars.environment_variables | ||
essential = vars.essential != null ? vars.essential : true | ||
healthCheck = vars.healthcheck_command == null ? null : { | ||
command = ["CMD-SHELL", vars.healthcheck_command] | ||
interval = 30 | ||
retries = 3 | ||
startPeriod = 10 | ||
timeout = 10 | ||
} | ||
image = vars.image | ||
logConfiguration = { | ||
"logDriver" : "awslogs", | ||
"options" : { | ||
"awslogs-group" : vars.log_group_name, | ||
"awslogs-region" : var.aws_region, | ||
"awslogs-stream-prefix" : "container" | ||
} | ||
} | ||
memory = vars.memory | ||
mountPoints = [ | ||
for mount in vars.mounts : | ||
{ | ||
containerPath : mount["mount_point"], | ||
readOnly : mount["read_only"], | ||
sourceVolume : mount["volume_name"] | ||
} | ||
] | ||
portMappings = vars.port == null ? null : [ | ||
{ | ||
containerPort = vars.port | ||
hostPort = vars.port | ||
protocol = "tcp" | ||
} | ||
] | ||
secrets = vars.secret_environment_variables | ||
volumesFrom = [] | ||
} | ||
] | ||
} | ||
|
||
resource "aws_ecs_task_definition" "task" { | ||
family = var.family_name | ||
container_definitions = jsonencode(local.container_definitions) | ||
cpu = var.task_cpu | ||
execution_role_arn = var.ecs_execution_role_arn | ||
memory = var.task_memory | ||
network_mode = "awsvpc" # Fixed for Fargate | ||
requires_compatibilities = ["FARGATE"] | ||
runtime_platform { | ||
cpu_architecture = "X86_64" | ||
operating_system_family = "LINUX" | ||
} | ||
task_role_arn = aws_iam_role.task_role.arn | ||
|
||
dynamic "volume" { | ||
for_each = var.volumes | ||
iterator = volume | ||
|
||
content { | ||
efs_volume_configuration { | ||
authorization_config { | ||
access_point_id = volume.value["access_point_id"] | ||
iam = "DISABLED" | ||
} | ||
file_system_id = volume.value["file_system_id"] | ||
transit_encryption = "ENABLED" | ||
} | ||
|
||
name = volume.value["volume_name"] | ||
} | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
resource-groups/dmp-ecs-fargate-task-definition/outputs.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
output "pass_task_role_policy_document_json" { | ||
description = "JSON describing an IAM policy which allows passage of the task role" | ||
value = data.aws_iam_policy_document.pass_task_role.json | ||
} | ||
|
||
output "task_definition_arn" { | ||
description = "ARN of the task definition" | ||
value = aws_ecs_task_definition.task.arn | ||
} | ||
|
||
output "task_family_name" { | ||
description = "Family name for the task" | ||
value = aws_ecs_task_definition.task.family | ||
} | ||
|
||
output "task_role_arn" { | ||
description = "ARN of the IAM role assigned to all tasks run under this task definition" | ||
value = aws_iam_role.task_role.arn | ||
} | ||
|
||
output "task_role_name" { | ||
description = "Name of the IAM role assigned to all tasks run under this task definition" | ||
value = aws_iam_role.task_role.name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = ">=5.7.0" | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
resource-groups/dmp-ecs-fargate-task-definition/task_role.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
resource "aws_iam_role" "task_role" { | ||
name = "${var.family_name}-ecs-task" | ||
description = "Role to be assumed by the ${var.family_name} tasks during general operation" | ||
|
||
assume_role_policy = jsonencode({ | ||
Version = "2012-10-17" | ||
Statement = [ | ||
{ | ||
Action = "sts:AssumeRole" | ||
Effect = "Allow" | ||
Principal = { | ||
Service = "ecs-tasks.amazonaws.com" | ||
} | ||
Condition = { | ||
ArnLike = { | ||
"aws:SourceArn" = "arn:aws:ecs:${var.aws_region}:${var.aws_account_id}:*" | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
} | ||
|
||
|
||
data "aws_iam_policy_document" "pass_task_role" { | ||
version = "2012-10-17" | ||
|
||
statement { | ||
sid = "Pass${replace(var.family_name, "/[-_]/", "")}TaskRole" | ||
actions = [ | ||
"iam:GetRole", | ||
"iam:PassRole" | ||
] | ||
effect = "Allow" | ||
resources = [ | ||
aws_iam_role.task_role.arn | ||
] | ||
} | ||
depends_on = [ | ||
aws_iam_role.task_role | ||
] | ||
} |
76 changes: 76 additions & 0 deletions
76
resource-groups/dmp-ecs-fargate-task-definition/variables.tf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
variable "aws_account_id" { | ||
type = string | ||
description = "ID of the account into which deployments are performed" | ||
} | ||
|
||
variable "aws_region" { | ||
type = string | ||
description = "Region for resource deployment" | ||
} | ||
|
||
variable "container_definitions" { | ||
type = map(object({ | ||
# CPU to allocate to the container (where a value of 1024 == 1vCPU) | ||
cpu = number | ||
# Environment variables to be made available to the container | ||
environment_variables = list(map(string)) | ||
# Indicates whether or not the container is essential to the task | ||
essential = bool | ||
# Command to run within container to verify process health | ||
healthcheck_command = string | ||
# Canonical Docker image name - OR - URL of the image repo | ||
image = string | ||
# Full name of an existing CloudWatch Log Group for the container | ||
log_group_name = string | ||
# Memory to allocate to the container (where a value of 1024 == 1GB) | ||
memory = number | ||
# List of config value objects for volumes to be mounted from the container | ||
mounts = list(object({ | ||
mount_point = string | ||
read_only = bool | ||
volume_name = string | ||
})) | ||
# Startup command to override that which is specified in the original Dockerfile of the container | ||
override_command = list(string) | ||
# Port to which the container expects to bind its listener | ||
port = number | ||
# Environment variables to be looked up as secrets and then made available to the container | ||
secret_environment_variables = list(map(string)) | ||
})) | ||
} | ||
|
||
variable "ecs_execution_role_arn" { | ||
type = string | ||
description = "ARN of the role which is assumed by the ECS execution processes" | ||
} | ||
|
||
variable "family_name" { | ||
type = string | ||
description = "The name to give to the task definition, across all revisions" | ||
} | ||
|
||
variable "override_entrypoints" { | ||
type = map(list(string)) | ||
description = "Forced override of entrypoint for the container" | ||
default = {} | ||
} | ||
|
||
variable "task_cpu" { | ||
type = number | ||
description = "CPU to allocate to each task (where a value of 1024 == 1vCPU) - Must be >= total of all containers' CPU" | ||
} | ||
|
||
variable "task_memory" { | ||
type = number | ||
description = "Memory to allocate to each task (where a value of 1024 == 1GB) - Must be >= total of all containers' memory" | ||
} | ||
|
||
variable "volumes" { | ||
type = list(object({ | ||
access_point_id = string | ||
file_system_id = string | ||
volume_name = string | ||
})) | ||
description = "List of volumes made available to the task's container(s)" | ||
default = [] | ||
} |