cdk-rds-sql 6.1.3 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -7,10 +7,10 @@
7
7
  ]
8
8
  },
9
9
  "bundled": {
10
- "@types/aws-lambda": "^8.10.148"
10
+ "@types/aws-lambda": "^8.10.150"
11
11
  },
12
12
  "dependencies": {
13
- "aws-cdk-lib": "^2.171.1",
13
+ "aws-cdk-lib": "^2.189.1",
14
14
  "constructs": "^10.3.0"
15
15
  },
16
16
  "dependencyClosure": {
@@ -40,32 +40,6 @@
40
40
  }
41
41
  }
42
42
  },
43
- "@aws-cdk/asset-kubectl-v20": {
44
- "targets": {
45
- "dotnet": {
46
- "namespace": "Amazon.CDK.Asset.KubectlV20",
47
- "packageId": "Amazon.CDK.Asset.KubectlV20"
48
- },
49
- "go": {
50
- "moduleName": "github.com/cdklabs/awscdk-asset-kubectl-go",
51
- "packageName": "kubectlv20"
52
- },
53
- "java": {
54
- "maven": {
55
- "artifactId": "cdk-asset-kubectl-v20",
56
- "groupId": "software.amazon.awscdk"
57
- },
58
- "package": "software.amazon.awscdk.cdk.asset.kubectl.v20"
59
- },
60
- "js": {
61
- "npm": "@aws-cdk/asset-kubectl-v20"
62
- },
63
- "python": {
64
- "distName": "aws-cdk.asset-kubectl-v20",
65
- "module": "aws_cdk.asset_kubectl_v20"
66
- }
67
- }
68
- },
69
43
  "@aws-cdk/asset-node-proxy-agent-v6": {
70
44
  "targets": {
71
45
  "dotnet": {
@@ -970,6 +944,19 @@
970
944
  }
971
945
  }
972
946
  },
947
+ "aws-cdk-lib.aws_cognito_identitypool": {
948
+ "targets": {
949
+ "dotnet": {
950
+ "namespace": "Amazon.CDK.AWS.Cognito.Identitypool"
951
+ },
952
+ "java": {
953
+ "package": "software.amazon.awscdk.services.cognito.identitypool"
954
+ },
955
+ "python": {
956
+ "module": "aws_cdk.aws_cognito_identitypool"
957
+ }
958
+ }
959
+ },
973
960
  "aws-cdk-lib.aws_comprehend": {
974
961
  "targets": {
975
962
  "dotnet": {
@@ -1256,6 +1243,19 @@
1256
1243
  }
1257
1244
  }
1258
1245
  },
1246
+ "aws-cdk-lib.aws_dsql": {
1247
+ "targets": {
1248
+ "dotnet": {
1249
+ "package": "Amazon.CDK.AWS.DSQL"
1250
+ },
1251
+ "java": {
1252
+ "package": "software.amazon.awscdk.services.dsql"
1253
+ },
1254
+ "python": {
1255
+ "module": "aws_cdk.aws_dsql"
1256
+ }
1257
+ }
1258
+ },
1259
1259
  "aws-cdk-lib.aws_dynamodb": {
1260
1260
  "targets": {
1261
1261
  "dotnet": {
@@ -1646,6 +1646,19 @@
1646
1646
  }
1647
1647
  }
1648
1648
  },
1649
+ "aws-cdk-lib.aws_gameliftstreams": {
1650
+ "targets": {
1651
+ "dotnet": {
1652
+ "package": "Amazon.CDK.AWS.GameLiftStreams"
1653
+ },
1654
+ "java": {
1655
+ "package": "software.amazon.awscdk.services.gameliftstreams"
1656
+ },
1657
+ "python": {
1658
+ "module": "aws_cdk.aws_gameliftstreams"
1659
+ }
1660
+ }
1661
+ },
1649
1662
  "aws-cdk-lib.aws_globalaccelerator": {
1650
1663
  "targets": {
1651
1664
  "dotnet": {
@@ -1854,29 +1867,29 @@
1854
1867
  }
1855
1868
  }
1856
1869
  },
1857
- "aws-cdk-lib.aws_iot": {
1870
+ "aws-cdk-lib.aws_invoicing": {
1858
1871
  "targets": {
1859
1872
  "dotnet": {
1860
- "namespace": "Amazon.CDK.AWS.IoT"
1873
+ "package": "Amazon.CDK.AWS.Invoicing"
1861
1874
  },
1862
1875
  "java": {
1863
- "package": "software.amazon.awscdk.services.iot"
1876
+ "package": "software.amazon.awscdk.services.invoicing"
1864
1877
  },
1865
1878
  "python": {
1866
- "module": "aws_cdk.aws_iot"
1879
+ "module": "aws_cdk.aws_invoicing"
1867
1880
  }
1868
1881
  }
1869
1882
  },
1870
- "aws-cdk-lib.aws_iot1click": {
1883
+ "aws-cdk-lib.aws_iot": {
1871
1884
  "targets": {
1872
1885
  "dotnet": {
1873
- "namespace": "Amazon.CDK.AWS.IoT1Click"
1886
+ "namespace": "Amazon.CDK.AWS.IoT"
1874
1887
  },
1875
1888
  "java": {
1876
- "package": "software.amazon.awscdk.services.iot1click"
1889
+ "package": "software.amazon.awscdk.services.iot"
1877
1890
  },
1878
1891
  "python": {
1879
- "module": "aws_cdk.aws_iot1click"
1892
+ "module": "aws_cdk.aws_iot"
1880
1893
  }
1881
1894
  }
1882
1895
  },
@@ -2569,6 +2582,32 @@
2569
2582
  }
2570
2583
  }
