Hey folks, how are you doing? I'm facing a little ...
# python
t
Hey folks, how are you doing? I'm facing a little problem here when using Pulumi, Docker and AWS Fargate/TaskDefinition. I guess I'm missing some of the concepts of outputs. I'm sending the Docker Image to ECR repository, but I can't access its name in execution time (probably because of a json.dumps method). (context in the thread)
My code is very similar to this: file1.py
Copy code
def create_image(args):
    ...
    ...

    image = docker.Image(
        "image",
        image_name=ecr_repo.repository_url,
        build=docker.DockerBuild(
            context="folder",
            dockerfile=path.join("folder", "Dockerfile"),
        ),
        registry=app_registry,
    )

    # Export the base and specific version image name.
    pulumi.export('baseImageName', image.base_image_name)
    pulumi.export('fullImageName', image.image_name)
    return image
main.py
Copy code
image = create_image(args)

aws.ecs.TaskDefinition("task-definition",
    family="task-definition-family",
    cpu=512
    memory=1024,
    network_mode="awsvpc",
    requires_compatibilities=["FARGATE"],
    execution_role_arn=app_exec_role.arn,
    task_role_arn=app_task_role.arn,
    container_definitions=json.dumps([{
        "name": "test",
        "image": image
        "memory": 1024,
        "essential": True
    }])
In my understanding, json.dumps (in container_definitions argument) wont work once the variable image is created in execution time, right? I wasn't able to use it without the json.dumps. Is there a way to use the "container_definition" together with the previously created image?
I need the same thing for my environment variables (in container definitions) and other resources info I have to put together in this container. I actually thinking about separating the project in three
pulumi stacks
. Is that a good practice?
p
You need to use
apply
(https://www.pulumi.com/docs/intro/concepts/inputs-outputs/#apply) to transform an output (Docker image name) into another value (container definition). Here's an example:
Copy code
task_definition = aws.ecs.TaskDefinition('my-task',
    family='my-task',
    cpu='512',
    memory='1024',
    network_mode='awsvpc',
    requires_compatibilities=['FARGATE'],
    execution_role_arn=role.arn,
    container_definitions=pulumi.Output.all(
        image.image_name, log_group.name
    ).apply(
        lambda args: json.dumps([{
            'name': 'my-app',
            'image': args[0],
            'portMappings': [{
                'containerPort': 80,
                'hostPort': 80,
                'protocol': 'tcp'
            }],
            'logConfiguration': {
                'logDriver': 'awslogs',
                'options': {
                    'awslogs-group': args[1],
                    'awslogs-stream-prefix': 'my-app'
                }
            }
        }])
    )
)
👍 1
t
Amazing! It has worked pretty well. Previously I tried to create something like that:
Copy code
image = create_image(args)

aws.ecs.TaskDefinition("task-definition",
    family="task-definition-family",
    cpu=512
    memory=1024,
    network_mode="awsvpc",
    requires_compatibilities=["FARGATE"],
    execution_role_arn=app_exec_role.arn,
    task_role_arn=app_task_role.arn,
    container_definitions=json.dumps([{
        "name": "test",
        "image": image.apply(lambda arg: f"{arg}"),
        "memory": 1024,
        "essential": True
    }])
Naturally , it won't work. Do you have any explanations about the reason? I mean, I know that it is wrong, but how could I better understand the why?