Skip to content

Commit

Permalink
feat(neptune): introduce cluster grant method for granular actions (#…
Browse files Browse the repository at this point in the history
…21926)

- neptune engine version 1.2.0.0 introduced more granular access control https://docs.aws.amazon.com/neptune/latest/userguide/iam-dp-actions.html
- introduce grant method to facilitate working with different actions

#21877 
----

This PR is split from #21908 as per the discussion with @TheRealAmazonKendra 

### All Submissions:

* [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
humanzz committed Sep 9, 2022
1 parent 38f8d89 commit 42e559d
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 11 deletions.
6 changes: 4 additions & 2 deletions packages/@aws-cdk/aws-neptune/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ The following example shows enabling IAM authentication for a database cluster a
const cluster = new neptune.DatabaseCluster(this, 'Cluster', {
vpc,
instanceType: neptune.InstanceType.R5_LARGE,
iamAuthentication: true, // Optional - will be automatically set if you call grantConnect().
iamAuthentication: true, // Optional - will be automatically set if you call grantConnect() or grant().
});
const role = new iam.Role(this, 'DBRole', { assumedBy: new iam.AccountPrincipal(this.account) });
cluster.grantConnect(role); // Grant the role neptune-db:* access to the DB.
// Use one of the following statements to grant the role the necessary permissions
cluster.grantConnect(role); // Grant the role neptune-db:* access to the DB
cluster.grant(role, 'neptune-db:ReadDataViaQuery', 'neptune-db:WriteDataViaQuery'); // Grant the role the specified actions to the DB
```

## Customizing parameters
Expand Down
19 changes: 16 additions & 3 deletions packages/@aws-cdk/aws-neptune/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ export interface IDatabaseCluster extends IResource, ec2.IConnectable {
*/
readonly clusterReadEndpoint: Endpoint;

/**
* Grant the given identity the specified actions
* @param grantee the identity to be granted the actions
* @param actions the data-access actions
*
* @see https://docs.aws.amazon.com/neptune/latest/userguide/iam-dp-actions.html
*/
grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant;

/**
* Grant the given identity connection access to the database.
*/
Expand Down Expand Up @@ -364,15 +373,15 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC

protected abstract enableIamAuthentication?: boolean;

public grantConnect(grantee: iam.IGrantable): iam.Grant {
public grant(grantee: iam.IGrantable, ...actions: string[]): iam.Grant {
if (this.enableIamAuthentication === false) {
throw new Error('Cannot grant connect when IAM authentication is disabled');
throw new Error('Cannot grant permissions when IAM authentication is disabled');
}

this.enableIamAuthentication = true;
return iam.Grant.addToPrincipal({
grantee,
actions: ['neptune-db:*'],
actions,
resourceArns: [
[
'arn',
Expand All @@ -385,6 +394,10 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC
],
});
}

public grantConnect(grantee: iam.IGrantable): iam.Grant {
return this.grant(grantee, 'neptune-db:*');
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "21.0.0",
"files": {
"06bc77521a70e494cf9fb7d601f5111e19745b0ecde4b6ac42b311f1a19f8328": {
"86dda049435a7e62de07d7e302f55c3c286433c9f4736de7c9bee4336473b1c7": {
"source": {
"path": "aws-cdk-neptune-integ.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "06bc77521a70e494cf9fb7d601f5111e19745b0ecde4b6ac42b311f1a19f8328.json",
"objectKey": "86dda049435a7e62de07d7e302f55c3c286433c9f4736de7c9bee4336473b1c7.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,74 @@
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"Role1ABCC5F0": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "sagemaker.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"Description": "AWS Sagemaker notebooks role example for interacting with Neptune Database Cluster"
}
},
"RoleDefaultPolicy5FFB7DAB": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"neptune-db:GetEngineStatus",
"neptune-db:ReadDataViaQuery"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":neptune-db:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
{
"Fn::GetAtt": [
"DatabaseB269D8BB",
"ClusterResourceId"
]
},
"/*"
]
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "RoleDefaultPolicy5FFB7DAB",
"Roles": [
{
"Ref": "Role1ABCC5F0"
}
]
}
},
"ParamsA8366201": {
"Type": "AWS::Neptune::DBClusterParameterGroup",
"Properties": {
Expand Down Expand Up @@ -503,6 +571,7 @@
"Ref": "DatabaseSubnets3C9252C9"
},
"EngineVersion": "1.2.0.0",
"IamAuthEnabled": true,
"KmsKeyId": {
"Fn::GetAtt": [
"DbSecurity381C2C15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"validateOnSynth": false,
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/06bc77521a70e494cf9fb7d601f5111e19745b0ecde4b6ac42b311f1a19f8328.json",
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/86dda049435a7e62de07d7e302f55c3c286433c9f4736de7c9bee4336473b1c7.json",
"requiresBootstrapStackVersion": 6,
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
"additionalDependencies": [
Expand Down Expand Up @@ -183,6 +183,18 @@
"data": "DbSecurity381C2C15"
}
],
"/aws-cdk-neptune-integ/Role/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "Role1ABCC5F0"
}
],
"/aws-cdk-neptune-integ/Role/DefaultPolicy/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "RoleDefaultPolicy5FFB7DAB"
}
],
"/aws-cdk-neptune-integ/Params/Resource": [
{
"type": "aws:cdk:logicalId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,110 @@
"version": "0.0.0"
}
},
"Role": {
"id": "Role",
"path": "aws-cdk-neptune-integ/Role",
"children": {
"Resource": {
"id": "Resource",
"path": "aws-cdk-neptune-integ/Role/Resource",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::IAM::Role",
"aws:cdk:cloudformation:props": {
"assumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "sagemaker.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"description": "AWS Sagemaker notebooks role example for interacting with Neptune Database Cluster"
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-iam.CfnRole",
"version": "0.0.0"
}
},
"DefaultPolicy": {
"id": "DefaultPolicy",
"path": "aws-cdk-neptune-integ/Role/DefaultPolicy",
"children": {
"Resource": {
"id": "Resource",
"path": "aws-cdk-neptune-integ/Role/DefaultPolicy/Resource",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::IAM::Policy",
"aws:cdk:cloudformation:props": {
"policyDocument": {
"Statement": [
{
"Action": [
"neptune-db:GetEngineStatus",
"neptune-db:ReadDataViaQuery"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":neptune-db:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":",
{
"Fn::GetAtt": [
"DatabaseB269D8BB",
"ClusterResourceId"
]
},
"/*"
]
]
}
}
],
"Version": "2012-10-17"
},
"policyName": "RoleDefaultPolicy5FFB7DAB",
"roles": [
{
"Ref": "Role1ABCC5F0"
}
]
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-iam.CfnPolicy",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-iam.Policy",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-iam.Role",
"version": "0.0.0"
}
},
"Params": {
"id": "Params",
"path": "aws-cdk-neptune-integ/Params",
Expand Down Expand Up @@ -856,6 +960,7 @@
"Ref": "DatabaseSubnets3C9252C9"
},
"engineVersion": "1.2.0.0",
"iamAuthEnabled": true,
"kmsKeyId": {
"Fn::GetAtt": [
"DbSecurity381C2C15",
Expand Down
Loading

0 comments on commit 42e559d

Please sign in to comment.