2571
2584
  },
2585
+ "aws-cdk-lib.aws_notifications": {
2586
+ "targets": {
2587
+ "dotnet": {
2588
+ "package": "Amazon.CDK.AWS.Notifications"
2589
+ },
2590
+ "java": {
2591
+ "package": "software.amazon.awscdk.services.notifications"
2592
+ },
2593
+ "python": {
2594
+ "module": "aws_cdk.aws_notifications"
2595
+ }
2596
+ }
2597
+ },
2598
+ "aws-cdk-lib.aws_notificationscontacts": {
2599
+ "targets": {
2600
+ "dotnet": {
2601
+ "package": "Amazon.CDK.AWS.NotificationsContacts"
2602
+ },
2603
+ "java": {
2604
+ "package": "software.amazon.awscdk.services.notificationscontacts"
2605
+ },
2606
+ "python": {
2607
+ "module": "aws_cdk.aws_notificationscontacts"
2608
+ }
2609
+ }
2610
+ },
2572
2611
  "aws-cdk-lib.aws_oam": {
2573
2612
  "targets": {
2574
2613
  "dotnet": {
@@ -2725,6 +2764,19 @@
2725
2764
  }
2726
2765
  }
2727
2766
  },
2767
+ "aws-cdk-lib.aws_pcs": {
2768
+ "targets": {
2769
+ "dotnet": {
2770
+ "package": "Amazon.CDK.AWS.PCS"
2771
+ },
2772
+ "java": {
2773
+ "package": "software.amazon.awscdk.services.pcs"
2774
+ },
2775
+ "python": {
2776
+ "module": "aws_cdk.aws_pcs"
2777
+ }
2778
+ }
2779
+ },
2728
2780
  "aws-cdk-lib.aws_personalize": {
2729
2781
  "targets": {
2730
2782
  "dotnet": {
@@ -3180,6 +3232,19 @@
3180
3232
  }
3181
3233
  }
3182
3234
  },
3235
+ "aws-cdk-lib.aws_s3tables": {
3236
+ "targets": {
3237
+ "dotnet": {
3238
+ "package": "Amazon.CDK.AWS.S3Tables"
3239
+ },
3240
+ "java": {
3241
+ "package": "software.amazon.awscdk.services.s3tables"
3242
+ },
3243
+ "python": {
3244
+ "module": "aws_cdk.aws_s3tables"
3245
+ }
3246
+ }
3247
+ },
3183
3248
  "aws-cdk-lib.aws_sagemaker": {
3184
3249
  "targets": {
3185
3250
  "dotnet": {
@@ -3219,6 +3284,19 @@
3219
3284
  }
3220
3285
  }
3221
3286
  },
3287
+ "aws-cdk-lib.aws_scheduler_targets": {
3288
+ "targets": {
3289
+ "dotnet": {
3290
+ "namespace": "Amazon.CDK.AWS.Scheduler.Targets"
3291
+ },
3292
+ "java": {
3293
+ "package": "software.amazon.awscdk.services.scheduler.targets"
3294
+ },
3295
+ "python": {
3296
+ "module": "aws_cdk.aws_scheduler_targets"
3297
+ }
3298
+ }
3299
+ },
3222
3300
  "aws-cdk-lib.aws_sdb": {
3223
3301
  "targets": {
3224
3302
  "dotnet": {
@@ -3766,19 +3844,6 @@
3766
3844
  }
3767
3845
  }
3768
3846
  },
3769
- "aws-cdk-lib.lambda_layer_kubectl": {
3770
- "targets": {
3771
- "dotnet": {
3772
- "namespace": "Amazon.CDK.LambdaLayer.Kubectl"
3773
- },
3774
- "java": {
3775
- "package": "software.amazon.awscdk.lambdalayer.kubectl"
3776
- },
3777
- "python": {
3778
- "module": "aws_cdk.lambda_layer_kubectl"
3779
- }
3780
- }
3781
- },
3782
3847
  "aws-cdk-lib.lambda_layer_node_proxy_agent": {
3783
3848
  "targets": {
3784
3849
  "dotnet": {
@@ -3884,12 +3949,12 @@
3884
3949
  }
3885
3950
  }
3886
3951
  },
3887
- "description": "A CDK construct that allows creating roles and databases an on Aurora Serverless Postgresql cluster.",
3952
+ "description": "A CDK construct that allows creating roles or users and databases an on Aurora Serverless Postgresql or Mysql/MariaDB cluster.",
3888
3953
  "docs": {
3889
3954
  "stability": "stable"
3890
3955
  },
3891
3956
  "homepage": "https://github.com/berenddeboer/cdk-rds-sql.git",
3892
- "jsiiVersion": "5.7.10 (build 5114b23)",
3957
+ "jsiiVersion": "5.7.20 (build 433aee4)",
3893
3958
  "keywords": [
3894
3959
  "aurora",
3895
3960
  "aws",
@@ -3910,7 +3975,7 @@
3910
3975
  },
