By using AWS re:Post, you agree to the Terms of Use

CDK - Connect a Network Load Balancer and a Neptune Cluster Endpoint together


For the past two days I've been struggling with exposing a Neptune endpoint to the public using an NLB in a single stack. The architecture was inspired by this document.

For the life of me I haven't been able to figure out how to obtain the IP address of the Neptune endpoint to use as the target of NLB's listener. The main issue resides in the conversion of the Neptune hostname to an IP address as required by NLB's target group IPTarget and how CDK synthesizes stacks before deployment.

I explored the use of CustomResources to no avail due to my limited familiarity with the topic (day 5 of my aws journey), and was hoping someone could point me in the right direction.

Here's my stack (CDK app repo here):

import { Construct } from "constructs";
import { Stack } from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
import * as neptune from "@aws-cdk/aws-neptune-alpha";

import { Props } from "../../_config";
import createVPC from "../helpers/createVPC";
import createNeptuneCluster from "../helpers/createNeptuneCluster";
import createNLB from "../helpers/createNLB";

export class ABCGraphStack extends Stack {
  public readonly vpc: ec2.Vpc;

  public readonly subnets: {
    public: ec2.ISubnet[];
    private: ec2.ISubnet[];
    isolated: ec2.ISubnet[];
  public readonly neptuneCluster: neptune.DatabaseCluster;
  public readonly neptuneReadEndpoint: neptune.Endpoint;
  public readonly neptuneWriteEndpoint: neptune.Endpoint;
  public readonly nlb: elbv2.NetworkLoadBalancer;

  constructor(scope: Construct, id: string, props: Props) {
    super(scope, id, props);

    // Create VPC for use with Neptune
    const { vpc, subnets } = createVPC(props, this);
    this.vpc = vpc;
    this.subnets = subnets;

    // Create Neptune Cluster
    this.neptuneCluster = createNeptuneCluster(

    // Update Neptune Security Group to allow-all-in
      "Allow All Inbound to Neptune"

    // Add an ordering dependency on VPC.

    // Output the Neptune read/write addresses
    this.neptuneReadEndpoint = this.neptuneCluster.clusterReadEndpoint;
    this.neptuneWriteEndpoint = this.neptuneCluster.clusterEndpoint;

   // HOW TO GET IP ADDRESS OF this.neptuneWriteEndpoint.hostname?

    // Create Network Load Balancer
    this.nlb = createNLB(props, this, this.vpc, "????????", 8182);
1 Answers

You would need to build a workflow similar to what is documented here:

But instead of using this for an ALB->NLB proxy, you would use the Lambda workflow to update the IP address in the Target Group for the NLB. The Lambda would need to be triggered using an EventBridge Event at regular intervals to check for if the IP address associated with a Neptune endpoint ever changed.

profile picture
answered 16 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions