I'm trying to get the value of two Outputs (Load Balancers) and inject them into a Container Definition resource (aws.ecs.TaskDefinition
).
Both Load Balancers and Task Definition are being created in the same stack, the dependency is managed with the depends_on
flag).
I followed the explanation described here and was able to reproduce it, but in my specific case I need to pass two variables to the attribute container_definitions
of the class aws.ecs.TaskDefinition
.
So I tried:
load_balancer_1 = aws.lb.LoadBalancer("LoadBalancer1",
// stuff here
)
load_balancer_2 = aws.lb.LoadBalancer("LoadBalancer2",
// stuff here
)
def get_lb1_dnsName(lb1_dnsname):
return json.dumps(
{
"name": "var1",
"value": lb1_dnsname
}
)
def get_lb2_dnsName(lb2_dnsname):
return json.dumps(
{
"name": "var2",
"value": lb2_dnsname
}
)
container_task_definition = aws.ecs.TaskDefinition("TaskDefinition",
// stuff here
container_definitions=json.dumps([
{ "name":"foo",
"essential":True,
"image":"image-url:latest",
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/foo",
"awslogs-region": "us-east-1",
"awslogs-create-group": "true",
"awslogs-stream-prefix": "ecs"
}
},
"environment": [
load_balancer_1.dns_name.apply(get_lb1_dnsName),
load_balancer_2.dns_name.apply(get_lb2_dnsName)
]
}
]
),
opts=pulumi.ResourceOptions(depends_on=[load_balancer_1, load_balancer_2])
)
Even though I keep receiving the error:
TypeError: Object of type Output is not JSON serializable
So I wonder how to properly set the Load Balancers dns_name to the enviroment variables of the Task Definition. e.g:
"environment": [
"env1": dns_of_load_balancer_1
"env2": dns_of_load_balancer_2
]
Creating the individual functions is fine, but if you're working with multiple outputs, you need to use all
It's personal preference, but I prefer to wrap the entire string with the apply, it ends up looking a little like this:
task_definition = aws.ecs.TaskDefinition(
"app-task",
family="fargate-task-definition",
cpu="256",
memory="512",
network_mode="awsvpc",
requires_compatibilities=["FARGATE"],
execution_role_arn=role.arn,
container_definitions=pulumi.Output.all(lb_one=alb.dns_name, lb_two=alb2.dns_name).apply(
lambda args: json.dumps(
[
{
"name": "my-app",
"image": "nginx",
"portMappings": [
{"containerPort": 80, "hostPort": 80, "protocol": "tcp"}
],
"environment": [
{"name": "LOADBALANCER_ONE", "value": args["lb_one"]},
{"name": "LOADBALANCER_TWO", "value": args["lb_two"]},
],
}
]
),
),
)
In addition to this, you don't actually need the explicit depends_on
in your resource options. By using the outputs from the original resources as inputs (via apply/all) to your task definition, Pulumi can figure out the order (although it doesn't hurt to have them)