3911
3976
  "name": "cdk-rds-sql",
3912
3977
  "readme": {
3913
- "markdown": "# About\n\nThis CDK construct library makes it possible to create databases,\nschemas, and roles in an Aurora Serverless v2, RDS Database Cluster or\nDatabase Instance. Both PostgreSQL and MySQL databases are supported.\n\nThis construct library is intended to be used in enterprise\nenvironments, and works in isolated subnets.\n\n<p align=\"left\">\n <a href=\"https://github.com/semantic-release/semantic-release\"><img src=\"https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release\" alt=semantic-release: angular\"></a>\n <a href=\"https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml\"><img src=\"https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml/badge.svg\" alt=\"Release badge\"></a>\n</p>\n\n# Requirements\n\n- CDK v2.\n\n# Installation\n\n npm i cdk-rds-sql\n\n# Usage\n\n## Provider\n\nFirst setup your VPC and create your cluster:\n\n```ts\nimport { Duration, RemovalPolicy } from \"aws-cdk-lib\"\nimport * as ec2 from \"aws-cdk-lib/aws-ec2\"\nimport * as rds from \"aws-cdk-lib/aws-rds\"\n\nconst vpc = ec2.Vpc.fromLookup(this, \"Vpc\", {\n vpcId: this.node.tryGetContext(\"vpc-id\"),\n})\n\nconst cluster = new rds.ServerlessCluster(this, \"Cluster\", {\n vpc: vpc,\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_ISOLATED,\n },\n engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,\n parameterGroup: rds.ParameterGroup.fromParameterGroupName(\n this,\n \"ParameterGroup\",\n \"default.aurora-postgresql11\"\n ),\n removalPolicy: RemovalPolicy.DESTROY,\n scaling: {\n autoPause: Duration.minutes(60),\n minCapacity: rds.AuroraCapacityUnit.ACU_2,\n maxCapacity: rds.AuroraCapacityUnit.ACU_2,\n },\n})\n```\n\nThen create a provider which will connect to your database. For a cluster:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n cluster: cluster,\n secret: cluster.secret!,\n})\n```\n\nFor an instance:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n instance: instance,\n secret: cluster.secret!,\n})\n```\n\nThe provider will setup a lambda, which normally lives in the same VPC\nas the database. You can give a different VPC, as long as that VPC has\naccess to the VPC of the database. Only the provider lambda will talk\nto your database.\n\nThe provider will by default use the private isolated subnet of the\nVPC. Your isolated network must have a VPC endpoint to AWS Secrets Manager\nand possibly KMS as well. If you want to use a subnet with egress\naccess in case you have no such VPC endpoints, specify the subnet as\nfollows:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,\n },\n cluster: cluster,\n secret: cluster.secret!,\n})\n```\n\n### Disabling SSL\n\nThe default connection to RDS is ssl enabled (this used to be disabled\nin versions below 4).\n\nYou can disable ssl by setting the `ssl` option to `false`:\n\n```ts\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n instance: instance,\n secret: cluster.secret!,\n ssl: false, // default is true\n})\n```\n\n## Roles\n\nCreate a postgres role (or mysql user) for a cluster as follows:\n\n```ts\nimport { Role } from \"cdk-rds-sql\"\n\nconst role = new Role(this, \"Role\", {\n provider: provider,\n roleName: \"myrole\",\n databaseName: \"mydb\",\n})\n```\n\nThis will automatically create a secret just like `ServerlessCluster`\ndoes, with all the connection info needed for this user. It's secret value is a JSON like:\n\n```json\n{\n \"dbClusterIdentifier\": \"teststack-clustereb1186t9-sh4wpqfdyfvu\",\n \"password\": \"very-long-and-boring\",\n \"dbname\": \"mydb\",\n \"engine\": \"postgres\",\n \"port\": 5432,\n \"host\": \"teststack-clustereb1186t9-sh4wpqfdyfvu.cluster-cgudolabssna.us-east-1.rds.amazonaws.com\",\n \"username\": \"myrole\"\n}\n```\n\nYou can access the secret via `role.secret`.\n\nInstead of `databaseName` you can also specify `database` to reference\nan existing database. The role will not be created until the database\nhas been created.\n\nIf you want to make the role the owner of a new database, just specify\nthe `databaseName` here, and create the database later.\n\n### IAM Authentication\n\nInstead of password-based authentication, you can create roles that use AWS IAM database authentication. This eliminates the need to store database passwords and provides enhanced security through AWS IAM policies.\n\n```ts\nimport { Role } from \"cdk-rds-sql\"\n\nconst iamRole = new Role(this, \"IamRole\", {\n provider: provider,\n roleName: \"myiamrole\",\n databaseName: \"mydb\",\n enableIamAuth: true,\n})\n```\n\nFor IAM-authenticated roles, the secret will not contain a password field:\n\n```json\n{\n \"dbClusterIdentifier\": \"teststack-clustereb1186t9-sh4wpqfdyfvu\",\n \"dbname\": \"mydb\",\n \"engine\": \"postgres\",\n \"port\": 5432,\n \"host\": \"teststack-clustereb1186t9-sh4wpqfdyfvu.cluster-cgudolabssna.us-east-1.rds.amazonaws.com\",\n \"username\": \"myiamrole\"\n}\n```\n\n**Requirements for IAM Authentication:**\n\n- SSL connections are required (enabled by default in this library)\n- Your application must have IAM permissions to connect to the database\n- The database user/role name must match the IAM identity\n\n**IAM Policy Example:**\n\nYour application will need an IAM policy like this to connect:\n\n```json\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"rds-db:connect\"\n ],\n \"Resource\": [\n \"arn:aws:rds-db:region:account-id:dbuser:cluster-resource-id/myiamrole\"\n ]\n }\n ]\n}\n```\n\nBoth PostgreSQL and MySQL databases support IAM authentication. For more details, see the [AWS RDS IAM Database Authentication documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).\n\n### MySQL support\n\nIn MySQL users are created with '%' as value for the host. It is hard\nto do this better:\n\n- Determine the CIDR blocks used by a VPC is not trivial.\n- For imported VPCs you cannot specify the IPv6 CIDR.\n- CIDRs might change without the system knowing, meaning applications\n could lose access to the database at random times, such as when a\n container is restarted.\n\n## Database\n\nCreate a database as follows:\n\n```ts\nimport { Database } from \"cdk-rds-sql\"\n\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n})\n```\n\nYou can provide an owner, which makes it easy to create database owned\nby a new user:\n\n```ts\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n owner: role,\n})\n```\n\n## Schema\n\nCreate a schema in the default database as follows:\n\n```ts\nimport { Schema } from \"cdk-rds-sql\"\n\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n})\n```\n\nOr in another database:\n\n```ts\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n})\n\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n databaseName: database.databaseName,\n})\n```\n\nOne may need a role permitted for using schema:\n\n```ts\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n databaseName: database.databaseName,\n role: role,\n})\n```\n\n## Sql\n\nYou can insert arbitrary SQL into your database with the `Sql` construct:\n\n```ts\nimport { Sql } from \"cdk-rds-sql\"\n\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: \"create table t (i int)\",\n})\n```\n\nCreate a table if it does not exist, and grant a role privileges:\n\n```ts\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: `\ncreate table if not exists t (i int);\ngrant select on t to myrole;\n`,\n})\n```\n\nRollback sql on stack deletion:\n\n```ts\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: `\ncreate table if not exists t (i int);\ngrant select on t to myrole;\n`,\n rollback: `\nDO $$BEGIN\n IF EXISTS (select from pg_database WHERE datname = 't') THEN\n IF EXISTS (select from pg_catalog.pg_roles WHERE rolname = 'myrole') THEN\n revoke select t from myrole;\n END IF;\n drop table t;\n END IF;\nEND$$;\n`,\n})\n```\n\nNote that there is no synchronisation between various `Sql`\nconstructs, in particular the order in your code does not determine\nthe order in which your SQL is executed. This happens in parallel,\nunless you specify an explicit dependency via `sql.node.addDepency()`.\n\nThere are a lot of concerns when using `Sql`:\n\n- When you update your Sql, your previous Sql is not \"rolled back\",\n the new Sql is simply executed again.\n- When you delete your `Sql` construct the rollback is executed if specified\n- When permission are granted via `Sql` they must be removed via rollback to succesfully remove the role\n- Currently the `Sql` constructs has less than 5 minutes to execute\n its work.\n- It is unknown how large your SQL can be.\n\n# Parameters\n\nSome lambda constructs, in particular [Bref](https://bref.sh/), do not\nsupport secrets out of the box. This construct allows you to create\nSSM parameters in addition to a secret:\n\n```ts\nconst role = new Role(this, \"Role\", {\n provider: provider,\n roleName: \"myrole\",\n databaseName: \"mydb\",\n parameterPrefix: \"/my-app/\",\n})\n```\n\nThis will create `/my-app/username`, `/my-app/password` and such.\n\nTo access parameters you will need IAM permissions such as:\n\n```ts\ninitialPolicy: [\n new iam.PolicyStatement({\n\tactions: [\"ssm:GetParameter\", \"ssm:GetParameters\"],\n\tresources: [\n\t // Grant access to all parameters under the base path\n\t `arn:aws:ssm:${this.region}:${this.account}:parameter/my-app/*`,\n\t],\n\teffect: iam.Effect.ALLOW,\n })\n],\n```\n\nNote that your VPC will need an SSM Parameters interface endpoint to support this.\n\n# IPv6\n\nIf you use the provider in an IPv6 subnet you probably need these settings:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n ...\n functionProps: {\n\tipv6AllowedForDualStack: true,\n\tallowAllIpv6Outbound: true,\n },\n}\n```\n\n# Working on this code\n\nThis code is managed by\n[projen](https://github.com/projen/projen/blob/main/README.md). In\naddition [pre-commit](https://pre-commit.com/) is used.\n\nSo after git clone and `npm ci` you would do:\n\n```\npre-commit install --install-hooks --hook-type commit-msg --hook-type pre-commit\n```\n\nto install the pre-commit hooks.\n\n## Testing\n\nTest code via projen with:\n\n npx projen test\n\nYou can run the sample stack with:\n\n npx projen integ:deploy:serverless\n\nIf you want to use an existing vpc:\n\n npx cdk deploy --context vpc-id=vpc-0123456789 TestServerlessV2Stack\n\n# To do\n\n- Update role: will not revoke connect to previous database if database name has changed.\n- If the cluster is configured for autopausing, wake cluster up before doing any SQL operations.\n- We rename roles and database on update: is that actually the best\n thing? More change to get us into an irrecoverable situation??\n"
3978
+ "markdown": "# About\n\nThis CDK construct library makes it possible to create databases,\nschemas, and roles in an Aurora Serverless v2, RDS Database Cluster or\nDatabase Instance. Both PostgreSQL and MySQL databases are supported.\n\nThis construct library is intended to be used in enterprise\nenvironments, and works in isolated subnets.\n\n<p align=\"left\">\n <a href=\"https://github.com/semantic-release/semantic-release\"><img src=\"https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release\" alt=semantic-release: angular\"></a>\n <a href=\"https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml\"><img src=\"https://github.com/berenddeboer/cdk-rds-sql/actions/workflows/release.yml/badge.svg\" alt=\"Release badge\"></a>\n</p>\n\n# Requirements\n\n- CDK v2.\n\n# Installation\n\n npm i cdk-rds-sql\n\n# Usage\n\n## Provider\n\nFirst setup your VPC and create your cluster:\n\n```ts\nimport { Duration, RemovalPolicy } from \"aws-cdk-lib\"\nimport * as ec2 from \"aws-cdk-lib/aws-ec2\"\nimport * as rds from \"aws-cdk-lib/aws-rds\"\n\nconst vpc = ec2.Vpc.fromLookup(this, \"Vpc\", {\n vpcId: this.node.tryGetContext(\"vpc-id\"),\n})\n\nconst cluster = new rds.ServerlessCluster(this, \"Cluster\", {\n vpc: vpc,\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_ISOLATED,\n },\n engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL,\n parameterGroup: rds.ParameterGroup.fromParameterGroupName(\n this,\n \"ParameterGroup\",\n \"default.aurora-postgresql11\"\n ),\n removalPolicy: RemovalPolicy.DESTROY,\n scaling: {\n autoPause: Duration.minutes(60),\n minCapacity: rds.AuroraCapacityUnit.ACU_2,\n maxCapacity: rds.AuroraCapacityUnit.ACU_2,\n },\n})\n```\n\nThen create a provider which will connect to your database. For a cluster:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n cluster: cluster,\n secret: cluster.secret!,\n})\n```\n\nFor an instance:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n instance: instance,\n secret: cluster.secret!,\n})\n```\n\nThe provider will setup a lambda, which normally lives in the same VPC\nas the database. You can give a different VPC, as long as that VPC has\naccess to the VPC of the database. Only the provider lambda will talk\nto your database.\n\nThe provider will by default use the private isolated subnet of the\nVPC. Your isolated network must have a VPC endpoint to AWS Secrets Manager\nand possibly KMS as well. If you want to use a subnet with egress\naccess in case you have no such VPC endpoints, specify the subnet as\nfollows:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n vpcSubnets: {\n subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,\n },\n cluster: cluster,\n secret: cluster.secret!,\n})\n```\n\n### Disabling SSL\n\nThe default connection to RDS is ssl enabled (this used to be disabled\nin versions below 4).\n\nYou can disable ssl by setting the `ssl` option to `false`:\n\n```ts\nconst provider = new Provider(this, \"Provider\", {\n vpc: vpc,\n instance: instance,\n secret: cluster.secret!,\n ssl: false, // default is true\n})\n```\n\n## Roles\n\nCreate a postgres role (or mysql user) for a cluster as follows:\n\n```ts\nimport { Role } from \"cdk-rds-sql\"\n\nconst role = new Role(this, \"Role\", {\n provider: provider,\n roleName: \"myrole\",\n databaseName: \"mydb\",\n})\n```\n\nThis will automatically create a secret just like `ServerlessCluster`\ndoes, with all the connection info needed for this user. It's secret value is a JSON like:\n\n```json\n{\n \"dbClusterIdentifier\": \"teststack-clustereb1186t9-sh4wpqfdyfvu\",\n \"password\": \"very-long-and-boring\",\n \"dbname\": \"mydb\",\n \"engine\": \"postgres\",\n \"port\": 5432,\n \"host\": \"teststack-clustereb1186t9-sh4wpqfdyfvu.cluster-cgudolabssna.us-east-1.rds.amazonaws.com\",\n \"username\": \"myrole\"\n}\n```\n\nYou can access the secret via `role.secret`.\n\nInstead of `databaseName` you can also specify `database` to reference\nan existing database. The role will not be created until the database\nhas been created.\n\nIf you want to make the role the owner of a new database, just specify\nthe `databaseName` here, and create the database later.\n\n### IAM Authentication\n\nInstead of password-based authentication, you can create roles that\nuse AWS IAM database authentication. This eliminates the need to store\ndatabase passwords and provides enhanced security through AWS IAM\npolicies.\n\n```ts\nimport { Role } from \"cdk-rds-sql\"\n\nconst iamRole = new Role(this, \"IamRole\", {\n provider: provider,\n roleName: \"myiamrole\",\n databaseName: \"mydb\",\n enableIamAuth: true,\n})\n```\n\nFor IAM-authenticated roles, the secret will not contain a password field:\n\n```json\n{\n \"dbClusterIdentifier\": \"teststack-clustereb1186t9-sh4wpqfdyfvu\",\n \"dbname\": \"mydb\",\n \"engine\": \"postgres\",\n \"port\": 5432,\n \"host\": \"teststack-clustereb1186t9-sh4wpqfdyfvu.cluster-cgudolabssna.us-east-1.rds.amazonaws.com\",\n \"username\": \"myiamrole\"\n}\n```\n\n**Requirements for IAM Authentication:**\n\n- SSL connections are required (enabled by default in this library)\n- Your application must have IAM permissions to connect to the database\n- The database user/role name must match the IAM identity\n\n**IAM Policy Example:**\n\nYour application will need an IAM policy like this to connect:\n\n```json\n{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\"rds-db:connect\"],\n \"Resource\": [\n \"arn:aws:rds-db:region:account-id:dbuser:cluster-resource-id/myiamrole\"\n ]\n }\n ]\n}\n```\n\nBoth PostgreSQL and MySQL databases support IAM authentication. For more details, see the [AWS RDS IAM Database Authentication documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).\n\n### MySQL support\n\nIn MySQL users are created with '%' as value for the host. It is hard\nto do this better:\n\n- Determine the CIDR blocks used by a VPC is not trivial.\n- For imported VPCs you cannot specify the IPv6 CIDR.\n- CIDRs might change without the system knowing, meaning applications\n could lose access to the database at random times, such as when a\n container is restarted.\n\n## Database\n\nCreate a database as follows:\n\n```ts\nimport { Database } from \"cdk-rds-sql\"\n\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n})\n```\n\nYou can provide an owner, which makes it easy to create database owned\nby a new user:\n\n```ts\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n owner: role,\n})\n```\n\n## Schema\n\nCreate a schema in the default database as follows:\n\n```ts\nimport { Schema } from \"cdk-rds-sql\"\n\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n})\n```\n\nOr in another database:\n\n```ts\nconst database = new Database(this, \"Database\", {\n provider: provider,\n databaseName: \"mydb\",\n})\n\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n databaseName: database.databaseName,\n})\n```\n\nOne may need a role permitted for using schema:\n\n```ts\nnew Schema(this, \"Schema\", {\n provider: provider,\n schemaName: \"myschema\",\n databaseName: database.databaseName,\n role: role,\n})\n```\n\n## Sql\n\nYou can insert arbitrary SQL into your database with the `Sql` construct:\n\n```ts\nimport { Sql } from \"cdk-rds-sql\"\n\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: \"create table t (i int)\",\n})\n```\n\nCreate a table if it does not exist, and grant a role privileges:\n\n```ts\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: `\ncreate table if not exists t (i int);\ngrant select on t to myrole;\n`,\n})\n```\n\nRollback sql on stack deletion:\n\n```ts\nconst sql = new Sql(this, \"Sql\", {\n provider: provider,\n database: database,\n statement: `\ncreate table if not exists t (i int);\ngrant select on t to myrole;\n`,\n rollback: `\nDO $$BEGIN\n IF EXISTS (select from pg_database WHERE datname = 't') THEN\n IF EXISTS (select from pg_catalog.pg_roles WHERE rolname = 'myrole') THEN\n revoke select t from myrole;\n END IF;\n drop table t;\n END IF;\nEND$$;\n`,\n})\n```\n\nNote that there is no synchronisation between various `Sql`\nconstructs, in particular the order in your code does not determine\nthe order in which your SQL is executed. This happens in parallel,\nunless you specify an explicit dependency via `sql.node.addDepency()`.\n\nThere are a lot of concerns when using `Sql`:\n\n- When you update your Sql, your previous Sql is not \"rolled back\",\n the new Sql is simply executed again.\n- When you delete your `Sql` construct the rollback is executed if specified\n- When permission are granted via `Sql` they must be removed via\n rollback to succesfully remove the role\n- Currently the `Sql` constructs has less than 5 minutes to execute\n its work.\n- It is unknown how large your SQL can be.\n\n# Parameters\n\nSome lambda constructs, in particular [Bref](https://bref.sh/), do not\nsupport secrets out of the box. Use the `parameterPrefix` property to\ncreate SSM parameters in addition to a secret:\n\n```ts\nconst role = new Role(this, \"Role\", {\n provider: provider,\n roleName: \"myrole\",\n databaseName: \"mydb\",\n parameterPrefix: \"/my-app/\",\n})\n```\n\nThis will create `/my-app/username`, `/my-app/password` and such.\n\nTo access parameters you will need IAM permissions such as:\n\n```ts\ninitialPolicy: [\n new iam.PolicyStatement({\n\tactions: [\"ssm:GetParameter\", \"ssm:GetParameters\"],\n\tresources: [\n\t // Grant access to all parameters under the base path\n\t `arn:aws:ssm:${this.region}:${this.account}:parameter/my-app/*`,\n\t],\n\teffect: iam.Effect.ALLOW,\n })\n],\n```\n\nNote that your VPC will need an SSM Parameters interface endpoint to support this.\n\n# IPv6\n\nIf you use the provider in an IPv6 subnet you probably need these settings:\n\n```ts\nimport { Provider } from \"cdk-rds-sql\"\n\nconst provider = new Provider(this, \"Provider\", {\n ...\n functionProps: {\n\tipv6AllowedForDualStack: true,\n\tallowAllIpv6Outbound: true,\n },\n}\n```\n\n# Working on this code\n\nThis code is managed by\n[projen](https://github.com/projen/projen/blob/main/README.md). In\naddition [pre-commit](https://pre-commit.com/) is used.\n\nSo after git clone and `npm ci` you would do:\n\n```\npre-commit install --install-hooks --hook-type commit-msg --hook-type pre-commit\n```\n\nto install the pre-commit hooks.\n\n## Testing\n\nTest code via projen with:\n\n npx projen test\n\nYou can run the sample stack with:\n\n npx projen integ:deploy:serverless\n\nIf you want to use an existing vpc:\n\n npx cdk deploy --context vpc-id=vpc-0123456789 TestServerlessV2Stack\n\n# To do\n\n- Update role: will not revoke connect to previous database if database name has changed.\n"
3914
3979
  },
