sparse-intern-71089
10/18/2022, 2:39 PMmillions-furniture-75402
10/18/2022, 2:48 PMrepository.buildAndPushImage()
?bland-tailor-50336
10/18/2022, 2:50 PMbland-tailor-50336
10/18/2022, 2:50 PMmillions-furniture-75402
10/18/2022, 2:50 PMbland-tailor-50336
10/18/2022, 2:51 PMOne sec I'll share my configuration
millions-furniture-75402
10/18/2022, 2:51 PMbland-tailor-50336
10/18/2022, 2:51 PMbland-tailor-50336
10/18/2022, 2:51 PMbland-tailor-50336
10/18/2022, 3:02 PMimport * as fs from 'fs';
import * as awsx from "@pulumi/awsx";
import * as aws from "@pulumi/aws";
const services = fs.readdirSync('./app').filter(path => /-service$/.test(path));
// Step 1: Create an ECS Fargate cluster.
const cluster = new awsx.ecs.Cluster("cluster");
// Step 2: Define the Networking for our service.
const alb = new awsx.lb.ApplicationLoadBalancer(
"net-lb", { external: true, securityGroups: cluster.securityGroups });
const web = alb.createListener("web", { port: 80, external: true });
const getServiceSegment = (service) => service.replace(/-service$/, '');
services.forEach((service) => {
const segment = getServiceSegment(service);
// Build and publish a Docker image to a private ECR registry.
const serviceImg = awsx.ecs.Image.fromPath(`${service}-img`, `./app/${service}`);
// Create a Fargate service task that can scale out.
const serviceTargetGroup = new aws.lb.TargetGroup(`${service}-target-group`, {
port: 80,
protocol: "HTTP",
vpcId: alb.vpc.id,
targetType: 'ip'
});
const service = new awsx.ecs.FargateService(service, {
cluster,
loadBalancers: [{
containerName: `${service}-container`,
containerPort: 80,
targetGroupArn: serviceTargetGroup.arn
}],
taskDefinitionArgs: {
containers: {
[`${service}-container`]: {
portMappings: [{
containerPort: 80,
}],
image: serviceImg,
cpu: 102 /*10% of 1024*/,
memory: 50 /*MB*/,
}
},
},
desiredCount: 3,
});
const listenerRule = new aws.lb.ListenerRule(`${service}-listener-rule`, {
listenerArn: web.listener.arn,
priority: 100,
actions: [{
type: "forward",
targetGroupArn: serviceTargetGroup.arn
}],
conditions: [
{
pathPattern: {
values: [`/${segment}`, `/${segment}/*`],
},
}
],
});
})
// Step 5: Export the Internet address for the service.
export const url = web.endpoint.hostname;
bland-tailor-50336
10/18/2022, 3:04 PMbland-tailor-50336
10/18/2022, 3:04 PMmillions-furniture-75402
10/18/2022, 3:07 PMmillions-furniture-75402
10/18/2022, 3:11 PM.fromDockerBuild
https://www.pulumi.com/docs/reference/pkg/nodejs/pulumi/awsx/ecs/#containers
If you want to explore multiple stacks, maybe the automation API can help you manage that easier.millions-furniture-75402
10/18/2022, 3:12 PMmillions-furniture-75402
10/18/2022, 3:13 PMmillions-furniture-75402
10/18/2022, 3:15 PMDOCKER_BUILDKIT=1
, which may not be necessary with current versions of docker if it's implicit (I'm not sure)
https://brianchristner.io/what-is-docker-buildkit/
const applicationImage = containerRepository.buildAndPushImage({
env: {
DOCKER_BUILDKIT: "1",
},
});
bland-tailor-50336
10/18/2022, 3:18 PMbland-tailor-50336
10/18/2022, 3:18 PMbland-tailor-50336
10/18/2022, 3:18 PMbland-tailor-50336
10/18/2022, 3:19 PMmillions-furniture-75402
10/18/2022, 3:20 PMmillions-furniture-75402
10/18/2022, 3:20 PMignoreChanges
dynamically if you have a hitbland-tailor-50336
10/18/2022, 3:21 PMbland-tailor-50336
10/18/2022, 3:24 PMbland-tailor-50336
10/18/2022, 3:25 PMmillions-furniture-75402
10/18/2022, 3:25 PMbland-tailor-50336
10/18/2022, 3:26 PMmillions-furniture-75402
10/18/2022, 3:26 PMbland-tailor-50336
10/18/2022, 3:26 PMmillions-furniture-75402
10/18/2022, 3:27 PMsandbox.us-east-1
, dev.us-east-1
millions-furniture-75402
10/18/2022, 3:27 PMpulumi stack init <stackname>
bland-tailor-50336
10/18/2022, 3:28 PMbland-tailor-50336
10/18/2022, 3:28 PMmillions-furniture-75402
10/18/2022, 3:28 PMbland-tailor-50336
10/18/2022, 3:28 PMmillions-furniture-75402
10/18/2022, 3:31 PMbland-tailor-50336
10/18/2022, 3:53 PMbland-tailor-50336
10/18/2022, 3:53 PMbland-tailor-50336
10/18/2022, 3:54 PMmillions-furniture-75402
10/18/2022, 3:58 PMmillions-furniture-75402
10/18/2022, 4:00 PMconst gameserverShared = new pulumi.StackReference(gameserverSharedName);
const gameserverSharedAlbId = gameserverShared.getOutput("albId");
const gameserverSharedAlbSecurityGroupId = gameserverShared.getOutput("albSecurityGroupId");
const alb = new awsx.lb.ApplicationLoadBalancer(`${resourcePrefix}-lb`, {
loadBalancer: aws.lb.LoadBalancer.get(`${resourcePrefix}-lb`, gameserverSharedAlbId, { vpcId: vpc.vpc.id }),
external: true,
securityGroups: [gameserverSharedAlbSecurityGroupId],
vpc: vpc.vpc,
});
millions-furniture-75402
10/18/2022, 4:03 PMconst appTargetGroup = new awsx.lb.ApplicationTargetGroup(`${resourcePrefix}-tg`, {
deregistrationDelay: 0,
healthCheck: { path: "/health", port: "443", protocol: "HTTPS", matcher: "200" },
loadBalancer: alb,
port: 443,
protocol: "HTTPS",
vpc: vpc.vpc,
tags: autotag,
});
const https = new awsx.lb.ApplicationListener(`${resourcePrefix}-https`, {
listener: aws.lb.Listener.get(`${resourcePrefix}-https`, gameserverSharedListenerHttpsId),
loadBalancer: alb,
targetGroup: appTargetGroup,
vpc: vpc.vpc,
});
new awsx.lb.ListenerRule(`${resourcePrefix}-lr`, https, {
actions: [{ targetGroupArn: appTargetGroup.targetGroup.arn.apply(v => v), type: "forward" }],
conditions: [{ hostHeader: { values: [fqdn] } }],
});
new aws.route53.Record(appName, {
aliases: [{ evaluateTargetHealth: true, name: alb.loadBalancer.dnsName, zoneId: elbServiceHostedZoneId }],
name: fqdn.apply(v => v),
type: "A",
zoneId: hostedZoneId,
});
millions-furniture-75402
10/18/2022, 4:04 PMvpc.vpc
is because I have a custom vpc component that contains the "regular" vpc