|
| 1 | +# Interaction with Neptune Cluster with IAM db authentication enabled |
| 2 | + |
| 3 | +## About |
| 4 | + |
| 5 | +This sample project shows how you can interact with a Neptune cluster when the |
| 6 | +IAM db authentication is enabled. |
| 7 | + |
| 8 | +According with the Neptune documentation, |
| 9 | +the AWS Identity and Access Management (IAM) is an AWS service |
| 10 | +that helps an administrator securely control access to AWS resources. |
| 11 | +IAM administrators control who can be authenticated (signed in) and authorized |
| 12 | +(have permissions) to use Neptune resources. |
| 13 | +IAM is an AWS service that you can use with no additional charge. |
| 14 | + |
| 15 | +You can use AWS Identity and Access Management (IAM) to authenticate to your Neptune DB instance or DB cluster. When IAM database authentication is enabled, each request must be signed using AWS Signature Version 4. |
| 16 | + |
| 17 | +## How to install it? |
| 18 | + |
| 19 | +This is a typescript [CDK](https://docs.aws.amazon.com/cdk/latest/guide/home.html) based project. |
| 20 | +CDK is a [NodeJS](https://nodejs.org/en/) module, and this is the only perquisite. |
| 21 | + |
| 22 | +This project was tested with NodeJs version 12.16.1. |
| 23 | + |
| 24 | +After you clone this repository, ensure that all the node dependencies are |
| 25 | +installed with the following command: |
| 26 | + |
| 27 | +```bash |
| 28 | +npm install |
| 29 | +``` |
| 30 | + |
| 31 | +After all the nodeJS dependencies are claimed you can install the CDK stack with |
| 32 | +the the following command: |
| 33 | + |
| 34 | +```bash |
| 35 | +./deploy.bash |
| 36 | +``` |
| 37 | + |
| 38 | +This operation will may take around 10 mins. If the deployment is successful |
| 39 | +then you may be able to see an output as the next one: |
| 40 | + |
| 41 | +```bash |
| 42 | +./deploy.bash |
| 43 | +...... |
| 44 | +...... |
| 45 | +Synth Complete, deploying Stack |
| 46 | +NeptuneRestIamStack: deploying... |
| 47 | +[0%] start: Publishing ff6804beac5d60d6ec143c1d10f08e10591a5d671f588baf1cabf18e27949177:current |
| 48 | +[100%] success: Published ff6804beac5d60d6ec143c1d10f08e10591a5d671f588baf1cabf18e27949177:current |
| 49 | +NeptuneRestIamStack: creating CloudFormation changeset... |
| 50 | +[██████████████████████████████████████████████████████████] (42/42) |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | + ✅ NeptuneRestIamStack |
| 55 | + |
| 56 | +Outputs: |
| 57 | +NeptuneRestIamStack.BulkLoaderRoleArn = arn:aws:iam::495161600685:role/NeptuneRestIamStack-NeptuneLoadFromS30422660D-G5ZI9V5C50J7 |
| 58 | +NeptuneRestIamStack.NeptuneClusterEndpoint = neptune-test-cluster.cluster-cl9mufznljov.eu-west-1.neptune.amazonaws.com |
| 59 | +NeptuneRestIamStack.NeptuneInstanceEndpoint = neptunedbinstance-wnxhffni670a.cl9mufznljov.eu-west-1.neptune.amazonaws.com |
| 60 | +NeptuneRestIamStack.SecurityGroupId = sg-0ead6abc144196f49 |
| 61 | +NeptuneRestIamStack.Subnets = subnet-0f759cdb19d8b13b3,subnet-081f56f0c0c288565 |
| 62 | + |
| 63 | +``` |
| 64 | + |
| 65 | +This CDK stack install an Neptune Cluster with IAM db authentication enabled and adds four six lambda able to interact with the Neptune Cluster. |
| 66 | + |
| 67 | +### Interaction with Neptune Cluster |
| 68 | + |
| 69 | +The interaction with the Neptune cluster can be done in two ways: |
| 70 | + |
| 71 | +1. over the Neptune REST API |
| 72 | +2. over the [Gremlin](https://tinkerpop.apache.org/gremlin.html) client. |
| 73 | + |
| 74 | +In botch cases you need to interact with the cluster you need to sing all the requests using |
| 75 | +[aws sig4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). |
| 76 | + |
| 77 | +#### REST Based interaction |
| 78 | + |
| 79 | +Here is an example for the REST based interaction |
| 80 | +originated from the bulkUploadHandler.ts file: |
| 81 | + |
| 82 | +```typescript |
| 83 | + try { |
| 84 | + const response = await neptunePost( |
| 85 | + process.env.NEPTUNE_ENDPOINT, |
| 86 | + process.env.NEPTUNE_PORT, |
| 87 | + process.env.AWS_DEFAULT_REGION, |
| 88 | + '/loader', |
| 89 | + body |
| 90 | + ); |
| 91 | + console.log( |
| 92 | + `File ${key} was processed with response response ${JSON.stringify( |
| 93 | + response, |
| 94 | + null, |
| 95 | + 2 |
| 96 | + )}.` |
| 97 | + ); |
| 98 | + } catch (e) { |
| 99 | + console.error(`File ${key} can not be processed.`); |
| 100 | + console.error(e); |
| 101 | + } |
| 102 | +``` |
| 103 | + |
| 104 | +The `neptunePost` method can be found in the utils.ts file. |
| 105 | +The `neptunePost` uses the [aws4-axios](https://www.npmjs.com/package/aws4-axios) |
| 106 | +to sign all the requests send to the Neptune Cluster using aws4. |
| 107 | +The aws4 library uses your secretAccessKey, accessKeyId and sessionToken in order to sing the request. |
| 108 | + |
| 109 | +If you use this code in a AWS Lambda, then the secretAccessKey, accessKeyId and sessionToken are obtained from the environment variables. |
| 110 | + |
| 111 | +Without a sign request all the attempts to communicate with Neptune cluster will end with HTTP 403 error. |
| 112 | + |
| 113 | +Here is the result bulkUploadHandlerv output after the file `edge.csv` was uploaded. |
| 114 | + |
| 115 | +`` |
| 116 | +2021-03-09T16:41:08.692Z 17c6d7a7-c870-42eb-9b36-9585fbfac76b INFO File edge.csv was processed with response response { |
| 117 | + "data": { |
| 118 | + "status": "200 OK", |
| 119 | + "payload": { |
| 120 | + "loadId": "f53d2153-95d4-4b23-b0af-b54753e353a5" |
| 121 | + } |
| 122 | + }, |
| 123 | + "status": 200, |
| 124 | + "statusText": "OK" |
| 125 | +}. |
| 126 | + |
| 127 | +`` |
| 128 | + |
| 129 | +Same logic for the clusterStateHandler and getAllBulkJobsHandler lambdas. |
| 130 | + |
| 131 | +#### Gremlin based interaction |
| 132 | + |
| 133 | +For Gremlin based access you need to use use a library able to sign the request. |
| 134 | +The next example uses the [gremlin-aws-sigv4](https://www.npmjs.com/package/gremlin-aws-sigv4) |
| 135 | + |
| 136 | +```typescript |
| 137 | +const countVerticesHandler: TaskHandler = async (event: any, context: any) => { |
| 138 | + const result: CountVerticesResult = await gremlinQuery( |
| 139 | + NEPTUNE_ENDPOINT, |
| 140 | + NEPTUNE_PORT, |
| 141 | + defaultGremlinOpts, |
| 142 | + context, |
| 143 | + countVertices, |
| 144 | + getVerticesCount |
| 145 | + ); |
| 146 | + console.log('countVertices=', result); |
| 147 | + return result; |
| 148 | +}; |
| 149 | + |
| 150 | +async function countVertices( |
| 151 | + g: gremlin.driver.AwsSigV4DriverRemoteConnection |
| 152 | +): Promise<any> { |
| 153 | + return g.V().count().next(); |
| 154 | +} |
| 155 | +``` |
| 156 | + |
| 157 | +The `gremlinQuery` method can be found in the utils.ts file. |
| 158 | +The `gremlinQuery` uses setup the gremlin client and cares about the signing |
| 159 | +the request. |
| 160 | +Same logic for: `addDataToNeptuneHandler`, `dropAllHandler` and `countVerticesHandler`. |
0 commit comments