@@ -4,10 +4,6 @@ import * as ecs from 'aws-cdk-lib/aws-ecs';
44import * as logs from 'aws-cdk-lib/aws-logs' ;
55import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2' ;
66import * as cognito from 'aws-cdk-lib/aws-cognito' ;
7- import * as elbv2_actions from 'aws-cdk-lib/aws-elasticloadbalancingv2-actions' ;
8- import * as acm from 'aws-cdk-lib/aws-certificatemanager' ;
9- import * as route53 from 'aws-cdk-lib/aws-route53' ;
10- import * as targets from 'aws-cdk-lib/aws-route53-targets' ;
117import { Construct } from 'constructs' ;
128import { AttributeType , BillingMode , Table } from 'aws-cdk-lib/aws-dynamodb' ;
139import { RemovalPolicy } from 'aws-cdk-lib' ;
@@ -90,43 +86,58 @@ export class BackendStack extends cdk.Stack {
9086 const userPoolDomain = cognito . UserPoolDomain . fromDomainName (
9187 this ,
9288 `${ appName } ExistingDomain-${ props . environment } ` ,
93- 'us-east-1pszlvsmwc' // The domain prefix without the .auth.region.amazoncognito.com part
89+ 'us-east-1pszlvsmwc' , // The domain prefix without the .auth.region.amazoncognito.com part
9490 ) ;
9591
96- // Create ALB
92+ // 1. Create ALB
9793 const alb = new elbv2 . ApplicationLoadBalancer ( this , `${ appName } ALB-${ props . environment } ` , {
9894 vpc,
9995 internetFacing : true ,
10096 loadBalancerName : `${ appName } -${ props . environment } ` ,
10197 } ) ;
10298
103- // HTTPS IMPLEMENTATION - CERTIFICATE
104- let certificate ;
105- if ( props . domainName && props . hostedZoneId ) {
106- // If domain name is provided, create or import certificate
107- const hostedZone = route53 . HostedZone . fromHostedZoneAttributes ( this , 'HostedZone' , {
108- hostedZoneId : props . hostedZoneId ,
109- zoneName : props . domainName ,
110- } ) ;
99+ // 2. Create ALB Target Group
100+ const targetGroup = new elbv2 . ApplicationTargetGroup (
101+ this ,
102+ `${ appName } TargetGroup-${ props . environment } ` ,
103+ {
104+ vpc,
105+ port : 3000 ,
106+ protocol : elbv2 . ApplicationProtocol . HTTP ,
107+ targetType : elbv2 . TargetType . IP ,
108+ healthCheck : {
109+ path : '/health' ,
110+ interval : cdk . Duration . seconds ( 30 ) ,
111+ timeout : cdk . Duration . seconds ( 5 ) ,
112+ } ,
113+ } ,
114+ ) ;
111115
112- certificate = new acm . Certificate ( this , `${ appName } Certificate-${ props . environment } ` , {
113- domainName : props . domainName ,
114- validation : acm . CertificateValidation . fromDns ( hostedZone ) ,
115- } ) ;
116+ // 3. HTTP 80 Listener
117+ alb . addListener ( `${ appName } HttpListener-${ props . environment } ` , {
118+ port : 80 ,
119+ protocol : elbv2 . ApplicationProtocol . HTTP ,
120+ defaultAction : elbv2 . ListenerAction . redirect ( {
121+ protocol : elbv2 . ApplicationProtocol . HTTPS ,
122+ } ) ,
123+ } ) ;
116124
117- // Create DNS record for ALB
118- new route53 . ARecord ( this , `${ appName } AliasRecord-${ props . environment } ` , {
119- zone : hostedZone ,
120- recordName : props . domainName ,
121- target : route53 . RecordTarget . fromAlias ( new targets . LoadBalancerTarget ( alb ) ) ,
122- } ) ;
123- } else {
124- // For development or when no domain is provided, generate a self-signed certificate
125- certificate = new acm . Certificate ( this , `${ appName } SelfSignedCert-${ props . environment } ` , {
126- domainName : alb . loadBalancerDnsName ,
127- validation : acm . CertificateValidation . fromDns ( ) ,
128- } ) ;
129- }
125+ // 4. Create Fargate Service
126+ const fargateService = new ecs . FargateService ( this , `${ appName } Service-${ props . environment } ` , {
127+ cluster,
128+ taskDefinition,
129+ desiredCount : isProd ? 2 : 1 ,
130+ assignPublicIp : false ,
131+ securityGroups : [
132+ new ec2 . SecurityGroup ( this , `${ appName } ServiceSG-${ props . environment } ` , {
133+ vpc,
134+ allowAllOutbound : true ,
135+ } ) ,
136+ ] ,
137+ } ) ;
138+
139+ // 5. Register the service with the Target Group
140+ targetGroup . addTarget ( fargateService ) ;
130141
131142 // Create a Cognito User Pool Client for the ALB
132143 const userPoolClient = new cognito . UserPoolClient (
@@ -151,20 +162,6 @@ export class BackendStack extends cdk.Stack {
151162 } ,
152163 ) ;
153164
154- // Create Fargate Service
155- const fargateService = new ecs . FargateService ( this , `${ appName } Service-${ props . environment } ` , {
156- cluster,
157- taskDefinition,
158- desiredCount : isProd ? 2 : 1 ,
159- assignPublicIp : false ,
160- securityGroups : [
161- new ec2 . SecurityGroup ( this , `${ appName } ServiceSG-${ props . environment } ` , {
162- vpc,
163- allowAllOutbound : true ,
164- } ) ,
165- ] ,
166- } ) ;
167-
168165 // Add autoscaling for production
169166 if ( isProd ) {
170167 const scaling = fargateService . autoScaleTaskCount ( {
@@ -179,52 +176,6 @@ export class BackendStack extends cdk.Stack {
179176 } ) ;
180177 }
181178
182- // Create ALB Target Group
183- const targetGroup = new elbv2 . ApplicationTargetGroup (
184- this ,
185- `${ appName } TargetGroup-${ props . environment } ` ,
186- {
187- vpc,
188- port : 3000 ,
189- protocol : elbv2 . ApplicationProtocol . HTTP ,
190- targetType : elbv2 . TargetType . IP ,
191- healthCheck : {
192- path : '/health' ,
193- interval : cdk . Duration . seconds ( 30 ) ,
194- timeout : cdk . Duration . seconds ( 5 ) ,
195- } ,
196- targets : [ fargateService ] ,
197- } ,
198- ) ;
199-
200- // HTTPS IMPLEMENTATION - LISTENERS
201-
202- // Create HTTPS Listener
203- alb . addListener ( `${ appName } HttpsListener-${ props . environment } ` , {
204- port : 443 ,
205- protocol : elbv2 . ApplicationProtocol . HTTPS ,
206- certificates : [ certificate ] ,
207- sslPolicy : elbv2 . SslPolicy . RECOMMENDED ,
208- defaultAction : new elbv2_actions . AuthenticateCognitoAction ( {
209- userPool,
210- userPoolClient,
211- userPoolDomain : userPoolDomain ,
212- next : elbv2 . ListenerAction . forward ( [ targetGroup ] ) ,
213- onUnauthenticatedRequest : elbv2 . UnauthenticatedAction . AUTHENTICATE ,
214- } ) ,
215- } ) ;
216-
217- // Create HTTP Listener that redirects to HTTPS
218- alb . addListener ( `${ appName } HttpListener-${ props . environment } ` , {
219- port : 80 ,
220- protocol : elbv2 . ApplicationProtocol . HTTP ,
221- defaultAction : elbv2 . ListenerAction . redirect ( {
222- protocol : elbv2 . ApplicationProtocol . HTTPS ,
223- port : '443' ,
224- permanent : true ,
225- } ) ,
226- } ) ;
227-
228179 // Create DynamoDB table for reports
229180 const reportsTable = new Table ( this , `${ appName } ReportsTable-${ props . environment } ` , {
230181 tableName : `${ appName } ReportsTable${ props . environment } ` ,
0 commit comments