I have a cost requirement to use a single ALB for ...
# aws
c
I have a cost requirement to use a single ALB for multiple instances (currently behind Elastic Beanstalk. This works effectively, but I would like to move to ECS or even EKS, using Pulumi to manage it all. It's possible to do it programmatically with a single config, but I'd like to seperate the core config (ALB) from ECS deployments. Here's the single config with hints on where I'd like seperation:
Copy code
import * as aws from "@pulumi/aws";
import * as awsx from "@pulumi/awsx";

// CORE CONFIGURATION
const cluster = new awsx.ecs.Cluster("stack-cluster");
const lb = new awsx.lb.ApplicationLoadBalancer("loadbalancer", { external: true });

const web = lb.createListener("web", { protocol: "HTTP", defaultAction: {
    type: "fixed-response",
    fixedResponse: {
        statusCode: "503",
        contentType: "application/json"
    }
} })

const defaultCertificateArn = "";

const webHttps = lb.createListener("web-https", { protocol: "HTTPS", certificateArn: defaultCertificateArn, defaultAction: {
    type: "fixed-response",
    fixedResponse: {
        statusCode: "503",
        contentType: "application/json"
    }
} })

const repo = new awsx.ecr.Repository("my-repo");

// FIRST SERVICE (GitHub repo 2)
const targetgroup1 = lb.createTargetGroup("targetgroup1", { protocol: "HTTP", port: 80 });

const app1Certificate = new aws.alb.ListenerCertificate("app1", {
    certificateArn: "",
    listenerArn: webHttps.listener.arn,
});

const rule1 = new awsx.lb.ListenerRule("http-app1", web, { conditions: [{ field: "host-header", values: "<http://app1.domain.com|app1.domain.com>" }], actions: [{type: "forward", targetGroupArn: targetgroup1.targetGroup.arn }]})
const ruleHttps1 = new awsx.lb.ListenerRule("https-app1", webHttps, { conditions: [{ field: "host-header", values: "<http://app1.domain.com|app1.domain.com>" }], actions: [{type: "forward", targetGroupArn: targetgroup1.targetGroup.arn }]})

const app1 = repo.buildAndPushImage("./app1");

const app1Service = new awsx.ecs.FargateService("app1", {
    cluster,
    taskDefinitionArgs: {
        containers: {
            app1: {
                image: app1,
                portMappings: [targetgroup1],
            },
        },
    },
    desiredCount: 2,
});


// SECOND SERVICE (GitHub repo 3)
const targetgroup2 = lb.createTargetGroup("targetgroup2", { protocol: "HTTP", port: 80 });

const app2Certificate = new aws.alb.ListenerCertificate("app2", {
    certificateArn: "",
    listenerArn: webHttps.listener.arn,
});

const rule2 = new awsx.lb.ListenerRule("http-app2", web, {  conditions: [{ field: "host-header", values: "<http://app2.domain.com|app2.domain.com>" }], actions: [{type: "forward", targetGroupArn: targetgroup2.targetGroup.arn }]})
const ruleHttps2 = new awsx.lb.ListenerRule("https-app2", webHttps, {  conditions: [{ field: "host-header", values: "<http://app2.domain.com|app2.domain.com>" }], actions: [{type: "forward", targetGroupArn: targetgroup2.targetGroup.arn }]})

const app2 = repo.buildAndPushImage("./app2");

let app2Service = new awsx.ecs.FargateService("app2", {
    cluster,
    desiredCount: 2,
    taskDefinitionArgs: {
        containers: {
            app2: {
                image: app2,  
                portMappings: [ targetgroup2 ],
            },
        },
    },
});
h
Pulumi separates things like this through configuration, rather than via different codebases or scripts. Then it uses stacks to reprsent a particular deployment with a particular config. That is, your config would control whether app1, app2, both or neither were built & deployed for a particular stack. If you want to add/remove apps to a stack, you change the config and re-run the deployment (for the same stack).
Hope that helps, glad to try and answer more specific questions
c
Thanks for this. I would imagine that for my case I could build and push each app to ECR separately, then use a single core pulumi "stack" project to deploy all apps to the stack as described above?
h
Yes, in fact I do something like that, but I don't use pulumi to build/push. Instead, I run codebuild jobs to do all the docker stuff, then the container names are passed into my pulumi program for deployment. However, I just came across this on the Pulumi site https://www.pulumi.com/docs/intro/concepts/organizing-stacks-projects/ and it probably answers the question you are asking. Check out the "micro stacks" section.