

# Connecting to an Amazon Neptune cluster
<a name="get-started-connecting"></a>

After creating a Neptune cluster, you can configure the connection methods to access it.

## Setting up `curl` or awscurl to communicate with your Neptune endpoint
<a name="get-started-access-graph-curl"></a>

Having a command-line tool for submitting queries to your Neptune DB cluster is very handy, as illustrated in many of the examples in this documentation. The [curl](https://curl.haxx.se/) command line tool is an excellent option for communicating with Neptune endpoints when IAM authentication is not enabled. Versions starting with 7.75.0 support the `--aws-sigv4` option for signing requests when IAM authentication is enabled.

For endpoints where IAM authentication *is* enabled, you can also use [awscurl](https://github.com/okigan/awscurl), which uses almost exactly the same syntax as `curl` but supports signing requests as required for IAM authentication. Because of the added security that IAM authentication provides, it is generally a good idea to enable it.

 For information about how to use `curl` (or `awscurl`), see the [curl man page](https://curl.haxx.se/docs/manpage.html), and the book *[Everything curl](https://ec.haxx.se/)*.

To connect using HTTPS (which Neptune requires), `curl` needs access to appropriate certificates. As long as `curl` can locate the appropriate certificates, it handles HTTPS connections just like HTTP connections, without extra parameters. The same is true for `awscurl`. Examples in this documentation are based on that scenario.

To learn how to obtain such certificates and how to format them properly into a certificate authority (CA) certificate store that `curl` can use, see [SSL Certificate Verification](https://curl.haxx.se/docs/sslcerts.html) in the `curl` documentation.

You can then specify the location of this CA certificate store using the `CURL_CA_BUNDLE` environment variable. On Windows, `curl` automatically looks for it in a file named `curl-ca-bundle.crt`. It looks first in the same directory as `curl.exe` and then elsewhere on the path. For more information, see [SSL Certificate Verification](https://curl.haxx.se/docs/sslcerts.html).

## Different ways to connect to a Neptune DB cluster
<a name="get-started-connect-ways"></a>

An Amazon Neptune DB cluster can *only* be created in an Amazon Virtual Private Cloud (Amazon VPC). Its endpoints are accessible only within that VPC unless you enable and set up [Neptune public endpoints](neptune-public-endpoints.md) for the DB cluster.

There are several different ways to set up access to your Neptune DB cluster in its VPC:
+ [Connecting from an Amazon EC2 instance in the same VPC](get-started-connect-ec2-same-vpc.md)
+ [Connecting from an Amazon EC2 instance in another VPC](get-started-connect-ec2-other-vpc.md)
+ [Connecting from a private network](get-started-connect-private-net.md)
+ [Connecting from a public endpoint](neptune-public-endpoints.md)

# Connecting an Amazon EC2 instance to Amazon Neptune cluster in the same VPC
<a name="get-started-connect-ec2-same-vpc"></a>

One of the most common ways to connect to a Neptune database is from an Amazon EC2 instance in the same VPC as your Neptune DB cluster. For example, the EC2 instance might be running a web server that connects with the internet. In this case, only the EC2 instance has access to the Neptune DB cluster, and the internet only has access to the EC2 instance:

![\[Diagram of accessing a Neptune cluster from an EC2 instance in the same VPC.\]](http://docs.aws.amazon.com/neptune/latest/userguide/images/VPC-connection-01.png)


To enable this configuration, you need to have the right VPC security groups and subnet groups set up. The web server is hosted in a public subnet, so that it can reach the public internet, and your Neptune cluster instance is hosted in a private subnet to keep it secure. See [Set up the Amazon VPC where your Amazon Neptune DB cluster is located](get-started-vpc.md).

In order for the Amazon EC2 instance to connect to your Neptune endpoint on, for example, port `8182`, you will need to set up a security group to do that. If your Amazon EC2 instance is using a security group named, for example, `ec2-sg1`, you need to create another Amazon EC2 security group (let's say `db-sg1`) that has inbound rules for port `8182` and has `ec2-sg1` as its source. Then, add `db-sg1` to your Neptune cluster to allow the connection.

After creating the Amazon EC2 instance, you can log into it using SSH and connect to your Neptune DB cluster. For information about connecting to an EC2 instance using SSH, see [Connect to your Linux instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html) in the *Amazon EC2 User Guide*.

If you are using a Linux or macOS command line to connect to the EC2 instance, you can paste the SSH command from the **SSHAccess** item in the **Outputs** section of the CloudFormation stack. You must have the PEM file in the current directory and the PEM file permissions must be set to 400 (`chmod 400 keypair.pem`).

**To create a VPC with both private and public subnets**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the top-right corner of the AWS Management Console, choose the Region to create your VPC in.

1. In the **VPC Dashboard**, choose **Launch VPC Wizard**.

1. Complete the **VPC Settings** area of the **Create VPC** page:

   1. Under **Resources to create**, choose **VPC, subnets, etc.**.

   1. Leave the default name tag as is, or enter a name of your choosing, or un-check the **Auto-generate** check box to disable name tag generation.

   1. Leave the IPv4 CIDR block value at `10.0.0.0/16`.

   1. Leave the IPv6 CIDR block value at **No IPv6 CIDR block**.

   1. Leave the **Tenancy** at **Default**.

   1. Leave the number of **Availability Zones (AZs)** at **2**.

   1. Leave **NAT gateways (\$1)** at **None**, unless you will be needing one or more NAT gateways.

   1. Set **VPC endpoints** to **None**, unless you will be using Amazon S3.

   1. Both **Enable DNS hostnames** and **Enable DNS resolution** should be checked.

1. Choose **Create VPC**.

# Connecting an Amazon EC2 instance to an Amazon Neptune cluster in a different VPC
<a name="get-started-connect-ec2-other-vpc"></a>

An Amazon Neptune DB cluster can *only* be created in an Amazon Virtual Private Cloud (Amazon VPC), and its endpoints are accessible within that VPC, usually from an Amazon Elastic Compute Cloud (Amazon EC2) instance running in that VPC. Alternatively, it can be accessed using a public endpoint. For more information on public endpoints, see [Neptune public endpoints](neptune-public-endpoints.md). 

When your DB cluster is in a different VPC from the EC2 instance you are using to access it, you can use [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html) to make the connection:

![\[Diagram of accessing a Neptune cluster from a different VPC.\]](http://docs.aws.amazon.com/neptune/latest/userguide/images/VPC-connection-02.png)


A VPC peering connection is a networking connection between two VPCs that routes traffic between them privately, so that instances in either VPC can communicate as if they are within the same network. You can create a VPC peering connection between VPCs in your account, between a VPC in your AWS account and a VPC in another AWS account, or with a VPC in a different AWS Region.

AWS uses the existing infrastructure of a VPC to create a VPC peering connection. It is neither a gateway nor an AWS Site-to-Site VPN connection, and it does not rely on a separate piece of physical hardware. It has no single point of failure for communication and no bandwidth bottleneck.

See the [Amazon VPC Peering Guide](https://docs.aws.amazon.com/vpc/latest/peering/) for more information about how use VPC peering.

# Connecting to an Amazon Neptune cluster over a private network
<a name="get-started-connect-private-net"></a>

You can access a Neptune DB cluster from a private network in two different ways:
+ Using an [AWS Site-to-Site VPN](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html) connection.
+ Using an [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/) connection.

The links above have information about these connection methods and how to set them up. The configuration of an AWS Site-to-Site connection might look like this:

![\[Diagram of accessing a Neptune cluster from a private network.\]](http://docs.aws.amazon.com/neptune/latest/userguide/images/VPC-connection-04.png)


# Neptune Public Endpoints
<a name="neptune-public-endpoints"></a>

## Overview
<a name="neptune-public-endpoints-overview"></a>

Amazon Neptune clusters are typically deployed within your VPC and can only be accessed from within that VPC. This requires configuring applications and development environments within the VPC or using proxy services to connect to the VPC, which increases setup time and costs.

Public endpoints simplify this experience by allowing direct connections to Neptune over the internet, making it easier to get started with graph databases without specialized networking knowledge.

## When to use public endpoints
<a name="neptune-public-endpoints-when-to-use"></a>

Consider using public endpoints in the following scenarios:
+ You want to quickly test Neptune in a development or test environment without complex network configuration
+ You don't have specialized AWS networking knowledge
+ Your application's security posture doesn't require a private VPC
+ You need to connect to Neptune from your local development environment

## Security considerations
<a name="neptune-public-endpoints-security"></a>

When using public endpoints, keep these security considerations in mind:
+ IAM authentication is required for clusters with public endpoints enabled.
+ Access to the database is controlled by the security group it uses.
+ You can restrict which IP addresses can connect to your cluster.
+ You can use IAM policies to control who can create or modify clusters with public access. See: [Restricting public access creation](#neptune-public-endpoints-restrict-access)

## Enabling public endpoints
<a name="neptune-public-endpoints-enabling"></a>

By default, new Neptune databases are created with public endpoints disabled. You must explicitly enable public access when creating or modifying a cluster.

Public endpoints are supported from Neptune engine release version 1.4.6.x. You need to upgrade existing clusters to at least this version to use this feature.

Public endpoint setting is available on the Neptune instance and not the Neptune cluster. Hence, a Neptune cluster can exist with some instances with public endpoints and some with not. However, we don't recommend having such a setting. For more information on this refer to: [How public endpoints work](#neptune-public-endpoints-how-they-work)

## Prerequisites
<a name="neptune-public-endpoints-prerequisites"></a>

### IAM authentication setting on the Neptune cluster
<a name="neptune-public-endpoints-iam-auth"></a>

Before enabling public endpoints on a Neptune instance, ensure your cluster supports IAM authentication. If not, enable it using the following command:

```
aws neptune modify-db-cluster \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-cluster-identifier neptune-public-endpoint \
  --enable-iam-database-authentication
```

### Network settings
<a name="neptune-public-endpoints-network-settings"></a>

1. Ensure your VPC has subnets that enable public routing (has an entry for an internet gateway in the route table of the subnets). If you don't provide a `db-subnet-group-name` parameter while creating the cluster, the default subnet group is picked for the cluster creation.

1. Make sure the security group attached to the cluster allows inbound traffic for the allowed IP ranges and the allowed ports. For example, if you want to allow TCP traffic from all IPs to connect to the Neptune instance running on port 8182, the inbound rule should have:

   1. Type: All TCP

   1. Protocol: TCP

   1. Port range: 8182

   1. CIDR block: 0.0.0.0/0

**Note**  
Although you can set the CIDR block range to 0.0.0.0/0, we recommend reducing this to a specific IP range of your client application for a better security posture.

## Creating a new instance with public endpoints
<a name="neptune-public-endpoints-creating-instance"></a>

You can create a new Neptune instance with public endpoints using the AWS Management Console, AWS CLI, or AWS SDK.

Using the AWS CLI:

```
aws neptune create-db-instance \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-cluster-identifier neptune-public-endpoint \
  --publicly-accessible
```

## Modifying an existing instance for public access
<a name="neptune-public-endpoints-modifying-instance"></a>

To modify an existing Neptune instance to enable public access:

```
aws neptune modify-db-instance \
  --region us-west-2 \
  --engine graphdb \
  --engine-version 1.4.6.x \
  --db-instance-identifier neptune-public-endpoint \
  --publicly-accessible
```

**Note**  
Public access is enabled at the instance level, not the cluster level. To ensure your cluster is always accessible via public endpoints, all instances in the cluster must have public access enabled.

## Using the public endpoints
<a name="neptune-public-endpoints-using"></a>

To check if your database is reachable, check the status using the AWS CLI `NeptuneData` API:

```
aws neptunedata get-engine-status \
  --endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

If the database is accessible, the response is like:

```
{
    "status": "healthy",
    "startTime": "Sun Aug 10 06:54:15 UTC 2025",
    "dbEngineVersion": "1.4.6.0.R1",
    "role": "writer",
    "dfeQueryEngine": "viaQueryHint",
    "gremlin": {
        "version": "tinkerpop-3.7.1"
    },
    "sparql": {
        "version": "sparql-1.1"
    },
    "opencypher": {
        "version": "Neptune-9.0.20190305-1.0"
    },
    "labMode": {
        "ObjectIndex": "disabled",
        "ReadWriteConflictDetection": "enabled"
    },
    "features": {
        "SlowQueryLogs": "disabled",
        "InlineServerGeneratedEdgeId": "disabled",
        "ResultCache": {
            "status": "disabled"
        },
        "IAMAuthentication": "disabled",
        "Streams": "disabled",
        "AuditLog": "disabled"
    },
    "settings": {
        "StrictTimeoutValidation": "true",
        "clusterQueryTimeoutInMs": "120000",
        "SlowQueryLogsThreshold": "5000"
    }
}
```

## Examples of how to query the database
<a name="neptune-public-endpoints-examples"></a>

### AWS CLI
<a name="neptune-public-endpoints-aws-cli"></a>

```
aws neptunedata execute-open-cypher-query \
--open-cypher-query "MATCH (n) RETURN n LIMIT 10" \
--endpoint-url https://my-cluster-name.cluster-abcdefgh1234.us-east-1.neptune.amazonaws.com:8182
```

### Python
<a name="neptune-public-endpoints-python"></a>

```
import boto3
import json
from botocore.config import Config

# Configuration - Replace with your actual Neptune cluster details
cluster_endpoint = "my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com"
port = 8182
region = "my-region"

# Configure Neptune client
# This disables retries and sets the client timeout to infinite 
#     (relying on Neptune's query timeout)
endpoint_url = f"https://{cluster_endpoint}:{port}"
config = Config(
    region_name=region,
    retries={'max_attempts': 1},
    read_timeout=None
)

client = boto3.client("neptunedata", config=config, endpoint_url=endpoint_url)

cypher_query = "MATCH (n) RETURN n LIMIT 5"
try:
    response = client.execute_open_cypher_query(openCypherQuery=cypher_query)
    print("openCypher Results:")
    for item in response.get('results', []):
        print(f"  {item}")
except Exception as e:
    print(f"openCypher query failed: {e}")
```

### JavaScript
<a name="neptune-public-endpoints-javascript"></a>

```
import {
    NeptunedataClient,
    GetPropertygraphSummaryCommand
} from "@aws-sdk/client-neptunedata";
import { inspect } from "util";
import { NodeHttpHandler } from "@smithy/node-http-handler";

/**
 * Main execution function
 */
async function main() {
    // Configuration - Replace with your actual Neptune cluster details
    const clusterEndpoint = 'my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com';
    const port = 8182;
    const region = 'my-region';

    // Configure Neptune client
    // This disables retries and sets the client timeout to infinite 
    //     (relying on Neptune's query timeout)
    const endpoint = `https://${clusterEndpoint}:${port}`;
    const clientConfig = {
        endpoint: endpoint,
        sslEnabled: true,
        region: region,
        maxAttempts: 1,  // do not retry
        requestHandler: new NodeHttpHandler({
            requestTimeout: 0  // no client timeout
        })
    };

    const client = new NeptunedataClient(clientConfig);
    try {
        try {
            const command = new GetPropertygraphSummaryCommand({ mode: "basic" });
            const response = await client.send(command);
            console.log("Graph Summary:", inspect(response.payload, { depth: null }));
        } catch (error) {
            console.log("Property graph summary failed:", error.message);
        }    
    } catch (error) {
        console.error("Error in main execution:", error);
    }
}

// Run the main function
main().catch(console.error);
```

### Go
<a name="neptune-public-endpoints-go"></a>

```
package main
import (
    "context"
    "fmt"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/neptunedata"
    "os"
    "encoding/json"
    "net/http"
)

func main() {    
    // Configuration - Replace with your actual Neptune cluster details
    clusterEndpoint := "my-cluster-name.cluster-abcdefgh1234.my-region.neptune.amazonaws.com"
    port := 8182
    region := "my-region"
    
    // Configure Neptune client
    // Configure HTTP client with no timeout
    //    (relying on Neptune's query timeout)
    endpoint := fmt.Sprintf("https://%s:%d", clusterEndpoint, port)
    // Load AWS SDK configuration
    sdkConfig, _ := config.LoadDefaultConfig(
        context.TODO(),
        config.WithRegion(region),
        config.WithHTTPClient(&http.Client{Timeout: 0}),
    )
    
    // Create Neptune client with custom endpoint
    client := neptunedata.NewFromConfig(sdkConfig, func(o *neptunedata.Options) {
        o.BaseEndpoint = aws.String(endpoint)
        o.Retryer = aws.NopRetryer{} // Do not retry calls if they fail
    })

    gremlinQuery := "g.addV('person').property('name','charlie').property(id,'charlie-1')"
    serializer := "application/vnd.gremlin-v1.0+json;types=false"
    
    gremlinInput := &neptunedata.ExecuteGremlinQueryInput{
        GremlinQuery: &gremlinQuery,
        Serializer:   &serializer,
    }
    gremlinResult, err := client.ExecuteGremlinQuery(context.TODO(), gremlinInput)
    if err != nil {
        fmt.Printf("Gremlin query failed: %v\n", err)
    } else {
        var resultMap map[string]interface{}
        err = gremlinResult.Result.UnmarshalSmithyDocument(&resultMap)
        if err != nil {
            fmt.Printf("Error unmarshaling Gremlin result: %v\n", err)
        } else {
            resultJSON, _ := json.MarshalIndent(resultMap, "", "  ")
            fmt.Printf("Gremlin Result: %s\n", string(resultJSON))
        }
    }
}
```

## How public endpoints work
<a name="neptune-public-endpoints-how-they-work"></a>

When a Neptune instance is publicly accessible:
+ Its DNS endpoint resolves to the private IP address from within the DB cluster's VPC.
+ It resolves to the public IP address from outside of the cluster's VPC.
+ Access is controlled by the security group assigned to the cluster.
+ Only instances that are publicly accessible can be accessed via the internet.

### Reader endpoint behavior
<a name="neptune-public-endpoints-reader-behavior"></a>
+ If all reader instances are publicly accessible, the reader endpoint will always resolve over the public internet.
+ If only some reader instances are publicly accessible, the reader endpoint will resolve publicly only if it selects a publicly accessible instance to serve the read query.

### Cluster endpoint behavior
<a name="neptune-public-endpoints-cluster-behavior"></a>
+ The DB cluster endpoint always resolves to the instance endpoint of the writer.
+ If public endpoint is enabled on the writer instance, the cluster endpoint will be publicly accessible, otherwise it won't be.

### Behavior after cluster failover
<a name="neptune-public-endpoints-failover-behavior"></a>
+ A Neptune cluster can have instances on different public accessible setting.
+ If a cluster has a public writer and a non-public reader, post a cluster failover, the new writer (previous reader) becomes non-public and the new reader (previous writer) becomes public.

## Network configuration requirements
<a name="neptune-public-endpoints-network-requirements"></a>

For public endpoints to work properly:

1. The Neptune instances must be in public subnets within your VPC.

1. The route tables associated with these subnets must have a route to an internet gateway for 0.0.0.0/0.

1. The security group must allow access from the public IP addresses or CIDR ranges you want to grant access to.

## Restricting public access creation
<a name="neptune-public-endpoints-restrict-access"></a>

You can use IAM policies to restrict who can create or modify Neptune clusters with public access. The following example policy denies the creation of Neptune instances with public access:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBInstance",
        "rds:ModifyDBInstance",
        "rds:RestoreDBInstanceFromDBSnapshot",
        "rds:RestoreDBInstanceToPointInTime"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "rds:PubliclyAccessible": true
        }
      }
    }
  ]
}
```

------

More about the `rds:PublicAccessEnabled` IAM condition key: [ Amazon RDS Service Authorization Reference](https://docs.aws.amazon.com//service-authorization/latest/reference/list_amazonrds.html#amazonrds-rds_PubliclyAccessible)

## CloudFormation support
<a name="neptune-public-endpoints-cloudformation"></a>

You can use CloudFormation to launch Neptune clusters with public endpoints enabled by specifying the `PubliclyAccessible` parameter in your CloudFormation template.

## Compatibility with Neptune features
<a name="neptune-public-endpoints-compatibility"></a>

A cluster with public endpoints enabled supports all Neptune features that a VPC-only cluster supports, including:
+ Neptune workbench
+ Full text search integration
+ Neptune Streams
+ Custom endpoints
+ Neptune Serverless
+ Graph Explorer

## Pricing
<a name="neptune-public-endpoints-pricing"></a>

Public endpoints are available at no additional cost beyond standard Neptune pricing. However, connecting from your local environment to Neptune over a public IP might incur increased data transfer costs.