Skip to content

Shorter naming for environment variables #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
33 changes: 33 additions & 0 deletions ecr.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "aws_ecr_repository" "service" {
count = var.ecr_create_repo ? 1 : 0
name = var.ecr_repo_name

image_scanning_configuration {
scan_on_push = var.ecr_scan_on_push
}
}

resource "aws_ecr_lifecycle_policy" "service" {
count = var.ecr_create_repo ? 1 : 0
repository = aws_ecr_repository.service[0].name

policy = <<EOF
{
"rules": [
{
"rulePriority": 1,
"description": "Expire images older than ${var.ecr_repo_remove_untagged_days} days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": ${var.ecr_repo_remove_untagged_days}
},
"action": {
"type": "expire"
}
}
]
}
EOF
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
output "container_definitions" {
value = "${module.merged.container_definitions}"
value = module.merged.container_definitions
}
113 changes: 71 additions & 42 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
# - 2. https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html
# - 3. https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_PortMapping.html
# - 4. https://github.com/hashicorp/terraform/issues/17033
data "aws_region" "current" {}

locals {
command = jsonencode(var.command)
Expand All @@ -36,9 +37,9 @@ locals {
dockerLabels = jsonencode(var.dockerLabels)
dockerSecurityOptions = jsonencode(var.dockerSecurityOptions)
entryPoint = jsonencode(var.entryPoint)
environment = jsonencode(var.environment)
extraHosts = jsonencode(var.extraHosts)

environment = jsonencode(var.environment != {} ? [for k, v in var.environment : { "name" : k, "value" : v }] : [])
healthCheck = replace(jsonencode(var.healthCheck), local.classes["digit"], "$1")

links = jsonencode(var.links)
Expand All @@ -53,7 +54,16 @@ locals {
"$1",
)

logConfiguration = jsonencode(var.logConfiguration)
cloudwatch_log_group_name = "/${var.cloudwatch_log_group_prefix}/ecs/${var.name}"

logConfiguration = var.enable_cloudwatch ? jsonencode({
logDriver = "awslogs"
options = {
awslogs-group = local.cloudwatch_log_group_name
awslogs-region = data.aws_region.current.name
awslogs-stream-prefix = "ecs"
}
}) : jsonencode(var.logConfiguration)

mountPoints = replace(
replace(jsonencode(var.mountPoints), "/\"1\"/", "true"),
Expand Down Expand Up @@ -82,50 +92,58 @@ locals {
digit = "/\"(-[[:digit:]]|[[:digit:]]+)\"/"
}

container_definition = var.register_task_definition ? format("[%s]", data.template_file.container_definition.rendered) : format("%s", data.template_file.container_definition.rendered)
image = var.ecr_create_repo ? "${aws_ecr_repository.service[0].repository_url}:${var.ecr_task_definition_tag}" : var.image

template_file = templatefile(
"${path.module}/templates/container-definition.json.tpl",
{
command = local.command == "[]" ? "null" : local.command
cpu = var.cpu == 0 ? "null" : var.cpu
disableNetworking = var.disableNetworking ? true : false
dnsSearchDomains = local.dnsSearchDomains == "[]" ? "null" : local.dnsSearchDomains
dnsServers = local.dnsServers == "[]" ? "null" : local.dnsServers
dockerLabels = local.dockerLabels == "{}" ? "null" : local.dockerLabels
dockerSecurityOptions = local.dockerSecurityOptions == "[]" ? "null" : local.dockerSecurityOptions
entryPoint = local.entryPoint == "[]" ? "null" : local.entryPoint
environment = local.environment == "[]" ? "null" : local.environment
essential = var.essential ? true : false
extraHosts = local.extraHosts == "[]" ? "null" : local.extraHosts
healthCheck = local.healthCheck == "{}" ? "null" : local.healthCheck
hostname = var.hostname == "" ? "null" : var.hostname
image = local.image
interactive = var.interactive ? true : false
links = local.links == "[]" ? "null" : local.links
linuxParameters = local.linuxParameters == "{}" ? "null" : local.linuxParameters
logConfiguration = local.logConfiguration == "{}" ? "null" : local.logConfiguration
memory = var.memory == 0 ? "null" : var.memory
memoryReservation = var.memoryReservation == 0 ? "null" : var.memoryReservation
mountPoints = local.mountPoints == "[]" ? "null" : local.mountPoints
name = var.name == "" ? "null" : var.name
portMappings = local.portMappings == "[]" ? "null" : local.portMappings
privileged = var.privileged ? true : false
pseudoTerminal = var.pseudoTerminal ? true : false
readonlyRootFilesystem = var.readonlyRootFilesystem ? true : false
repositoryCredentials = local.repositoryCredentials == "{}" ? "null" : local.repositoryCredentials
resourceRequirements = local.resourceRequirements == "[]" ? "null" : local.resourceRequirements
secrets = local.secrets == "[]" ? "null" : local.secrets
systemControls = local.systemControls == "[]" ? "null" : local.systemControls
ulimits = local.ulimits == "[]" ? "null" : local.ulimits
user = var.user == "" ? "null" : var.user
volumesFrom = local.volumesFrom == "[]" ? "null" : local.volumesFrom
workingDirectory = var.workingDirectory == "" ? "null" : var.workingDirectory
}
)

container_definition = var.register_task_definition ? format("[%s]", local.template_file) : format("%s", local.template_file)

container_definitions = replace(local.container_definition, "/\"(null)\"/", "$1")
}

data "template_file" "container_definition" {
template = file("${path.module}/templates/container-definition.json.tpl")

vars = {
command = local.command == "[]" ? "null" : local.command
cpu = var.cpu == 0 ? "null" : var.cpu
disableNetworking = var.disableNetworking ? true : false
dnsSearchDomains = local.dnsSearchDomains == "[]" ? "null" : local.dnsSearchDomains
dnsServers = local.dnsServers == "[]" ? "null" : local.dnsServers
dockerLabels = local.dockerLabels == "{}" ? "null" : local.dockerLabels
dockerSecurityOptions = local.dockerSecurityOptions == "[]" ? "null" : local.dockerSecurityOptions
entryPoint = local.entryPoint == "[]" ? "null" : local.entryPoint
environment = local.environment == "[]" ? "null" : local.environment
essential = var.essential ? true : false
extraHosts = local.extraHosts == "[]" ? "null" : local.extraHosts
healthCheck = local.healthCheck == "{}" ? "null" : local.healthCheck
hostname = var.hostname == "" ? "null" : var.hostname
image = var.image == "" ? "null" : var.image
interactive = var.interactive ? true : false
links = local.links == "[]" ? "null" : local.links
linuxParameters = local.linuxParameters == "{}" ? "null" : local.linuxParameters
logConfiguration = local.logConfiguration == "{}" ? "null" : local.logConfiguration
memory = var.memory == 0 ? "null" : var.memory
memoryReservation = var.memoryReservation == 0 ? "null" : var.memoryReservation
mountPoints = local.mountPoints == "[]" ? "null" : local.mountPoints
name = var.name == "" ? "null" : var.name
portMappings = local.portMappings == "[]" ? "null" : local.portMappings
privileged = var.privileged ? true : false
pseudoTerminal = var.pseudoTerminal ? true : false
readonlyRootFilesystem = var.readonlyRootFilesystem ? true : false
repositoryCredentials = local.repositoryCredentials == "{}" ? "null" : local.repositoryCredentials
resourceRequirements = local.resourceRequirements == "[]" ? "null" : local.resourceRequirements
secrets = local.secrets == "[]" ? "null" : local.secrets
systemControls = local.systemControls == "[]" ? "null" : local.systemControls
ulimits = local.ulimits == "[]" ? "null" : local.ulimits
user = var.user == "" ? "null" : var.user
volumesFrom = local.volumesFrom == "[]" ? "null" : local.volumesFrom
workingDirectory = var.workingDirectory == "" ? "null" : var.workingDirectory
}
resource "aws_cloudwatch_log_group" "ecs_task_definition" {
count = var.enable_cloudwatch == true ? 1 : 0

name = "/${var.cloudwatch_log_group_prefix}/ecs/${var.name}"
retention_in_days = var.cloudwatch_log_retention_in_days
}

resource "aws_ecs_task_definition" "ecs_task_definition" {
Expand All @@ -136,6 +154,8 @@ resource "aws_ecs_task_definition" "ecs_task_definition" {
network_mode = var.network_mode
pid_mode = var.pid_mode

track_latest = var.track_latest

# Fargate requires cpu and memory to be defined at the task level
cpu = var.cpu
memory = var.memory
Expand Down Expand Up @@ -184,6 +204,15 @@ resource "aws_ecs_task_definition" "ecs_task_definition" {
}
}
}

dynamic "runtime_platform" {
for_each = var.runtime_platform != null ? [var.runtime_platform] : []
content {
cpu_architecture = upper(runtime_platform.value.cpu_architecture)
operating_system_family = upper(runtime_platform.value.operating_system_family)
}
}

tags = var.tags

count = var.register_task_definition ? 1 : 0
Expand Down
3 changes: 3 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ output "revision" {
value = join("", aws_ecs_task_definition.ecs_task_definition.*.revision)
}

output "ecr_repo_name" {
value = var.ecr_create_repo == true ? aws_ecr_repository.service[0].name : null
}
9 changes: 3 additions & 6 deletions test/varfile.tfvars
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
environment = [
{
name = "AWS_DEFAULT_REGION"
value = "us-east-1"
},
]
environment = {
"AWS_DEFAULT_REGION" = "us-east-1"
}

family = "default"

Expand Down
79 changes: 73 additions & 6 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ variable "entryPoint" {
}

variable "environment" {
default = []
default = {}
description = "The environment variables to pass to a container"
type = list(map(string))
type = map(string)
}

variable "essential" {
Expand Down Expand Up @@ -90,7 +90,7 @@ variable "hostname" {
}

variable "image" {
default = ""
default = "null"
description = "The image used to start a container"
}

Expand Down Expand Up @@ -145,7 +145,7 @@ variable "name" {
}

variable "network_mode" {
default = "bridge"
default = "awsvpc"
description = "The Docker networking mode to use for the containers in the task"
}

Expand All @@ -164,7 +164,7 @@ variable "placement_constraints" {
}

variable "portMappings" {
default = []
default = [{ containerPort = 80 }]
description = "The list of port mappings for the container"
type = list(any)
}
Expand Down Expand Up @@ -196,7 +196,7 @@ variable "repositoryCredentials" {
}

variable "requires_compatibilities" {
default = []
default = ["FARGATE"]
description = "The launch type required by the task"
type = list(string)
}
Expand Down Expand Up @@ -261,3 +261,70 @@ variable "workingDirectory" {
default = ""
description = "The working directory in which to run commands inside the container"
}

variable "runtime_platform" {
type = object({
cpu_architecture = string
operating_system_family = string
})
nullable = true
description = "The runtime platform"
default = {
cpu_architecture = "X86_64"
operating_system_family = "LINUX"
}
}

variable "track_latest" {
type = bool
default = false
description = "Whether should track latest ACTIVE task definition on AWS or the one created with the resource stored in state. Default is false. Useful in the event the task definition is modified outside of this resource."
}


variable "ecr_create_repo" {
type = bool
default = false
description = "Enable ECR repository creation"
}

variable "ecr_scan_on_push" {
type = bool
default = false
description = "Enable ECR repository scanning on push"
}

variable "ecr_repo_name" {
type = string
description = "Name of the ECR repository"
}

variable "ecr_repo_remove_untagged_days" {
type = number
default = 7
description = "Number of days to keep untagged images"
}

variable "ecr_task_definition_tag" {
type = string
default = "latest"
description = "Tag to use for the ECR task definition"
}

variable "enable_cloudwatch" {
type = bool
default = false
description = "Whether to enable CloudWatch logging if false, the value of variable `logConfiguration` will be used"
}

variable "cloudwatch_log_group_prefix" {
type = string
default = ""
description = "The prefix for the CloudWatch log group name eg: /project/environment/app"
}

variable "cloudwatch_log_retention_in_days" {
type = number
default = 30
description = "The number of days to retain the CloudWatch log group"
}