FEAT: Added Redis Caching
Deploy Infrastructure / pulumi-up (push) Successful in 3s
Build, Push and Deploy Discovery / build-push-deploy (push) Failing after 34m37s

This commit is contained in:
FahdShalhoub
2026-08-29 23:12:11 +03:00
parent f66f3b555d
commit 35d4d6756e
8 changed files with 386 additions and 8 deletions
+68
View File
@@ -13,6 +13,7 @@ import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecr"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecs"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/elasticache"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lb"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds"
@@ -384,6 +385,7 @@ func main() {
cmsRepo, discoveryRepo *ecr.Repository
cmsService, discoveryService *ecs.Service
cmsAlb, discoveryAlb *lb.LoadBalancer
searchCacheAddress pulumi.StringOutput
)
// Bucket names are left to Pulumi's auto-naming in AWS, but pinned under
@@ -771,6 +773,67 @@ func main() {
}
}
if !localstack {
cacheSubnetGroup, err := elasticache.NewSubnetGroup(ctx, "search-cache-subnet-group", &elasticache.SubnetGroupArgs{
SubnetIds: pulumi.ToStringArray(subnetIDs),
})
if err != nil {
return err
}
cacheSecurityGroup, err := ec2.NewSecurityGroup(ctx, "search-cache-sg", &ec2.SecurityGroupArgs{
Description: pulumi.String("Allow the ECS tasks to reach the search cache"),
VpcId: pulumi.String(vpcID),
Ingress: ec2.SecurityGroupIngressArray{
&ec2.SecurityGroupIngressArgs{
Protocol: pulumi.String("tcp"),
FromPort: pulumi.Int(6379),
ToPort: pulumi.Int(6379),
SecurityGroups: pulumi.StringArray{serviceSecurityGroup.ID()},
Description: pulumi.String("Redis, from the service tasks only"),
},
},
Egress: ec2.SecurityGroupEgressArray{
&ec2.SecurityGroupEgressArgs{
Protocol: pulumi.String("-1"),
FromPort: pulumi.Int(0),
ToPort: pulumi.Int(0),
CidrBlocks: pulumi.ToStringArray([]string{"0.0.0.0/0"}),
},
},
})
if err != nil {
return err
}
searchCache, err := elasticache.NewCluster(ctx, "search-cache", &elasticache.ClusterArgs{
Engine: pulumi.String("redis"),
EngineVersion: pulumi.String("7.1"),
NodeType: pulumi.String("cache.t4g.micro"),
NumCacheNodes: pulumi.Int(1),
ParameterGroupName: pulumi.String("default.redis7"),
Port: pulumi.Int(6379),
SubnetGroupName: cacheSubnetGroup.Name,
SecurityGroupIds: pulumi.StringArray{cacheSecurityGroup.ID()},
ApplyImmediately: pulumi.Bool(true),
})
if err != nil {
return err
}
// A single-node Redis cluster has no configuration endpoint — that
// is a Memcached thing — so the address is the one cache node's.
searchCacheAddress = pulumi.All(searchCache.CacheNodes, searchCache.Port).ApplyT(
func(args []any) (string, error) {
nodes := args[0].([]elasticache.ClusterCacheNode)
if len(nodes) == 0 || nodes[0].Address == nil {
return "", fmt.Errorf("search cache reported no node address")
}
return fmt.Sprintf("%s:%d", *nodes[0].Address, args[1].(int)), nil
},
).(pulumi.StringOutput)
}
// Private bucket for raw video uploads (pre-transcode). Kept separate
// from encoded-bucket, which is fronted by CloudFront/OAC for public
// delivery of finished renditions — raw source video must not be
@@ -1359,6 +1422,10 @@ func main() {
discoveryExtraEnv := []envVar{
{Name: "AWS_REGION", Value: pulumi.String(awsRegion).ToStringOutput()},
{Name: "CATALOGUE_EVENTS_QUEUE_URL", Value: catalogueQueue.Url},
// The search cache. Reached over the Redis protocol on the
// private network, so unlike the queue above it needs no
// matching grant on discovery-task-role.
{Name: "REDIS_ADDR", Value: searchCacheAddress},
}
discoveryRepo, discoveryService, discoveryAlb, err = deployFargateService(ctx, "discovery", 8080,
@@ -1452,6 +1519,7 @@ func main() {
ctx.Export("ecsClusterArn", cluster.Arn)
ctx.Export("cmsServiceArn", cmsService.Arn)
ctx.Export("discoveryServiceArn", discoveryService.Arn)
ctx.Export("searchCacheAddress", searchCacheAddress)
}
return nil
})