Skip to content

Commit

Permalink
Add redshiftserverless.py module (#2101)
Browse files Browse the repository at this point in the history
- Add redshiftserverless.py module to support the deployment of Serverless Redshift Workgroups and Namespaces.
- Update CONTRIBUTING.md
  • Loading branch information
tnielsen2 committed Nov 26, 2022
1 parent e872afb commit 6db9eb0
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 5 deletions.
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Thus the code base grew organically as new validation routines and features were
bit challenging to know what new resources and properties were added periodically from AWS.

Eventually AWS added the Resource Specification and started publishing machine readable versions but
initially it had quite a few errors and inconsistensies. An early code generator was used for adding
initially it had quite a few errors and inconsistencies. An early code generator was used for adding
new resources and delta changes to existing code but still needed hand tweaking.

An updated code generator is now available but may require tweaks to handle inconsistencies or backward compatibility.
Expand All @@ -45,8 +45,8 @@ make spec
To generate code, the current process is roughly, scan the CloudFormation history to identify changes and then run (using S3 as an example):

```
python3 scripts/gen.py --stub --name s3 CloudFormationResourceSpecification.json > troposphere/s3.py
```
python3 scripts/gen.py s3 CloudFormationResourceSpecification.json > troposphere/s3.py
```
Use the auto-formatters to clean up the generated code using:
```
make fix
Expand Down Expand Up @@ -113,7 +113,7 @@ The above example replaces the *Type* field. But sometimes there is a need to us

Early on it was not always clear what AWS wanted Resources and Properties named. These
names have been kept historically for backward compatibility (although these might change
in a future release). Thus, the names used in code generatio must be maintained.
in a future release). Thus, the names used in code generation must be maintained.
An S3 example to maintain the seage of `S3Key` instead of the current name `S3KeyFilter`.

```
Expand Down Expand Up @@ -154,7 +154,7 @@ WAFv2 with 2 different Property contents. This renames the LoggingConfiguration

One of the core reasons to use troposphere is to help with the validation of the CloudFormation template prior to applying it into AWS.
The code generator will usually do type validation to ensure the correct type is used for a property and tje *required* field which will
warn if thereare missing required fields. The other validators allow for functions to do further type and value validation along with
warn if there are missing required fields. The other validators allow for functions to do further type and value validation along with
class validation.

### Property type function validators
Expand Down
51 changes: 51 additions & 0 deletions examples/RedshiftServerless.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
from troposphere import Template
from troposphere.redshiftserverless import ConfigParameter, Namespace, Workgroup

# Redshift serverless cluster variables
admin_username = "{{{{resolve:ssm:/redshift_admin_username}}}}"
admin_password = "{{{{resolve:ssm:/redshift_admin_password}}}}"
default_iam_role_arn = "arn:aws:iam::123456789123:role/service-role/AmazonRedshift-CommandsAccessRole-123451234512345"
default_db_name = "dev"
iam_roles = []
serverless_namespace_name = "serverless"
tcp_port = 5439
vpc_id = "vpc-12345678123456789"
subnet_ids = ["subnet-12345678912345678", "subnet-98765432198765432"]
security_group_ids = ["sg-12345123451234567"]

# Prepare Template
t = Template()
t.set_description("RedshiftServerless: Template and module example")

RedshiftServerlessNamespace = t.add_resource(
Namespace(
"RedshiftServerlessNamespace",
AdminUsername=admin_username,
AdminUserPassword=admin_password,
DbName=default_db_name,
DefaultIamRoleArn=default_iam_role_arn,
IamRoles=iam_roles,
NamespaceName=serverless_namespace_name,
)
)

RedshiftServerlessWorkgroup = t.add_resource(
Workgroup(
"RedshiftServerlessWorkgroup",
ConfigParameters=[
ConfigParameter(
ParameterKey="enable_user_activity_logging", ParameterValue="true"
)
],
EnhancedVpcRouting=True,
NamespaceName=serverless_namespace_name,
PubliclyAccessible=False,
SecurityGroupIds=security_group_ids,
SubnetIds=subnet_ids,
WorkgroupName="RedshiftServerlessWorkgroup",
)
)

# Output all necessary files with the template and stack_details
print(t.to_json())
38 changes: 38 additions & 0 deletions tests/examples_output/RedshiftServerless.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"Description": "RedshiftServerless: Template and module example",
"Resources": {
"RedshiftServerlessNamespace": {
"Properties": {
"AdminUserPassword": "{{{{resolve:ssm:/redshift_admin_password}}}}",
"AdminUsername": "{{{{resolve:ssm:/redshift_admin_username}}}}",
"DbName": "dev",
"DefaultIamRoleArn": "arn:aws:iam::123456789123:role/service-role/AmazonRedshift-CommandsAccessRole-123451234512345",
"IamRoles": [],
"NamespaceName": "serverless"
},
"Type": "AWS::RedshiftServerless::Namespace"
},
"RedshiftServerlessWorkgroup": {
"Properties": {
"ConfigParameters": [
{
"ParameterKey": "enable_user_activity_logging",
"ParameterValue": "true"
}
],
"EnhancedVpcRouting": true,
"NamespaceName": "serverless",
"PubliclyAccessible": false,
"SecurityGroupIds": [
"sg-12345123451234567"
],
"SubnetIds": [
"subnet-12345678912345678",
"subnet-98765432198765432"
],
"WorkgroupName": "RedshiftServerlessWorkgroup"
},
"Type": "AWS::RedshiftServerless::Workgroup"
}
}
}
63 changes: 63 additions & 0 deletions troposphere/redshiftserverless.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright (c) 2012-2022, Mark Peek <mark@peek.org>
# All rights reserved.
#
# See LICENSE file for full license.
#
# *** Do not modify - this file is autogenerated ***


from . import AWSObject, AWSProperty, PropsDictType, Tags
from .validators import boolean, integer


class Namespace(AWSObject):
"""
`Namespace <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-namespace.html>`__
"""

resource_type = "AWS::RedshiftServerless::Namespace"

props: PropsDictType = {
"AdminUserPassword": (str, False),
"AdminUsername": (str, False),
"DbName": (str, False),
"DefaultIamRoleArn": (str, False),
"FinalSnapshotName": (str, False),
"FinalSnapshotRetentionPeriod": (integer, False),
"IamRoles": ([str], False),
"KmsKeyId": (str, False),
"LogExports": ([str], False),
"NamespaceName": (str, True),
"Tags": (Tags, False),
}


class ConfigParameter(AWSProperty):
"""
`ConfigParameter <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshiftserverless-workgroup-configparameter.html>`__
"""

props: PropsDictType = {
"ParameterKey": (str, False),
"ParameterValue": (str, False),
}


class Workgroup(AWSObject):
"""
`Workgroup <http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshiftserverless-workgroup.html>`__
"""

resource_type = "AWS::RedshiftServerless::Workgroup"

props: PropsDictType = {
"BaseCapacity": (integer, False),
"ConfigParameters": ([ConfigParameter], False),
"EnhancedVpcRouting": (boolean, False),
"NamespaceName": (str, False),
"PubliclyAccessible": (boolean, False),
"SecurityGroupIds": ([str], False),
"SubnetIds": ([str], False),
"Tags": (Tags, False),
"WorkgroupName": (str, True),
}

0 comments on commit 6db9eb0

Please sign in to comment.