cloudposse / terraform-aws-ecs-container-definition

Terraform module to generate well-formed JSON documents (container definitions) that are passed to the aws_ecs_task_definition Terraform resource
https://cloudposse.com/accelerate
Apache License 2.0
339 stars 244 forks source link

CPU limit is not optional #150

Closed aairey closed 2 years ago

aairey commented 2 years ago

The variable defaults to 0, but it is allowed to leave it unset.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition#cpu https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

IMHO, we should allow to pass null to this module.


Error: Invalid value for module argument

  on main.tf line 33, in module "container-definition":
  33:   container_cpu                = var.container-cpu

The given value is not suitable for child module variable "container_cpu"
defined at .terraform/modules/container-definition/variables.tf:54,1-25: a
number is required.```
korenyoni commented 2 years ago

@aairey How are you producing this?

I've supplied null to container_cpu in fixtures.us-east-2.tfvars in examples/complete and can produce a clean plan:

region = "us-east-2"

namespace = "eg"

stage = "test"

name = "container-definition"

container_name               = "app"
container_image              = "cloudposse/geodesic"
container_memory             = 256
container_memory_reservation = 128
#container_cpu                = 256
container_cpu                = null
essential                    = true
readonly_root_filesystem     = false

container_environment = [
  {
    name  = "string_var"
    value = "I am a string"
  },
  {
    name  = "true_boolean_var"
    value = true
  },
  {
    name  = "false_boolean_var"
    value = false
  },
  {
    name  = "integer_var"
    value = 42
  }
]

port_mappings = [
  {
    containerPort = 8080
    hostPort      = 80
    protocol      = "tcp"
  },
  {
    containerPort = 8081
    hostPort      = 443
    protocol      = "udp"
  }
]

log_configuration = {
  logDriver = "json-file"
  options = {
    "max-size" = "10m"
    "max-file" = "3"
  }
  secretOptions = null
}

privileged = false

extra_hosts = [{
  ipAddress = "127.0.0.1"
  hostname  = "app.local"
  },
]

hostname        = "hostname"
pseudo_terminal = true
interactive     = true

Terraform 0.13.7

examples/complete $ terraform plan -var-file fixtures.us-east-2.tfvars ```hcl Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_ecs_task_definition.task will be created + resource "aws_ecs_task_definition" "task" { + arn = (known after apply) + container_definitions = jsonencode( [ + { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] }, ] ) + family = "eg-test-container-definition" + id = (known after apply) + network_mode = (known after apply) + revision = (known after apply) + skip_destroy = false + tags = { + "Name" = "eg-test-container-definition" + "Namespace" = "eg" + "Stage" = "test" } + tags_all = { + "Name" = "eg-test-container-definition" + "Namespace" = "eg" + "Stage" = "test" } } Plan: 1 to add, 0 to change, 0 to destroy. Changes to Outputs: + json_map_encoded = jsonencode( { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] } ) + json_map_encoded_list = jsonencode( [ + { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] }, ] ) + json_map_object = { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] } + task_definition_container_definition = { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] } ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. ```

Terraform 1.1.2

examples/complete $ terraform plan -var-file fixtures.us-east-2.tfvars ```hcl Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_ecs_task_definition.task will be created + resource "aws_ecs_task_definition" "task" { + arn = (known after apply) + container_definitions = jsonencode( [ + { + environment = [ + { + name = "false_boolean_var" + value = "false" }, + { + name = "integer_var" + value = "42" }, + { + name = "string_var" + value = "I am a string" }, + { + name = "true_boolean_var" + value = "true" }, ] + essential = true + extraHosts = [ + { + hostname = "app.local" + ipAddress = "127.0.0.1" }, ] + hostname = "hostname" + image = "cloudposse/geodesic" + interactive = true + logConfiguration = { + logDriver = "json-file" + options = { + max-file = "3" + max-size = "10m" } } + memory = 256 + memoryReservation = 128 + mountPoints = [] + name = "app" + portMappings = [ + { + containerPort = 8080 + hostPort = 80 + protocol = "tcp" }, + { + containerPort = 8081 + hostPort = 443 + protocol = "udp" }, ] + privileged = false + pseudoTerminal = true + readonlyRootFilesystem = false + volumesFrom = [] }, ] ) + family = "eg-test-container-definition" + id = (known after apply) + network_mode = (known after apply) + revision = (known after apply) + skip_destroy = false + tags = { + "Name" = "eg-test-container-definition" + "Namespace" = "eg" + "Stage" = "test" } + tags_all = { + "Name" = "eg-test-container-definition" + "Namespace" = "eg" + "Stage" = "test" } } Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run. ```

That additional information that's useful for bug reports such as these is included in our issue template... looks like you didn't use it.