3915
3980
  "repository": {
3916
3981
  "type": "git",
@@ -5013,6 +5078,6 @@
5013
5078
  "symbolId": "src/sql:SqlProps"
5014
5079
  }
5015
5080
  },
5016
- "version": "6.1.3",
5017
- "fingerprint": "OSWQkBKuUvytrwDYuqWb51S4Qwasx2Cvb/b4clwJ2EQ="
5081
+ "version": "6.2.0",
5082
+ "fingerprint": "JXQUDvSxH36bjjM6xbN28WiqQDGP+jhMn+rWB1p0tJ0="
5018
5083
  }
@@ -56,5 +56,5 @@ repos:
56
56
  exclude: .projenrc.ts
57
57
  name: test
58
58
  language: system
59
- entry: sh -c 'npx projen test --coverage=false'
59
+ entry: sh -c 'npx jest --coverage=false'
60
60
  files: \.ts$
package/README.md CHANGED
@@ -159,7 +159,10 @@ the `databaseName` here, and create the database later.
159
159
 
160
160
  ### IAM Authentication
161
161
 
162
- Instead of password-based authentication, you can create roles that use AWS IAM database authentication. This eliminates the need to store database passwords and provides enhanced security through AWS IAM policies.
162
+ Instead of password-based authentication, you can create roles that
163
+ use AWS IAM database authentication. This eliminates the need to store
164
+ database passwords and provides enhanced security through AWS IAM
165
+ policies.
163
166
 
