All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.awscdk.services.redshift.package-info Maven / Gradle / Ivy

There is a newer version: 1.204.0
Show newest version
/**
 * 

Amazon Redshift Construct Library

*

* --- *

* cfn-resources: Stable *

*

*

* All classes with the Cfn prefix in this module (CFN Resources) are always stable and safe to use. *

*

*

* cdk-constructs: Experimental *

*

*

* The APIs of higher level constructs in this module are experimental and under active development. * They are subject to non-backward compatible changes or removal in any future version. These are * not subject to the Semantic Versioning model and breaking changes will be * announced in the release notes. This means that while you may use them, you may need to update * your source code when upgrading to a newer version of this package. *

*

*

*


*

* *

*

Starting a Redshift Cluster Database

*

* To set up a Redshift cluster, define a Cluster. It will be launched in a VPC. * You can specify a VPC, otherwise one will be created. The nodes are always launched in private subnets and are encrypted by default. *

*

 * import software.amazon.awscdk.services.ec2.*;
 * 
 * 
 * Vpc vpc = new Vpc(this, "Vpc");
 * Cluster cluster = Cluster.Builder.create(this, "Redshift")
 *         .masterUser(Login.builder()
 *                 .masterUsername("admin")
 *                 .build())
 *         .vpc(vpc)
 *         .build();
 * 
*

* By default, the master password will be generated and stored in AWS Secrets Manager. *

* A default database named default_db will be created in the cluster. To change the name of this database set the defaultDatabaseName attribute in the constructor properties. *

* By default, the cluster will not be publicly accessible. * Depending on your use case, you can make the cluster publicly accessible with the publiclyAccessible property. *

*

Connecting

*

* To control who can access the cluster, use the .connections attribute. Redshift Clusters have * a default port, so you don't need to specify the port: *

*

 * cluster.connections.allowDefaultPortFromAnyIpv4("Open to the world");
 * 
*

* The endpoint to access your database cluster will be available as the .clusterEndpoint attribute: *

*

 * cluster.getClusterEndpoint().getSocketAddress();
 * 
*

*

Database Resources

*

* This module allows for the creation of non-CloudFormation database resources such as users * and tables. This allows you to manage identities, permissions, and stateful resources * within your Redshift cluster from your CDK application. *

* Because these resources are not available in CloudFormation, this library leverages * custom * resources * to manage them. In addition to the IAM permissions required to make Redshift service * calls, the execution role for the custom resource handler requires database credentials to * create resources within the cluster. *

* These database credentials can be supplied explicitly through the adminUser properties * of the various database resource constructs. Alternatively, the credentials can be * automatically pulled from the Redshift cluster's default administrator * credentials. However, this option is only available if the password for the credentials * was generated by the CDK application (ie., no value vas provided for the masterPassword * property * of * Cluster.masterUser). *

*

Creating Users

*

* Create a user within a Redshift cluster database by instantiating a User construct. This * will generate a username and password, store the credentials in a AWS Secrets Manager * Secret, * and make a query to the Redshift cluster to create a new database user with the * credentials. *

*

 * User.Builder.create(this, "User")
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * 
*

* By default, the user credentials are encrypted with your AWS account's default Secrets * Manager encryption key. You can specify the encryption key used for this purpose by * supplying a key in the encryptionKey property. *

*

 * import software.amazon.awscdk.services.kms.*;
 * 
 * 
 * Key encryptionKey = new Key(this, "Key");
 * User.Builder.create(this, "User")
 *         .encryptionKey(encryptionKey)
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * 
*

* By default, a username is automatically generated from the user construct ID and its path * in the construct tree. You can specify a particular username by providing a value for the * username property. Usernames must be valid identifiers; see: Names and * identifiers in the Amazon * Redshift Database Developer Guide. *

*

 * User.Builder.create(this, "User")
 *         .username("myuser")
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * 
*

* The user password is generated by AWS Secrets Manager using the default configuration * found in * secretsmanager.SecretStringGenerator, * except with password length 30 and some SQL-incompliant characters excluded. The * plaintext for the password will never be present in the CDK application; instead, a * CloudFormation Dynamic * Reference * will be used wherever the password value is required. *

*

Creating Tables

*

* Create a table within a Redshift cluster database by instantiating a Table * construct. This will make a query to the Redshift cluster to create a new database table * with the supplied schema. *

*

 * Table.Builder.create(this, "Table")
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").build(), Column.builder().name("col2").dataType("float").build()))
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * 
*

* The table can be configured to have distStyle attribute and a distKey column: *

*

 * Table.Builder.create(this, "Table")
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").distKey(true).build(), Column.builder().name("col2").dataType("float").build()))
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .distStyle(TableDistStyle.KEY)
 *         .build();
 * 
*

* The table can also be configured to have sortStyle attribute and sortKey columns: *

*

 * Table.Builder.create(this, "Table")
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").sortKey(true).build(), Column.builder().name("col2").dataType("float").sortKey(true).build()))
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .sortStyle(TableSortStyle.COMPOUND)
 *         .build();
 * 
*

*

Granting Privileges

*

* You can give a user privileges to perform certain actions on a table by using the * Table.grant() method. *

*

 * User user = User.Builder.create(this, "User")
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * Table table = Table.Builder.create(this, "Table")
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").build(), Column.builder().name("col2").dataType("float").build()))
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * 
 * table.grant(user, TableAction.DROP, TableAction.SELECT);
 * 
*

* Take care when managing privileges via the CDK, as attempting to manage a user's * privileges on the same table in multiple CDK applications could lead to accidentally * overriding these permissions. Consider the following two CDK applications which both refer * to the same user and table. In application 1, the resources are created and the user is * given INSERT permissions on the table: *

*

 * String databaseName = "databaseName";
 * String username = "myuser";
 * String tableName = "mytable";
 * 
 * User user = User.Builder.create(this, "User")
 *         .username(username)
 *         .cluster(cluster)
 *         .databaseName(databaseName)
 *         .build();
 * Table table = Table.Builder.create(this, "Table")
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").build(), Column.builder().name("col2").dataType("float").build()))
 *         .cluster(cluster)
 *         .databaseName(databaseName)
 *         .build();
 * table.grant(user, TableAction.INSERT);
 * 
*

* In application 2, the resources are imported and the user is given INSERT permissions on * the table: *

*

 * String databaseName = "databaseName";
 * String username = "myuser";
 * String tableName = "mytable";
 * 
 * IUser user = User.fromUserAttributes(this, "User", UserAttributes.builder()
 *         .username(username)
 *         .password(SecretValue.unsafePlainText("NOT_FOR_PRODUCTION"))
 *         .cluster(cluster)
 *         .databaseName(databaseName)
 *         .build());
 * ITable table = Table.fromTableAttributes(this, "Table", TableAttributes.builder()
 *         .tableName(tableName)
 *         .tableColumns(List.of(Column.builder().name("col1").dataType("varchar(4)").build(), Column.builder().name("col2").dataType("float").build()))
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build());
 * table.grant(user, TableAction.INSERT);
 * 
*

* Both applications attempt to grant the user the appropriate privilege on the table by * submitting a GRANT USER SQL query to the Redshift cluster. Note that the latter of these * two calls will have no effect since the user has already been granted the privilege. *

* Now, if application 1 were to remove the call to grant, a REVOKE USER SQL query is * submitted to the Redshift cluster. In general, application 1 does not know that * application 2 has also granted this permission and thus cannot decide not to issue the * revocation. This leads to the undesirable state where application 2 still contains the * call to grant but the user does not have the specified permission. *

* Note that this does not occur when duplicate privileges are granted within the same * application, as such privileges are de-duplicated before any SQL query is submitted. *

*

Rotating credentials

*

* When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically: *

*

 * cluster.addRotationSingleUser();
 * 
*

* The multi user rotation scheme is also available: *

*

 * User user = User.Builder.create(this, "User")
 *         .cluster(cluster)
 *         .databaseName("databaseName")
 *         .build();
 * cluster.addRotationMultiUser("MultiUserRotation", RotationMultiUserOptions.builder()
 *         .secret(user.getSecret())
 *         .build());
 * 
*/ @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) package software.amazon.awscdk.services.redshift;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy