Package: serverless-container-constructs
serverless-container-constructsCDK patterns for modern application with serverless containers on AWSAlbFargateServicesInspired byVijay Menonfrom theAWS blog postintroduced in 2019,AlbFargateServicesallows you to create one or many fargate services with both internet-facing ALB and internal ALB associated with all services. With this pattern, fargate services will be allowed to intercommunicat via internal ALB while external inbound traffic will be spread across the same service tasks through internet-facing ALB.The sample below will create 3 fargate services associated with both external and internal ALBs. The internal ALB will have an alias(internal.svc.local) auto-configured from Route 53 so services can communite through the private ALB endpoint.import{AlbFargateServices}from'serverless-container-constructs';newAlbFargateServices(stack,'Service',{spot:true,//FARGATE_SPOTonlyclustertasks:[{listenerPort:80,task:orderTask,desiredCount:2,//customizetheserviceautoscalingpolicyscalingPolicy:{maxCapacity:20,requestPerTarget:1000,targetCpuUtilization:50,},},{listenerPort:8080,task:customerTask,desiredCount:2},{listenerPort:9090,task:productTask,desiredCount:2},],route53Ops:{zoneName,//svc.localexternalAlbRecordName,//external.svc.localinternalAlbRecordName,//internal.svc.local},});Fargate Spot SupportBy enabling thespotproperty, 100% fargate spot tasks will be provisioned to help you save up to 70%. Check more details aboutFargate Spot. This is a handy catch-all flag to force all tasks to beFARGATE_SPOTonly.To specify mixed strategy with partialFARGATEand partialFARGATE_SPOT, specify thecapacityProviderStrategyfor individual tasks likenewAlbFargateServices(stack,'Service',{tasks:[{listenerPort:8080,task:customerTask,desiredCount:2,capacityProviderStrategy:[{capacityProvider:'FARGATE',base:1,weight:1,},{capacityProvider:'FARGATE_SPOT',base:0,weight:3,},],},],});The custom capacity provider strategy will be applied ifcapacityProviderStretegyis specified, otherwise, 100% spot will be used whenspot: true. The default policy is 100% Fargate on-demand.ECS ExecSimply turn on theenableExecuteCommandproperty to enable theECS Execsupport for all services.Internal or External OnlyBy default, all task(s) defined in theAlbFargateServiceswill be registered to both external and internal ALBs.
Setaccessibilityto make it internal only, external only, or both.newAlbFargateServices(stack,'Service',{tasks:[//thistaskisinternalonly{listenerPort:8080,task:task1,accessibility:LoadBalancerAccessibility.INTERNAL_ONLY},//thistaskisexternalonly{listenerPort:8081,task:task2,accessibility:LoadBalancerAccessibility.EXTERNAL_ONLY},//thistaskisbothexternalandinternalfacing(defaultbehavior){listenerPort:8082,task:task3},],});Please note if all tasks are defined asINTERNAL_ONLY, no external ALB will be created. Similarly, no internal ALB
will be created if all defined asEXTERNAL_ONLY.VPC SubnetsBy default, all tasks will be deployed in the private subnets. You will need the NAT gateway for the default route associated with the private subnets to ensure the task can successfully pull the container images.However, you are allowed to specifyvpcSubnetsto customize the subnet selection.To deploy all tasks in public subnets, one per AZ:newAlbFargateServices(stack,'Service',{vpcSubnets:{subnetType:ec2.SubnetType.PUBLIC,onePerAz:true,},...});This will implicitly enable theauto assign public IPfor each fargate task so the task can successfully pull the container images from external registry. However, the ingress traffic will still be balanced via the external ALB.To deploy all tasks in specific subnets:newAlbFargateServices(stack,'Service',{vpcSubnets:{subnets:[ec2.Subnet.fromSubnetId(stack,'sub-1a','subnet-0e9460dbcfc4cf6ee'),ec2.Subnet.fromSubnetId(stack,'sub-1b','subnet-0562f666bdf5c29af'),ec2.Subnet.fromSubnetId(stack,'sub-1c','subnet-00ab15c0022872f06'),],},...});Sample ApplicationThis repository comes with a sample applicaiton with 3 services in Golang. On deployment, theOrderservice will be exposed externally on external ALB port80and all requests to theOrderservice will trigger sub-requests internally to another other two services(productandcustomer) through the internal ALB and eventually aggregate the response back to the client.DeployTo deploy the sample application in you default VPC://installfirst
yarninstall
npxcdkdiff-cuse_default_vpc=1npxcdkdeploy-cuse_default_vpc=1On deployment complete, you will see the external ALB endpoint in the CDK output.cURLthe external HTTP endpoint and you should be able to see the aggregated response.$curlhttp://demo-Servi-EH1OINYDWDU9-1397122594.ap-northeast-1.elb.amazonaws.com{"service":"order","version":"1.0"}{"service":"product","version":"1.0"}{"service":"customer","version":"1.0"}cdk-nagwithAwsSolutionscheckThis construct follows the best practices from theAWS Solutoinswithcdk-nag. Enable theAWS_SOLUTIONS_CHECKcontext variable to check aginst the cdk-nag rules.npxcdkdiff-cAWS_SOLUTIONS_CHECK=1or
npxcdksynth-cAWS_SOLUTIONS_CHECK=1SecuritySeeCONTRIBUTINGfor more information.LicenseThis library is licensed under the MIT-0 License. See the LICENSE file.