Skip to main content

The CDK Construct Library for AWS::Redshift

Project description

Amazon Redshift Construct Library

---

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 aws_cdk.aws_ec2 as ec2


vpc = ec2.Vpc(self, "Vpc")
cluster = Cluster(self, "Redshift",
    master_user=Login(
        master_username="admin"
    ),
    vpc=vpc
)

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.allow_default_port_from_any_ipv4("Open to the world")

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

cluster.cluster_endpoint.socket_address

Rotating credentials

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

cluster.add_rotation_single_user()

The multi user rotation scheme is also available:

import aws_cdk.aws_secretsmanager as secretsmanager


cluster.add_rotation_multi_user("MyUser",
    secret=secretsmanager.Secret.from_secret_name_v2(self, "Imported Secret", "my-secret")
)

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(self, "User",
    cluster=cluster,
    database_name="databaseName"
)

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 aws_cdk.aws_kms as kms


encryption_key = kms.Key(self, "Key")
User(self, "User",
    encryption_key=encryption_key,
    cluster=cluster,
    database_name="databaseName"
)

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(self, "User",
    username="myuser",
    cluster=cluster,
    database_name="databaseName"
)

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(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)

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

Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)", dist_key=True), Column(name="col2", data_type="float")
    ],
    cluster=cluster,
    database_name="databaseName",
    dist_style=TableDistStyle.KEY
)

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

Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)", sort_key=True), Column(name="col2", data_type="float", sort_key=True)
    ],
    cluster=cluster,
    database_name="databaseName",
    sort_style=TableSortStyle.COMPOUND
)

Granting Privileges

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

user = User(self, "User",
    cluster=cluster,
    database_name="databaseName"
)
table = Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)

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:

database_name = "databaseName"
username = "myuser"
table_name = "mytable"

user = User(self, "User",
    username=username,
    cluster=cluster,
    database_name=database_name
)
table = Table(self, "Table",
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name=database_name
)
table.grant(user, TableAction.INSERT)

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

database_name = "databaseName"
username = "myuser"
table_name = "mytable"

user = User.from_user_attributes(self, "User",
    username=username,
    password=SecretValue.plain_text("NOT_FOR_PRODUCTION"),
    cluster=cluster,
    database_name=database_name
)
table = Table.from_table_attributes(self, "Table",
    table_name=table_name,
    table_columns=[Column(name="col1", data_type="varchar(4)"), Column(name="col2", data_type="float")],
    cluster=cluster,
    database_name="databaseName"
)
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.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws-cdk.aws-redshift-alpha-2.2.0a0.tar.gz (121.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aws_cdk.aws_redshift_alpha-2.2.0a0-py3-none-any.whl (120.2 kB view details)

Uploaded Python 3

File details

Details for the file aws-cdk.aws-redshift-alpha-2.2.0a0.tar.gz.

File metadata

  • Download URL: aws-cdk.aws-redshift-alpha-2.2.0a0.tar.gz
  • Upload date:
  • Size: 121.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.6.5

File hashes

Hashes for aws-cdk.aws-redshift-alpha-2.2.0a0.tar.gz
Algorithm Hash digest
SHA256 b390204eb96a52f6973a40b4d8648c3ba51d2af070a093aea1abfc3001cf2e1b
MD5 23008bee164d03a66f36cf735578537d
BLAKE2b-256 d888f868339b038db282066a3dd5412b537ee36e6f01cd186157a4357cf7b9c8

See more details on using hashes here.

File details

Details for the file aws_cdk.aws_redshift_alpha-2.2.0a0-py3-none-any.whl.

File metadata

  • Download URL: aws_cdk.aws_redshift_alpha-2.2.0a0-py3-none-any.whl
  • Upload date:
  • Size: 120.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.6.5

File hashes

Hashes for aws_cdk.aws_redshift_alpha-2.2.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 4a17c107f66c75b3cb3ab36e78a694003426ce1823e678720b6766a3ad03bfa7
MD5 a017faed69c30b0be2594641f3bd4c84
BLAKE2b-256 4d6bfa0f12685b9babc0afdc8fa866df2fe8e82b41a40cf7748e79aa40ddfdd9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page