164
167
  ```ts
165
168
  import { Role } from "cdk-rds-sql"
@@ -201,9 +204,7 @@ Your application will need an IAM policy like this to connect:
201
204
  "Statement": [
202
205
  {
203
206
  "Effect": "Allow",
204
- "Action": [
205
- "rds-db:connect"
206
- ],
207
+ "Action": ["rds-db:connect"],
207
208
  "Resource": [
208
209
  "arn:aws:rds-db:region:account-id:dbuser:cluster-resource-id/myiamrole"
209
210
  ]
@@ -348,7 +349,8 @@ There are a lot of concerns when using `Sql`:
348
349
  - When you update your Sql, your previous Sql is not "rolled back",
349
350
  the new Sql is simply executed again.
350
351
  - When you delete your `Sql` construct the rollback is executed if specified
351
- - When permission are granted via `Sql` they must be removed via rollback to succesfully remove the role
352
+ - When permission are granted via `Sql` they must be removed via
353
+ rollback to succesfully remove the role
352
354
  - Currently the `Sql` constructs has less than 5 minutes to execute
353
355
  its work.
354
356
  - It is unknown how large your SQL can be.
@@ -356,8 +358,8 @@ There are a lot of concerns when using `Sql`:
356
358
  # Parameters
357
359
 
358
360
  Some lambda constructs, in particular [Bref](https://bref.sh/), do not
359
- support secrets out of the box. This construct allows you to create
360
- SSM parameters in addition to a secret:
361
+ support secrets out of the box. Use the `parameterPrefix` property to
362
+ create SSM parameters in addition to a secret:
361
363
 
362
364
  ```ts
