cuddly-magician-97620
01/28/2023, 1:22 AMamazon-ecs-deploy-task-definition
GitHub action to deploy containers to the Fargate service provisioned with Pulumi. My GitHub workflow reads Pulumi stack output, and feeds the task definition to the GitHub action. The action expects containerDefinitions
in a JSON format, and nested under the task_definition
key. However, a simple output in the following form:
export const fgtest = {
task_definition: service.taskDefinition.taskDefinition,
}
results in containerDefinitions
key serialized to a string.
I have a relatively simple taskDefinitionOutput
function that deserializes that key into proper JSON, but I am unable to make it work with the new Crosswalk.
Any attempt to use the spread operator on the new Crosswalk task definition output results in this obscure error:
TypeError: prop.apply is not a function
Here is a sample code that works with the old (classic) Crosswalk:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
const stack = pulumi.getStack();
// taskDefinitionOutput helps return a valid taskDefinition for use in CI/CD
export function taskDefinitionOutput(fargate: awsx.classic.ecs.FargateService) {
const { id, arn, urn, ...taskDefinition } =
fargate.taskDefinition.taskDefinition;
return {
...taskDefinition,
containerDefinitions: taskDefinition.containerDefinitions.apply((data) =>
JSON.parse(data)
),
};
}
const cluster = new awsx.classic.ecs.Cluster(`cluster-${stack}`, {});
const listener = new awsx.classic.lb.NetworkListener(`nginx-${stack}`, { port: 80 });
const service = new awsx.classic.ecs.FargateService(`service-${stack}`, {
cluster: cluster,
assignPublicIp: true,
desiredCount: 2,
taskDefinitionArgs: {
container: {
image: "nginx:latest",
cpu: 512,
memory: 128,
essential: true,
portMappings: [listener],
},
},
});
export const url = listener.endpoint;
export const fgtest = {
task_definition: taskDefinitionOutput(service),
}
And here is the (failing) attempt at refactoring for new Crosswalk:
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";
const stack = pulumi.getStack();
// taskDefinitionOutput helps return a valid taskDefinition for use in CI/CD
export function taskDefinitionOutput(taskDefinitionOutput: any) {
return {
...taskDefinitionOutput,
containerDefinitions: taskDefinitionOutput.containerDefinitions.apply((data:any) =>
JSON.parse(data)
),
};
}
const cluster = new aws.ecs.Cluster(`cluster-${stack}`, {});
const lb = new awsx.lb.ApplicationLoadBalancer(`lb-${stack}`, {});
const service = new awsx.ecs.FargateService(`service-${stack}`, {
cluster: cluster.arn,
assignPublicIp: true,
desiredCount: 2,
taskDefinitionArgs: {
container: {
image: "nginx:latest",
cpu: 512,
memory: 128,
essential: true,
portMappings: [{
targetGroup: lb.defaultTargetGroup,
}],
},
},
});
export const url = lb.loadBalancer.dnsName;
export const fgtest = {
task_definition: taskDefinitionOutput(service.service.taskDefinition),
}
Please help.