Skip to content
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

containers variable provided as a list limits ability to have unique containers in the same task #62

Open
decoded4620 opened this issue Jul 24, 2024 · 0 comments

Comments

@decoded4620
Copy link

decoded4620 commented Jul 24, 2024

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:

  1. Having respository credentials (for a NGINX container being pulled from your artifactory instances) vs not (the webapp container pulling its container from ECR).
  2. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant