diff --git a/README.md b/README.md
index 684f30c7f86..a9e1ad5c113 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,7 @@ In order to deploy both the stacks the user needs to provide a set of required a
 | certificateArn                | Optional    | string    | Add ACM certificate to the any listener (OpenSearch or OpenSearch-Dashboards) whose port is mapped to 443. e.g., `--context certificateArn=arn:1234`|
 | mapOpensearchPortTo           | Optional    | integer   | Load balancer port number to map to OpenSearch. e.g., `--context mapOpensearchPortTo=8440` Defaults to 80 when security is disabled and 443 when security is enabled |
 | mapOpensearchDashboardsPortTo | Optional    | integer   | Load balancer port number to map to OpenSearch-Dashboards. e.g., `--context mapOpensearchDashboardsPortTo=443` Always defaults to 8443 |
+| loadBalancerType              | Optional    | string    | The type of load balancer to deploy. Valid values are nlb for Network Load Balancer or alb for Application Load Balancer. Defaults to nlb. e.g., `--context loadBalancerType=alb` |
 
 * Before starting this step, ensure that your AWS CLI is correctly configured with access credentials.
 * Also ensure that you're running these commands in the current directory
@@ -169,7 +170,7 @@ All the ec2 instances are hosted in private subnet and can only be accessed usin
 
 ## Port Mapping
 
-The ports to access the cluster are dependent on the `security` parameter value
+The ports to access the cluster are dependent on the `security` parameter value and are identical whether using an Application Load Balancer (ALB) or a Network Load Balancer (NLB):
 * If `security` is `disable` (HTTP),
   * OpenSearch 9200 is mapped to port 80 on the LB
 * If `security` is `enable` (HTTPS),
diff --git a/lib/infra/infra-stack.ts b/lib/infra/infra-stack.ts
index 8cf8585052f..3f7b4aa67bd 100644
--- a/lib/infra/infra-stack.ts
+++ b/lib/infra/infra-stack.ts
@@ -29,6 +29,13 @@ import {
   SubnetType,
 } from 'aws-cdk-lib/aws-ec2';
 import {
+  ApplicationListener,
+  ApplicationLoadBalancer,
+  ApplicationProtocol,
+  BaseApplicationListenerProps,
+  BaseListener,
+  BaseLoadBalancer,
+  BaseNetworkListenerProps,
   ListenerCertificate,
   NetworkListener, NetworkLoadBalancer, Protocol,
 } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
@@ -55,6 +62,11 @@ enum cpuArchEnum{
   ARM64='arm64'
 }
 
+export enum LoadBalancerType {
+  NLB = 'nlb',
+  ALB = 'alb'
+}
+
 const getInstanceType = (instanceType: string, arch: string) => {
   if (arch === 'x64') {
     if (instanceType !== 'undefined') {
@@ -133,10 +145,13 @@ export interface InfraProps extends StackProps {
    readonly mapOpensearchPortTo ?: number
    /** Map opensearch-dashboards port on load balancer to */
    readonly mapOpensearchDashboardsPortTo ?: number
+   /** Type of load balancer to use (e.g., 'nlb' or 'alb') */
+   readonly loadBalancerType?: LoadBalancerType
 }
 
 export class InfraStack extends Stack {
-  public readonly nlb: NetworkLoadBalancer;
+  public readonly elb: NetworkLoadBalancer | ApplicationLoadBalancer;
+  public readonly elbType: LoadBalancerType;
 
   private instanceRole: Role;
 
@@ -200,8 +215,6 @@ export class InfraStack extends Stack {
 
   constructor(scope: Stack, id: string, props: InfraProps) {
     super(scope, id, props);
-    let opensearchListener: NetworkListener;
-    let dashboardsListener: NetworkListener;
     let managerAsgCapacity: number;
     let dataAsgCapacity: number;
     let clientNodeAsg: AutoScalingGroup;
@@ -398,11 +411,28 @@ export class InfraStack extends Stack {
 
     const certificateArn = `${props?.certificateArn ?? scope.node.tryGetContext('certificateArn')}`;
 
-    this.nlb = new NetworkLoadBalancer(this, 'clusterNlb', {
-      vpc: props.vpc,
-      internetFacing: (!this.isInternal),
-      crossZoneEnabled: true,
-    });
+    // Set the load balancer type, defaulting to NLB if not specified
+    const loadBalancerTypeStr = scope.node.tryGetContext('loadBalancerType') ?? 'nlb'
+    this.elbType = props?.loadBalancerType ?? LoadBalancerType[(loadBalancerTypeStr).toUpperCase() as keyof typeof LoadBalancerType];
+    switch (this.elbType) {
+      case LoadBalancerType.NLB:
+        this.elb = new NetworkLoadBalancer(this, 'clusterNlb', {
+          vpc: props.vpc,
+          internetFacing: (!this.isInternal),
+          crossZoneEnabled: true,
+        });
+        break;
+      case LoadBalancerType.ALB:
+        this.elb = new ApplicationLoadBalancer(this, 'clusterAlb', {
+          vpc: props.vpc,
+          internetFacing: (!this.isInternal),
+          crossZoneEnabled: true,
+          securityGroup: props.securityGroup,
+        });
+        break;
+      default:
+        throw new Error('Invalid load balancer type provided. Valid values are ' + Object.values(LoadBalancerType).join(', '));
+    }
 
     const opensearchPortMap = `${props?.mapOpensearchPortTo ?? scope.node.tryGetContext('mapOpensearchPortTo')}`;
     const opensearchDashboardsPortMap = `${props?.mapOpensearchDashboardsPortTo ?? scope.node.tryGetContext('mapOpensearchDashboardsPortTo')}`;
@@ -428,34 +458,27 @@ export class InfraStack extends Stack {
       + ` Current mapping is OpenSearch:${this.opensearchPortMapping} OpenSearch-Dashboards:${this.opensearchDashboardsPortMapping}`);
     }
 
-    if (!this.securityDisabled && !this.minDistribution && this.opensearchPortMapping === 443 && certificateArn !== 'undefined') {
-      opensearchListener = this.nlb.addListener('opensearch', {
-        port: this.opensearchPortMapping,
-        protocol: Protocol.TLS,
-        certificates: [ListenerCertificate.fromArn(certificateArn)],
-      });
-    } else {
-      opensearchListener = this.nlb.addListener('opensearch', {
-        port: this.opensearchPortMapping,
-        protocol: Protocol.TCP,
-      });
-    }
+    const useSSLOpensearchListener = !this.securityDisabled && !this.minDistribution && this.opensearchPortMapping === 443 && certificateArn !== 'undefined';
+    const opensearchListener = InfraStack.createListener(
+      this.elb,
+      this.elbType,
+      'opensearch',
+      this.opensearchPortMapping,
+      (useSSLOpensearchListener) ? certificateArn : undefined
+    );
 
+    let dashboardsListener: NetworkListener | ApplicationListener;
     if (this.dashboardsUrl !== 'undefined') {
-      if (!this.securityDisabled && !this.minDistribution && this.opensearchDashboardsPortMapping === 443 && certificateArn !== 'undefined') {
-        dashboardsListener = this.nlb.addListener('dashboards', {
-          port: this.opensearchDashboardsPortMapping,
-          protocol: Protocol.TLS,
-          certificates: [ListenerCertificate.fromArn(certificateArn)],
-        });
-      } else {
-        dashboardsListener = this.nlb.addListener('dashboards', {
-          port: this.opensearchDashboardsPortMapping,
-          protocol: Protocol.TCP,
-        });
-      }
+      const useSSLDashboardsListener = !this.securityDisabled && !this.minDistribution 
+        && this.opensearchDashboardsPortMapping === 443 && certificateArn !== 'undefined';
+      dashboardsListener = InfraStack.createListener(
+        this.elb,
+        this.elbType,
+        'dashboards',
+        this.opensearchDashboardsPortMapping,
+        (useSSLDashboardsListener) ? certificateArn : undefined
+      );
     }
-
     if (this.singleNodeCluster) {
       console.log('Single node value is true, creating single node configurations');
       singleNodeInstance = new Instance(this, 'single-node-instance', {
@@ -483,19 +506,23 @@ export class InfraStack extends Stack {
       });
       Tags.of(singleNodeInstance).add('role', 'client');
 
-      opensearchListener.addTargets('single-node-target', {
-        port: 9200,
-        protocol: Protocol.TCP,
-        targets: [new InstanceTarget(singleNodeInstance)],
-      });
+      // Disable target security for now, can be provided as an option in the future
+      InfraStack.addTargetsToListener(
+        opensearchListener,
+        this.elbType, 
+        'single-node-target', 
+        9200, 
+        new InstanceTarget(singleNodeInstance),
+        false);
 
       if (this.dashboardsUrl !== 'undefined') {
-        // @ts-ignore
-        dashboardsListener.addTargets('single-node-osd-target', {
-          port: 5601,
-          protocol: Protocol.TCP,
-          targets: [new InstanceTarget(singleNodeInstance)],
-        });
+        InfraStack.addTargetsToListener(
+          dashboardsListener!,
+          this.elbType, 
+          'single-node-osd-target', 
+          5601, 
+          new InstanceTarget(singleNodeInstance),
+          false);
       }
       new CfnOutput(this, 'private-ip', {
         value: singleNodeInstance.instancePrivateIp,
@@ -660,23 +687,27 @@ export class InfraStack extends Stack {
         Tags.of(mlNodeAsg).add('role', 'ml-node');
       }
 
-      opensearchListener.addTargets('opensearchTarget', {
-        port: 9200,
-        protocol: Protocol.TCP,
-        targets: [clientNodeAsg],
-      });
+      // Disable target security for now, can be provided as an option in the future
+      InfraStack.addTargetsToListener(
+        opensearchListener,
+        this.elbType, 
+        'opensearchTarget', 
+        9200, 
+        clientNodeAsg,
+        false);
 
       if (this.dashboardsUrl !== 'undefined') {
-        // @ts-ignore
-        dashboardsListener.addTargets('dashboardsTarget', {
-          port: 5601,
-          protocol: Protocol.TCP,
-          targets: [clientNodeAsg],
-        });
+        InfraStack.addTargetsToListener(
+          dashboardsListener!,
+          this.elbType, 
+          'dashboardsTarget', 
+          5601, 
+          clientNodeAsg,
+          false);
       }
     }
     new CfnOutput(this, 'loadbalancer-url', {
-      value: this.nlb.loadBalancerDnsName,
+      value: this.elb.loadBalancerDnsName,
     });
 
     if (this.enableMonitoring) {
@@ -1013,4 +1044,75 @@ export class InfraStack extends Stack {
 
     return cfnInitConfig;
   }
+
+  /**
+   * Creates a listener for the given load balancer.
+   * If a certificate is provided, the protocol will be set to TLS/HTTPS.
+   * Otherwise, the protocol will be set to TCP/HTTP.
+   */
+  private static createListener(elb: BaseLoadBalancer, elbType: LoadBalancerType, id: string, port: number,
+      certificateArn?: string): ApplicationListener | NetworkListener {
+    const useSSL = !!certificateArn;
+
+    let protocol: ApplicationProtocol | Protocol;
+    switch(elbType) {
+      case LoadBalancerType.ALB:
+        protocol = useSSL ? ApplicationProtocol.HTTPS : ApplicationProtocol.HTTP;
+        break;
+      case LoadBalancerType.NLB:
+        protocol = useSSL ? Protocol.TLS : Protocol.TCP;
+        break;
+      default:
+        throw new Error('Unsupported load balancer type.');
+    }
+
+    const listenerProps: BaseApplicationListenerProps | BaseNetworkListenerProps = {
+      port: port,
+      protocol: protocol,
+      certificates: useSSL ? [ListenerCertificate.fromArn(certificateArn)] : undefined,
+    };
+
+    switch(elbType) {
+      case LoadBalancerType.ALB: {
+        const alb = elb as ApplicationLoadBalancer;
+        return alb.addListener(id, listenerProps as BaseApplicationListenerProps);
+      }
+      case LoadBalancerType.NLB: {
+        const nlb = elb as NetworkLoadBalancer;
+        return nlb.addListener(id, listenerProps as BaseNetworkListenerProps);
+      }
+      default:
+        throw new Error('Unsupported load balancer type.');
+    }
+  }
+
+  /**
+   * Adds targets to the given listener.
+   * Works for both Application Load Balancers and Network Load Balancers.
+   */
+  private static addTargetsToListener(listener: BaseListener, elbType: LoadBalancerType, id: string, port: number, target: AutoScalingGroup | InstanceTarget,
+      securityEnabled: boolean) {
+    switch(elbType) {
+      case LoadBalancerType.ALB: {
+        const albListener = listener as ApplicationListener;
+        albListener.addTargets(id, {
+          port: port,
+          protocol: securityEnabled ? ApplicationProtocol.HTTPS : ApplicationProtocol.HTTP,
+          targets: [target],
+        });
+        break;
+      }
+      case LoadBalancerType.NLB: {
+        const nlbListener = listener as NetworkListener;
+        nlbListener.addTargets(id, {
+          port: port,
+          protocol: securityEnabled ? Protocol.TLS : Protocol.TCP,
+          targets: [target],
+        });
+        break;
+      }
+      default:
+        throw new Error('Unsupported load balancer type.');
+    }
+  }
 }
diff --git a/test/infra-stack-props.test.ts b/test/infra-stack-props.test.ts
index f8be7563e37..83173873bd3 100644
--- a/test/infra-stack-props.test.ts
+++ b/test/infra-stack-props.test.ts
@@ -317,3 +317,43 @@ test('Throw error on invalid CPU Arch', () => {
     expect(error.message).toEqual('distributionUrl parameter is required. Please provide the OpenSearch distribution artifact url to download');
   }
 });
+
+test('Throw error on invalid load balancer type', () => {
+  const app = new App({
+    context: {
+      distVersion: '1.0.0',
+      securityDisabled: false,
+      minDistribution: false,
+      cpuArch: 'x64',
+      singleNodeCluster: false,
+      dashboardsUrl: 'www.example.com',
+      distributionUrl: 'www.example.com',
+      serverAccessType: 'ipv4',
+      restrictServerAccessTo: 'all',
+      additionalConfig: '{ "name": "John Doe", "age": 30, "email": "johndoe@example.com" }',
+      additionalOsdConfig: '{ "something.enabled": "true", "something_else.enabled": "false" }',
+      loadBalancerType: 'invalid-type',
+    },
+  });
+
+  try {
+    // WHEN
+    const networkStack = new NetworkStack(app, 'opensearch-network-stack', {
+      env: { account: 'test-account', region: 'us-east-1' },
+    });
+
+    // @ts-ignore
+    const infraStack = new InfraStack(app, 'opensearch-infra-stack', {
+      vpc: networkStack.vpc,
+      securityGroup: networkStack.osSecurityGroup,
+      env: { account: 'test-account', region: 'us-east-1' },
+    });
+
+    // eslint-disable-next-line no-undef
+    fail('Expected an error to be thrown');
+  } catch (error) {
+    expect(error).toBeInstanceOf(Error);
+    // @ts-ignore
+    expect(error.message).toEqual('Invalid load balancer type provided. Valid values are nlb, alb');
+  }
+});
diff --git a/test/opensearch-cluster-cdk.test.ts b/test/opensearch-cluster-cdk.test.ts
index eb5e2e1b8e2..0f6be488d84 100644
--- a/test/opensearch-cluster-cdk.test.ts
+++ b/test/opensearch-cluster-cdk.test.ts
@@ -5,7 +5,7 @@ The OpenSearch Contributors require contributions made to
 this file be licensed under the Apache-2.0 license or a
 compatible open source license. */
 
-import { App } from 'aws-cdk-lib';
+import { App, Stack } from 'aws-cdk-lib';
 import { Template } from 'aws-cdk-lib/assertions';
 import { InfraStack } from '../lib/infra/infra-stack';
 import { NetworkStack } from '../lib/networking/vpc-stack';
@@ -1070,3 +1070,50 @@ test('Ensure target group protocol is always TCP', () => {
     TargetType: 'instance',
   });
 });
+
+
+describe.each([
+  { loadBalancerType: 'alb', securityDisabled: false, expectedType: 'application', expectedProtocol: 'HTTPS' },
+  { loadBalancerType: 'alb', securityDisabled: true, expectedType: 'application', expectedProtocol: 'HTTP' },
+  { loadBalancerType: 'nlb', securityDisabled: false, expectedType: 'network', expectedProtocol: 'TLS' },
+  { loadBalancerType: 'nlb', securityDisabled: true, expectedType: 'network', expectedProtocol: 'TCP' },
+])('Test $loadBalancerType creation with securityDisabled=$securityDisabled', ({ loadBalancerType, securityDisabled, expectedType, expectedProtocol }) => {
+  test(`should create ${loadBalancerType} with securityDisabled=${securityDisabled}`, () => {
+    const app = new App({
+      context: {
+        securityDisabled,
+        certificateArn: (securityDisabled) ? undefined : 'arn:1234',
+        minDistribution: false,
+        distributionUrl: 'www.example.com',
+        cpuArch: 'x64',
+        singleNodeCluster: false,
+        dashboardsUrl: 'www.example.com',
+        distVersion: '1.0.0',
+        serverAccessType: 'ipv4',
+        restrictServerAccessTo: 'all',
+        loadBalancerType,
+      },
+    });
+
+    // WHEN 
+    const networkStack = new NetworkStack(app, 'opensearch-network-stack', {
+      env: { account: 'test-account', region: 'us-east-1' },
+    });
+
+    const infraStack = new InfraStack(app as unknown as Stack, 'opensearch-infra-stack', {
+      vpc: networkStack.vpc,
+      securityGroup: networkStack.osSecurityGroup,
+      env: { account: 'test-account', region: 'us-east-1' },
+    });
+
+    // THEN
+    const infraTemplate = Template.fromStack(infraStack);
+    infraTemplate.hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', {
+      Type: expectedType,
+    });
+
+    infraTemplate.hasResourceProperties('AWS::ElasticLoadBalancingV2::Listener', {
+      Protocol: expectedProtocol,
+    });
+  });
+});