363
365
  const role = new Role(this, "Role", {
@@ -434,6 +436,3 @@ If you want to use an existing vpc:
434
436
  # To do
435
437
 
436
438
  - Update role: will not revoke connect to previous database if database name has changed.
437
- - If the cluster is configured for autopausing, wake cluster up before doing any SQL operations.
438
- - We rename roles and database on update: is that actually the best
439
- thing? More change to get us into an irrecoverable situation??
@@ -84,7 +84,12 @@ export abstract class AbstractEngine {
84
84
  */
85
85
  protected async getPassword(arn: string): Promise<string | void> {
86
86
  if (!arn) return
87
- const secrets_client = new SecretsManagerClient({})
87
+ const secrets_client = new SecretsManagerClient({
88
+ requestHandler: {
89
+ connectionTimeout: 5000,
90
+ requestTimeout: 10000,
91
+ },
92
+ })
88
93
  const command = new GetSecretValueCommand({
89
94
  SecretId: arn,
90
95
  })
package/lambda/handler.ts CHANGED
@@ -110,8 +110,9 @@ export const handler = async (
110
110
  startingDelay: 500,
111
111
  }
112
112
  )
113
- if (!secret.SecretString)
113
+ if (!secret.SecretString) {
114
114
  throw `No secret string in ${event.ResourceProperties.SecretArn}`
115
+ }
115
116
  const secretValues = JSON.parse(secret.SecretString)
116
117
 
117
118
  // Determine the database engine type
package/lib/database.js CHANGED
@@ -40,5 +40,5 @@ class Database extends aws_cdk_lib_1.CustomResource {
40
40
  }
41
41
  exports.Database = Database;
42
42
  _a = JSII_RTTI_SYMBOL_1;
43
- Database[_a] = { fqn: "cdk-rds-sql.Database", version: "6.1.3" };
43
+ Database[_a] = { fqn: "cdk-rds-sql.Database", version: "6.2.0" };
44
44
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNEM7QUFDNUMsMkNBQXNDO0FBQ3RDLGlDQUF1QztBQTJCdkMsTUFBTSxnQkFBaUIsU0FBUSxzQkFBUztJQUd0QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXlCO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDaEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFBO0lBQ3hDLENBQUM7Q0FDRjtBQUVELE1BQWEsUUFBUyxTQUFRLDRCQUFjO0lBQzFDOztPQUVHO0lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQWdCLEVBQUUsRUFBVSxFQUFFLFlBQW9CO1FBQ3hFLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ3JDLFlBQVksRUFBRSxZQUFZO1NBQzNCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFJRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9CO1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsWUFBWSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWTtZQUN6QyxVQUFVLEVBQUU7Z0JBQ1YsUUFBUSxFQUFFLHFCQUFjLENBQUMsUUFBUTtnQkFDakMsVUFBVSxFQUFFLEtBQUssQ0FBQyxZQUFZO2dCQUM5QixTQUFTLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUztnQkFDMUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUTthQUM3QjtTQUNGLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUN2QyxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUE7UUFDdEMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3RDLENBQUM7SUFDSCxDQUFDOztBQTNCSCw0QkE0QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDdXN0b21SZXNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiXG5pbXBvcnQgeyBSZHNTcWxSZXNvdXJjZSB9IGZyb20gXCIuL2VudW1cIlxuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiLi9wcm92aWRlclwiXG5pbXBvcnQgeyBSb2xlIH0gZnJvbSBcIi4vcm9sZVwiXG5cbmludGVyZmFjZSBEYXRhYmFzZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogTmFtZSBvZiBkYXRhYmFzZSB0byBjcmVhdGUuXG4gICAqL1xuICByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBkYXRhYmFzZSBvd25lci5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVyPzogUm9sZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlUHJvcHMgZXh0ZW5kcyBEYXRhYmFzZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogUHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSBwcm92aWRlcjogUHJvdmlkZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRGF0YWJhc2Uge1xuICByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xufVxuXG5jbGFzcyBJbXBvcnRlZERhdGFiYXNlIGV4dGVuZHMgQ29uc3RydWN0IGltcGxlbWVudHMgSURhdGFiYXNlIHtcbiAgcHVibGljIHJlYWRvbmx5IGRhdGFiYXNlTmFtZTogc3RyaW5nXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IERhdGFiYXNlQXR0cmlidXRlcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcbiAgICB0aGlzLmRhdGFiYXNlTmFtZSA9IHByb3BzLmRhdGFiYXNlTmFtZVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEYXRhYmFzZSBleHRlbmRzIEN1c3RvbVJlc291cmNlIGltcGxlbWVudHMgSURhdGFiYXNlIHtcbiAgLyoqXG4gICAqIFJldHVybiBhIERhdGFiYXNlIGJhc2VkIHVwb24gbmFtZSBvbmx5LiBVc2UgZm9yIGltcG9ydGluZyBleGlzdGluZyBkYXRhYmFzZXMuXG4gICAqL1xuICBzdGF0aWMgZnJvbURhdGFiYXNlTmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBkYXRhYmFzZU5hbWU6IHN0cmluZyk6IElEYXRhYmFzZSB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnRlZERhdGFiYXNlKHNjb3BlLCBpZCwge1xuICAgICAgZGF0YWJhc2VOYW1lOiBkYXRhYmFzZU5hbWUsXG4gICAgfSlcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBEYXRhYmFzZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3BzLnByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgUmVzb3VyY2U6IFJkc1NxbFJlc291cmNlLkRBVEFCQVNFLFxuICAgICAgICBSZXNvdXJjZUlkOiBwcm9wcy5kYXRhYmFzZU5hbWUsXG4gICAgICAgIFNlY3JldEFybjogcHJvcHMucHJvdmlkZXIuc2VjcmV0LnNlY3JldEFybixcbiAgICAgICAgT3duZXI6IHByb3BzLm93bmVyPy5yb2xlTmFtZSxcbiAgICAgIH0sXG4gICAgfSlcbiAgICB0aGlzLm5vZGUuYWRkRGVwZW5kZW5jeShwcm9wcy5wcm92aWRlcilcbiAgICB0aGlzLmRhdGFiYXNlTmFtZSA9IHByb3BzLmRhdGFiYXNlTmFtZVxuICAgIGlmIChwcm9wcy5vd25lcikge1xuICAgICAgdGhpcy5ub2RlLmFkZERlcGVuZGVuY3kocHJvcHMub3duZXIpXG4gICAgfVxuICB9XG59XG4iXX0=