0

I've set the following via Terraform:

Task-definition level:

network_mode = "bridge"

Container level:

portMappings = [
  {
    hostPort = 0,    
    containerPort = 8080
  }
]

Terraform will check state and ask me to confirm, but then fail:

Error: port should be set when target type is instance

This structure seems to be the general theme of all of the dozens of subtly-conflicting recommendations on Google.

It's not even clear where/how/if I am expected to provide containerPortRange. It doesn't seem necessary, seems often not mentioned, but seems like it'd be a great idea. That said, based on the naming ("container" vs "host"), it seems like it's supposed to represent the port on the container and this seems like the one place that it really shouldn't matter. Some clarification on this would be appreciated.

Note that there's a chance that "awsvpc" should work just as well as "bridge":

(https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definitions)

enter image description here

However, when I use "awsvpc", I get both the above error as well as this one (two separate paragraphs):

Error: creating ECS Task Definition (sellback-website-staging): ClientException: When networkMode=awsvpc, the host ports and container ports in port mappings must match.

I've lost so much time on this one thing over all of the times that I've tried to accomplish it that it's pretty frustrating. I'm having to maintain a wasteful number of EC2 instances to compensate.

If someone could even provide an example of doing this via Terraform as a form of documentation, it might squash almost all questions at once.

1 Answer 1

0

From what I can find in GitHub Code Search, it seems like older versions of the AWS provider returned that error during the apply phase for a new aws_lb_target_group whenever its top-level port attribute wasn't set, unless the target type is "lambda".

Newer versions of the provider check for this situation during the planning phase instead, but return the same error:

    if v := config.GetAttr(names.AttrPort); v.IsKnown() && v.IsNull() {
        return sdkdiag.DiagnosticError(errs.NewAttributeRequiredWhenError(
            cty.GetAttrPath(names.AttrPort),
            cty.GetAttrPath("target_type"),
            targetType,
        ))
    }

This suggests to me that you have an aws_lb_target_group resource in your configuration and it has target_type = "instance" but does not specify the port argument. The only target type that doesn't require a port is "lambda".

My knowledge of ECS in particular is limited, but based on my rough mental model of how it works I expect you'd need to set port to match whatever "host port" is selected, so that the load balancer will forward connections to the host's listen port and then the software on that host will in turn forward the request into your container.

Since you are setting hostPort to zero that means the host port is selected randomly from the ephemeral port range and so cannot be predicted statically. Therefore it seems like you'll need to find some way to determine the randomly-selected port number and assign it to the port argument in your aws_lb_target_group resource, but I'm afraid that part is beyond my knowledge.

2
  • Yours, and seemingly everyone's. That's the second act of the same magic trick. Neither "target_type" nor "instance" appear anywhere within our Terraform modules. Lambda is also certainly not deployed via our Terraform modules. Commented Jun 29 at 1:49
  • According to the code for this resource type, target_type defaults to "instance" if you don't set it. Commented Jun 30 at 19:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .