1. Applying SSL termination at the load balancer level

    TypeScript

    When you want to handle SSL termination at the load balancer, it means that the load balancer will manage the encryption and decryption of SSL (Secure Sockets Layer) traffic. This process allows the load balancer to offload the cryptographic load from the backend servers, which can improve performance and management, especially when scaling out an application.

    In AWS, for instance, this is typically done using an Application Load Balancer (ALB) and an SSL/TLS certificate. The ALB listens for incoming connections, terminates the SSL/TLS session, decrypts requests and distributes them to the back-end targets, like EC2 instances, in a VPC.

    Here's a Pulumi program written in TypeScript that sets up an AWS ALB with SSL termination:

    import * as aws from "@pulumi/aws"; // The first step is to create a new certificate in AWS Certificate Manager. // Here we're assuming you've already requested or imported your certificate // and you have the ARN available. Replace the placeholder with your ARN. const certificateArn = "arn:aws:acm:REGION:ACCOUNT-ID:certificate/CERTIFICATE-ID"; // Create a security group for the ALB that allows inbound traffic on port 443 (HTTPS). const albSecurityGroup = new aws.ec2.SecurityGroup("alb-secgrp", { ingress: [ { protocol: 'tcp', fromPort: 443, toPort: 443, cidrBlocks: ['0.0.0.0/0'], }, ], egress: [ { protocol: '-1', fromPort: 0, toPort: 0, cidrBlocks: ['0.0.0.0/0'], }, ], }); // Create an Application Load Balancer. const alb = new aws.lb.LoadBalancer("app-lb", { internal: false, loadBalancerType: "application", securityGroups: [albSecurityGroup.id], subnets: [ // The IDs of the subnets you want to attach to the ALB. // These are just placeholders and should be replaced with actual subnet IDs. "subnet-xxxxxxxxxxxxx", "subnet-yyyyyyyyyyyyy", ], enableDeletionProtection: false, }); // Create a Target Group for directing the traffic to the appropriate backend. const targetGroup = new aws.lb.TargetGroup("app-tg", { port: 80, protocol: "HTTP", targetType: "instance", vpcId: "vpc-zzzzzzzzzzzzzzzzz", // Replace with your VPC ID. }); // Create a listener for the ALB which listens on port 443 and routes the traffic to the TargetGroup. const listener = new aws.lb.Listener("app-listener", { loadBalancerArn: alb.arn, port: 443, protocol: "HTTPS", defaultAction: { type: "forward", targetGroupArn: targetGroup.arn, }, certificateArn: certificateArn, }); // Export the DNS name of the load balancer so it can be easily accessed. export const albDnsName = alb.dnsName;

    In this program, we are doing the following:

    1. We reference an SSL/TLS certificate that you've pre-created in AWS Certificate Manager. This certificate will be used for SSL termination at the ALB. If you don't have a certificate, you can request one directly via AWS Certificate Manager or import one that you've obtained from another certificate authority.

    2. We create a security group that allows inbound traffic on port 443, which is the standard port for HTTPS traffic.

    3. We then set up an Application Load Balancer that listens for incoming HTTPS requests. This load balancer is made internet-facing by setting internal to false and is of type "application".

    4. We create a target group, which is used to route requests to one or more registered targets, such as EC2 instances. Here, the target group is configured to handle HTTP traffic on port 80, on which the instances will receive the decrypted traffic.

    5. The listener is where the SSL termination happens. It listens on port 443 and has the protocol set to HTTPS. When it receives connections, it uses the specified SSL certificate to decrypt the traffic and then forwards it to the target group.

    6. Finally, we export the DNS name of the ALB so it can be used to access the service from the internet.

    Please ensure to replace placeholders (CERTIFICATE-ID, ARN, subnet-xxxxxxxxxxxxx, vpc-zzzzzzzzzzzzzzzzz, etc.) with actual values that correspond to your setup. Also, additional configuration might be required depending on your specific needs, such as configuring health checks or more complex listener rules.