Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/container-definition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ Note that this example may create resources which will incur monetary charges on
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ecs_container_definition"></a> [ecs\_container\_definition](#module\_ecs\_container\_definition) | ../../modules/container-definition | n/a |
| <a name="module_ecs_container_definition_simple"></a> [ecs\_container\_definition\_simple](#module\_ecs\_container\_definition\_simple) | ../../modules/container-definition | n/a |

## Resources

| Name | Type |
|------|------|
| [null_resource.container_definition_json](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [null_resource.container_definition_json_simple](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |

## Inputs

Expand All @@ -57,6 +59,8 @@ Note that this example may create resources which will incur monetary charges on
| <a name="output_cloudwatch_log_group_name"></a> [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of CloudWatch log group created |
| <a name="output_container_definition"></a> [container\_definition](#output\_container\_definition) | Container definition |
| <a name="output_container_definition_json"></a> [container\_definition\_json](#output\_container\_definition\_json) | Container definition |
| <a name="output_container_definition_json_simple"></a> [container\_definition\_json\_simple](#output\_container\_definition\_json\_simple) | Container definition |
| <a name="output_container_definition_simple"></a> [container\_definition\_simple](#output\_container\_definition\_simple) | Container definition |
<!-- END_TF_DOCS -->

## License
Expand Down
32 changes: 32 additions & 0 deletions examples/container-definition/definition_simple.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"cpu": 256,
"essential": true,
"image": "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50",
"interactive": false,
"linuxParameters": {
"initProcessEnabled": false
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/aws/ecs",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "ecs"
}
},
"memory": 512,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"name": "app",
"protocol": "tcp"
}
],
"privileged": false,
"pseudoTerminal": false,
"readonlyRootFilesystem": false,
"startTimeout": 30,
"stopTimeout": 120,
"versionConsistency": "disabled"
}
21 changes: 21 additions & 0 deletions examples/container-definition/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,24 @@ module "ecs_container_definition" {

tags = local.tags
}

module "ecs_container_definition_simple" {
source = "../../modules/container-definition"

image = "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50"
cpu = 256
memory = 512
essential = true
readonlyRootFilesystem = false
portMappings = [{
name = "app"
protocol = "tcp"
containerPort = 80
hostPort = 80
}]
restartPolicy = {
enabled = false
}

tags = local.tags
}
23 changes: 23 additions & 0 deletions examples/container-definition/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,29 @@ resource "null_resource" "container_definition_json" {
}
}

output "container_definition_simple" {
description = "Container definition"
value = module.ecs_container_definition.container_definition
}

output "container_definition_json_simple" {
description = "Container definition"
value = module.ecs_container_definition.container_definition_json
}

resource "null_resource" "container_definition_json_simple" {
count = var.write_container_definition_to_file ? 1 : 0

triggers = {
container_definition_json = timestamp()
}

provisioner "local-exec" {
# Need the output pretty-printed and sorted for comparison
command = "echo '${module.ecs_container_definition_simple.container_definition_json}' | jq -S > ./definition_simple.json"
}
}

################################################################################
# CloudWatch Log Group
################################################################################
Expand Down
14 changes: 7 additions & 7 deletions modules/container-definition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ No modules.
| <a name="input_dockerSecurityOptions"></a> [dockerSecurityOptions](#input\_dockerSecurityOptions) | A list of strings to provide custom labels for SELinux and AppArmor multi-level security systems. This field isn't valid for containers in tasks using the Fargate launch type | `list(string)` | `null` | no |
| <a name="input_enable_cloudwatch_logging"></a> [enable\_cloudwatch\_logging](#input\_enable\_cloudwatch\_logging) | Determines whether CloudWatch logging is configured for this container definition. Set to `false` to use other logging drivers | `bool` | `true` | no |
| <a name="input_enable_execute_command"></a> [enable\_execute\_command](#input\_enable\_execute\_command) | Specifies whether to enable Amazon ECS Exec for the tasks within the service | `bool` | `false` | no |
| <a name="input_entrypoint"></a> [entrypoint](#input\_entrypoint) | The entry point that is passed to the container | `list(string)` | `[]` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment variables to pass to the container | <pre>list(object({<br/> name = string<br/> value = string<br/> }))</pre> | `[]` | no |
| <a name="input_environmentFiles"></a> [environmentFiles](#input\_environmentFiles) | A list of files containing the environment variables to pass to a container | <pre>list(object({<br/> value = string<br/> type = string<br/> }))</pre> | `[]` | no |
| <a name="input_entrypoint"></a> [entrypoint](#input\_entrypoint) | The entry point that is passed to the container | `list(string)` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment variables to pass to the container | <pre>list(object({<br/> name = string<br/> value = string<br/> }))</pre> | `null` | no |
| <a name="input_environmentFiles"></a> [environmentFiles](#input\_environmentFiles) | A list of files containing the environment variables to pass to a container | <pre>list(object({<br/> value = string<br/> type = string<br/> }))</pre> | `null` | no |
| <a name="input_essential"></a> [essential](#input\_essential) | If the `essential` parameter of a container is marked as `true`, and that container fails or stops for any reason, all other containers that are part of the task are stopped | `bool` | `null` | no |
| <a name="input_extraHosts"></a> [extraHosts](#input\_extraHosts) | A list of hostnames and IP address mappings to append to the `/etc/hosts` file on the container | <pre>list(object({<br/> hostname = string<br/> ipAddress = string<br/> }))</pre> | `null` | no |
| <a name="input_firelensConfiguration"></a> [firelensConfiguration](#input\_firelensConfiguration) | The FireLens configuration for the container. This is used to specify and configure a log router for container logs. For more information, see [Custom Log Routing](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_firelens.html) in the Amazon Elastic Container Service Developer Guide | <pre>object({<br/> options = optional(map(string))<br/> type = optional(string)<br/> })</pre> | `null` | no |
Expand All @@ -170,7 +170,7 @@ No modules.
| <a name="input_logConfiguration"></a> [logConfiguration](#input\_logConfiguration) | The log configuration for the container. For more information see [LogConfiguration](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_LogConfiguration.html) | <pre>object({<br/> logDriver = optional(string)<br/> options = optional(map(string))<br/> secretOptions = optional(list(object({<br/> name = string<br/> valueFrom = string<br/> })))<br/> })</pre> | `{}` | no |
| <a name="input_memory"></a> [memory](#input\_memory) | The amount (in MiB) of memory to present to the container. If your container attempts to exceed the memory specified here, the container is killed. The total amount of memory reserved for all containers within a task must be lower than the task `memory` value, if one is specified | `number` | `null` | no |
| <a name="input_memoryReservation"></a> [memoryReservation](#input\_memoryReservation) | The soft limit (in MiB) of memory to reserve for the container. When system memory is under heavy contention, Docker attempts to keep the container memory to this soft limit. However, your container can consume more memory when it needs to, up to either the hard limit specified with the `memory` parameter (if applicable), or all of the available memory on the container instance | `number` | `null` | no |
| <a name="input_mountPoints"></a> [mountPoints](#input\_mountPoints) | The mount points for data volumes in your container | <pre>list(object({<br/> containerPath = optional(string)<br/> readOnly = optional(bool)<br/> sourceVolume = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_mountPoints"></a> [mountPoints](#input\_mountPoints) | The mount points for data volumes in your container | <pre>list(object({<br/> containerPath = optional(string)<br/> readOnly = optional(bool)<br/> sourceVolume = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | The name of a container. If you're linking multiple containers together in a task definition, the name of one container can be entered in the links of another container to connect the containers. Up to 255 letters (uppercase and lowercase), numbers, underscores, and hyphens are allowed | `string` | `null` | no |
| <a name="input_operating_system_family"></a> [operating\_system\_family](#input\_operating\_system\_family) | The OS family for task | `string` | `"LINUX"` | no |
| <a name="input_portMappings"></a> [portMappings](#input\_portMappings) | The list of port mappings for the container. Port mappings allow containers to access ports on the host container instance to send or receive traffic. For task definitions that use the awsvpc network mode, only specify the containerPort. The hostPort can be left blank or it must be the same value as the containerPort | <pre>list(object({<br/> appProtocol = optional(string)<br/> containerPort = optional(number)<br/> containerPortRange = optional(string)<br/> hostPort = optional(number)<br/> name = optional(string)<br/> protocol = optional(string)<br/> }))</pre> | `null` | no |
Expand All @@ -180,17 +180,17 @@ No modules.
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
| <a name="input_repositoryCredentials"></a> [repositoryCredentials](#input\_repositoryCredentials) | Container repository credentials; required when using a private repo. This map currently supports a single key; "credentialsParameter", which should be the ARN of a Secrets Manager's secret holding the credentials | <pre>object({<br/> credentialsParameter = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_resourceRequirements"></a> [resourceRequirements](#input\_resourceRequirements) | The type and amount of a resource to assign to a container. The only supported resource is a GPU | <pre>list(object({<br/> type = string<br/> value = string<br/> }))</pre> | `null` | no |
| <a name="input_restartPolicy"></a> [restartPolicy](#input\_restartPolicy) | Container restart policy; helps overcome transient failures faster and maintain task availability | <pre>object({<br/> enabled = optional(bool)<br/> ignoredExitCodes = optional(list(number))<br/> restartAttemptPeriod = optional(number)<br/> })</pre> | <pre>{<br/> "enabled": true<br/>}</pre> | no |
| <a name="input_restartPolicy"></a> [restartPolicy](#input\_restartPolicy) | Container restart policy; helps overcome transient failures faster and maintain task availability | <pre>object({<br/> enabled = optional(bool, true)<br/> ignoredExitCodes = optional(list(number))<br/> restartAttemptPeriod = optional(number)<br/> })</pre> | <pre>{<br/> "enabled": true<br/>}</pre> | no |
| <a name="input_secrets"></a> [secrets](#input\_secrets) | The secrets to pass to the container. For more information, see [Specifying Sensitive Data](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html) in the Amazon Elastic Container Service Developer Guide | <pre>list(object({<br/> name = string<br/> valueFrom = string<br/> }))</pre> | `null` | no |
| <a name="input_service"></a> [service](#input\_service) | The name of the service that the container definition is associated with. Used in CloudWatch log group default name (if one is not provided) | `string` | `null` | no |
| <a name="input_startTimeout"></a> [startTimeout](#input\_startTimeout) | Time duration (in seconds) to wait before giving up on resolving dependencies for a container | `number` | `30` | no |
| <a name="input_stopTimeout"></a> [stopTimeout](#input\_stopTimeout) | Time duration (in seconds) to wait before the container is forcefully killed if it doesn't exit normally on its own | `number` | `120` | no |
| <a name="input_systemControls"></a> [systemControls](#input\_systemControls) | A list of namespaced kernel parameters to set in the container | <pre>list(object({<br/> namespace = optional(string)<br/> value = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_systemControls"></a> [systemControls](#input\_systemControls) | A list of namespaced kernel parameters to set in the container | <pre>list(object({<br/> namespace = optional(string)<br/> value = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources | `map(string)` | `{}` | no |
| <a name="input_ulimits"></a> [ulimits](#input\_ulimits) | A list of ulimits to set in the container. If a ulimit value is specified in a task definition, it overrides the default values set by Docker | <pre>list(object({<br/> hardLimit = number<br/> name = string<br/> softLimit = number<br/> }))</pre> | `null` | no |
| <a name="input_user"></a> [user](#input\_user) | The user to run as inside the container. Can be any of these formats: user, user:group, uid, uid:gid, user:gid, uid:group. The default (null) will use the container's configured `USER` directive or root if not set | `string` | `null` | no |
| <a name="input_versionConsistency"></a> [versionConsistency](#input\_versionConsistency) | Specifies whether Amazon ECS will resolve the container image tag provided in the container definition to an image digest | `string` | `"disabled"` | no |
| <a name="input_volumesFrom"></a> [volumesFrom](#input\_volumesFrom) | Data volumes to mount from another container | <pre>list(object({<br/> readOnly = optional(bool)<br/> sourceContainer = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_volumesFrom"></a> [volumesFrom](#input\_volumesFrom) | Data volumes to mount from another container | <pre>list(object({<br/> readOnly = optional(bool)<br/> sourceContainer = optional(string)<br/> }))</pre> | `null` | no |
| <a name="input_workingDirectory"></a> [workingDirectory](#input\_workingDirectory) | The working directory to run commands inside the container | `string` | `null` | no |

## Outputs
Expand Down
17 changes: 10 additions & 7 deletions modules/container-definition/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ locals {
# tflint-ignore: terraform_naming_convention
linuxParameters = var.enable_execute_command ? merge(local.trimedLinuxParameters, { "initProcessEnabled" : true }) : merge({ "initProcessEnabled" : false }, local.trimedLinuxParameters)

# tflint-ignore: terraform_naming_convention
trimmedRestartPolicy = { for k, v in var.restartPolicy : k => v if v != null }

definition = {
command = var.command
cpu = var.cpu
Expand All @@ -42,9 +45,9 @@ locals {
dnsServers = local.is_not_windows ? var.dnsServers : null
dockerLabels = var.dockerLabels
dockerSecurityOptions = var.dockerSecurityOptions
entrypoint = var.entrypoint
environment = var.environment
environmentFiles = var.environmentFiles
entrypoint = var.entrypoint != null ? var.entrypoint : null
environment = var.environment != null ? var.environment : null
environmentFiles = var.environmentFiles != null ? var.environmentFiles : null
essential = var.essential
extraHosts = local.is_not_windows ? var.extraHosts : null
firelensConfiguration = var.firelensConfiguration != null ? { for k, v in var.firelensConfiguration : k => v if v != null } : null
Expand All @@ -57,23 +60,23 @@ locals {
logConfiguration = length(local.logConfiguration) > 0 ? local.logConfiguration : null
memory = var.memory
memoryReservation = var.memoryReservation
mountPoints = var.mountPoints
mountPoints = var.mountPoints != null ? var.mountPoints : null
name = var.name
portMappings = var.portMappings != null ? [for p in var.portMappings : { for k, v in p : k => v if v != null }] : null
privileged = local.is_not_windows ? var.privileged : null
pseudoTerminal = var.pseudoTerminal
readonlyRootFilesystem = local.is_not_windows ? var.readonlyRootFilesystem : null
repositoryCredentials = var.repositoryCredentials
resourceRequirements = var.resourceRequirements
restartPolicy = { for k, v in var.restartPolicy : k => v if v != null }
restartPolicy = local.trimmedRestartPolicy.enabled ? local.trimmedRestartPolicy : null
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if enabled = false then we don't send any configs for restartPolicy to the Task Definition API call

secrets = var.secrets
startTimeout = var.startTimeout
stopTimeout = var.stopTimeout
systemControls = var.systemControls
systemControls = var.systemControls != null ? var.systemControls : null
ulimits = local.is_not_windows ? var.ulimits : null
user = local.is_not_windows ? var.user : null
versionConsistency = var.versionConsistency
volumesFrom = var.volumesFrom
volumesFrom = var.volumesFrom != null ? var.volumesFrom : null
workingDirectory = var.workingDirectory
}

Expand Down
21 changes: 8 additions & 13 deletions modules/container-definition/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ variable "enable_execute_command" {
variable "entrypoint" {
description = "The entry point that is passed to the container"
type = list(string)
default = []
nullable = false
default = null
}

variable "environment" {
Expand All @@ -99,8 +98,7 @@ variable "environment" {
name = string
value = string
}))
default = []
nullable = false
default = null
}

# tflint-ignore: terraform_naming_convention
Expand All @@ -110,8 +108,7 @@ variable "environmentFiles" {
value = string
type = string
}))
default = []
nullable = false
default = null
}

variable "essential" {
Expand Down Expand Up @@ -241,8 +238,7 @@ variable "mountPoints" {
readOnly = optional(bool)
sourceVolume = optional(string)
}))
default = []
nullable = false
default = null
}

variable "name" {
Expand Down Expand Up @@ -311,13 +307,14 @@ variable "resourceRequirements" {
variable "restartPolicy" {
description = "Container restart policy; helps overcome transient failures faster and maintain task availability"
type = object({
enabled = optional(bool)
enabled = optional(bool, true)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignoredExitCodes = optional(list(number))
restartAttemptPeriod = optional(number)
})
default = {
enabled = true
}
nullable = false
}

variable "secrets" {
Expand Down Expand Up @@ -350,8 +347,7 @@ variable "systemControls" {
namespace = optional(string)
value = optional(string)
}))
default = []
nullable = false
default = null
}

variable "ulimits" {
Expand Down Expand Up @@ -385,8 +381,7 @@ variable "volumesFrom" {
readOnly = optional(bool)
sourceContainer = optional(string)
}))
default = []
nullable = false
default = null
}

# tflint-ignore: terraform_naming_convention
Expand Down
Loading