Version: 1.0.31
(Not sure if this is addressed somehow in future versions)
One use case that is common when spinning up a web application is to use an NGINX reverse proxy container. If running both your webapp container and nginx container in the same task - it make proxy passing much easier - the localhost:<port>
strategy for passing traffic from NGINX to the application works, and you don't need the additional complexity of task to task communication.
It would be useful if this module enabled passing of json encoded container definition instead of:
variable "containers" {
type = list(any)
description = "Container definitions to use for the task. If this is used, all other container options will be ignored."
default = []
}
The reason is due to a terraform limitation, that items in a list (which is converted to a tuple during plan / apply) must have the exact same structure. Thus we have broken use cases, such as:
- Having respository credentials (for a NGINX container being pulled from your artifactory instances) vs not (the webapp container pulling its container from ECR).
- Having different environment variables for each container
If you pass two unique container configurations (for the above use cases) the terraform cannot be applied due to the terraform uniform list limitation.
Abbreviated Example that does not work:
[
{
"Environment": [
{
"Name": "VAR_A",
"Value": "Value A"
}
]
"RepositoryCredentials": null
"Secrets": []
},
{
"Environment": [
{
"Name": "VAR_B",
"Value": "Value B"
},
],
"RepositoryCredentials": {
"CredentialsParameter": "arn:aws:secretsmanager:us-west-2:123456789:secret:jfrog_repository_credential-p2Ghcc"
},
"Secrets": [
{
"Name": "DATABASE_PASSWORD",
"ValueFrom": "arn:aws:secretsmanager:us-west-2:123456789:secret:my-secret-1d6a-OwBc4V"
}
],
}
]
In order to achieve the use case, we have to concat environment variables for both containers to make them the same, and both containers must pull from the same container repository (either with or without credentials), as well as have the same secrets, and so forth.
Looking internally - we see that the containers
variable is converted to a jsonencoded object which is passed to the raw resource aws_ecs_task_definition
, e.g.
container_definitions = length(var.containers) == 0 ? "[${module.container_definition.json_map_encoded}]" : jsonencode(var.containers)
NOTE: we use "cloudposse/ecs-container-definition/aws" for the container definitions and the list of containers is constructed as such:
webapp_and_nginx_container = [
module.nginx_reverse_proxy_container_definition.json_map_object,
module.webapp_container_definition.json_map_object
]
Proposed Solution
Can we include an additional variable container_definitions_json
(maybe a better name) which is simply a JSON encoded string that can be passed directly through to the aws_ecs_task_definition
, so we can have more flexibility in the containers we're configuring for the task?
I'm happy to throw up a PR to solve this, but want to get community feedback to see if it makes sense from a wider use case standpoint. We make heavy use of the terraform-aws-modules
package and would like to continue to do so - this is just blocking some pretty standard use cases.