Skip to content
This repository was archived by the owner on Oct 23, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"typeName": "AWS::Redshift::ClusterSubnetGroup",
"description": "Specifies an Amazon Redshift subnet group.",
"description": "Resource Type definition for AWS::Redshift::ClusterSubnetGroup. Specifies an Amazon Redshift subnet group.",
"sourceUrl": "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-redshift",
"definitions": {
"Tag": {
Expand Down Expand Up @@ -65,19 +65,24 @@
"Description",
"SubnetIds"
],
"primaryIdentifier": [
"/properties/ClusterSubnetGroupName"
"createOnlyProperties": [
"/properties/ClusterSubnetGroupName",
"/properties/Description"
],
"readOnlyProperties": [
"primaryIdentifier": [
"/properties/ClusterSubnetGroupName"
],
"writeOnlyProperties": [
"/properties/Tags",
"/properties/Tags/*/Key",
"/properties/Tags/*/Value"
],
"tagging": {
"taggable": true
"taggable": true,
"tagOnCreate": true,
"tagUpdatable": true,
"cloudFormationSystemTags": false,
"tagProperty": "/properties/Tags",
"permissions": [
"redshift:DescribeTags",
"redshift:CreateTags",
"redshift:DeleteTags"
]
},
"handlers": {
"create": {
Expand Down Expand Up @@ -138,6 +143,7 @@
"redshift:DeleteClusterSubnetGroup",
"redshift:DescribeClusterSubnetGroups",
"redshift:DescribeTags",
"redshift:DeleteTags",
"ec2:AllocateAddress",
"ec2:AssociateAddress",
"ec2:AttachNetworkInterface",
Expand Down Expand Up @@ -167,4 +173,4 @@
]
}
}
}
}
24 changes: 14 additions & 10 deletions aws-redshift-clustersubnetgroup/docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AWS::Redshift::ClusterSubnetGroup

Specifies an Amazon Redshift subnet group.
Resource Type definition for AWS::Redshift::ClusterSubnetGroup. Specifies an Amazon Redshift subnet group.

## Syntax

Expand All @@ -15,6 +15,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
"<a href="#description" title="Description">Description</a>" : <i>String</i>,
"<a href="#subnetids" title="SubnetIds">SubnetIds</a>" : <i>[ String, ... ]</i>,
"<a href="#tags" title="Tags">Tags</a>" : <i>[ <a href="tag.md">Tag</a>, ... ]</i>,
"<a href="#clustersubnetgroupname" title="ClusterSubnetGroupName">ClusterSubnetGroupName</a>" : <i>String</i>
}
}
</pre>
Expand All @@ -29,6 +30,7 @@ Properties:
- String</i>
<a href="#tags" title="Tags">Tags</a>: <i>
- <a href="tag.md">Tag</a></i>
<a href="#clustersubnetgroupname" title="ClusterSubnetGroupName">ClusterSubnetGroupName</a>: <i>String</i>
</pre>

## Properties
Expand All @@ -41,7 +43,7 @@ _Required_: Yes

_Type_: String

_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
_Update requires_: [Replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-replacement)

#### SubnetIds

Expand All @@ -63,18 +65,20 @@ _Type_: List of <a href="tag.md">Tag</a>

_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)

## Return Values
#### ClusterSubnetGroupName

### Ref
This name must be unique for all subnet groups that are created by your AWS account. If costumer do not provide it, cloudformation will generate it. Must not be "Default".

When you pass the logical ID of this resource to the intrinsic `Ref` function, Ref returns the ClusterSubnetGroupName.
_Required_: No

### Fn::GetAtt
_Type_: String

The `Fn::GetAtt` intrinsic function returns a value for a specified attribute of this type. The following are the available attributes and sample return values.
_Maximum Length_: <code>255</code>

For more information about using the `Fn::GetAtt` intrinsic function, see [Fn::GetAtt](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html).
_Update requires_: [Replacement](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-replacement)

#### ClusterSubnetGroupName
## Return Values

This name must be unique for all subnet groups that are created by your AWS account. If costumer do not provide it, cloudformation will generate it. Must not be "Default".
### Ref

When you pass the logical ID of this resource to the intrinsic `Ref` function, Ref returns the ClusterSubnetGroupName.
1 change: 1 addition & 0 deletions aws-redshift-clustersubnetgroup/docs/tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ _Minimum Length_: <code>1</code>
_Maximum Length_: <code>255</code>

_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)

47 changes: 45 additions & 2 deletions aws-redshift-clustersubnetgroup/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,63 @@
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jackson.version>2.15.2</jackson.version>
<aws.sdk.version>2.17.267</aws.sdk.version>
</properties>

<dependencies>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/redshift -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>redshift</artifactId>
<version>2.15.51</version>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sdk-core</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>auth</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.cloudformation/aws-cloudformation-rpdk-java-plugin -->
<dependency>
<groupId>software.amazon.cloudformation</groupId>
<artifactId>aws-cloudformation-rpdk-java-plugin</artifactId>
<version>[2.0.0, 3.0.0)</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>sdk-core</artifactId>
<version>2.17.267</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>

Expand Down Expand Up @@ -67,6 +104,12 @@
<version>2.26.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
</dependencies>

<build>
Expand Down
19 changes: 19 additions & 0 deletions aws-redshift-clustersubnetgroup/sam-tests/create.json

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get rid of these SAM files, if not needed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"desiredResourceState": {
"ClusterSubnetGroupName": "cfn-subnet-group-4",
"Description": "Test Subnet Group Description",
"SubnetIds": [
"subnet-0ddbac69e73569727",
"subnet-0d1b9f96842cb5777"
],
"Tags": [
{
"Key": "Environment",
"Value": "Test"
}
]
},
"previousResourceState": null,
"logicalResourceIdentifier": "MySubnetGroup",
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe"
}
8 changes: 8 additions & 0 deletions aws-redshift-clustersubnetgroup/sam-tests/delete.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"desiredResourceState": {
"ClusterSubnetGroupName": "cfn-subnet-group-1"
},
"previousResourceState": null,
"logicalResourceIdentifier": "cfn-subnet-group-1",
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe"
}
7 changes: 7 additions & 0 deletions aws-redshift-clustersubnetgroup/sam-tests/list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"desiredResourceState": {},
"previousResourceState": null,
"nextToken": null,
"logicalResourceIdentifier": "cfn-subnet-group-4",
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe"
}
8 changes: 8 additions & 0 deletions aws-redshift-clustersubnetgroup/sam-tests/read.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"desiredResourceState": {
"ClusterSubnetGroupName": "cfn-subnet-group-4"
},
"previousResourceState": null,
"logicalResourceIdentifier": "cfn-subnet-group-4",
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe"
}
31 changes: 31 additions & 0 deletions aws-redshift-clustersubnetgroup/sam-tests/update.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"desiredResourceState": {
"ClusterSubnetGroupName": "cfn-subnet-group-4",
"Description": "Updated Subnet Group Description",
"SubnetIds": [
"subnet-0d1b9f96842cb5777"
],
"Tags": [
{
"Key": "Environment",
"Value": "Production"
}
]
},
"previousResourceState": {
"ClusterSubnetGroupName": "cfn-subnet-group-4",
"Description": "Test Subnet Group Description",
"SubnetIds": [
"subnet-0ddbac69e73569727",
"subnet-0d1b9f96842cb5777"
],
"Tags": [
{
"Key": "Environment",
"Value": "Test"
}
]
},
"logicalResourceIdentifier": "MySubnetGroup",
"clientRequestToken": "4b90a7e4-b790-456b-a937-0cfdfa211dfe"
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,88 @@
package software.amazon.redshift.clustersubnetgroup;

import com.amazonaws.util.StringUtils;
import software.amazon.awssdk.services.redshift.RedshiftClient;
import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy;
import software.amazon.cloudformation.proxy.Logger;
import software.amazon.cloudformation.proxy.HandlerErrorCode;
import software.amazon.cloudformation.proxy.ProgressEvent;
import software.amazon.cloudformation.proxy.ProxyClient;
import software.amazon.cloudformation.proxy.ResourceHandlerRequest;

import software.amazon.awssdk.services.redshift.model.DescribeTagsRequest;
import software.amazon.awssdk.services.redshift.model.DescribeTagsResponse;
import software.amazon.awssdk.services.redshift.model.CreateTagsResponse;
import software.amazon.awssdk.services.redshift.model.InvalidTagException;
import software.amazon.awssdk.services.redshift.model.InvalidClusterStateException;
import software.amazon.awssdk.services.redshift.model.ResourceNotFoundException;

public abstract class BaseHandlerStd extends BaseHandler<CallbackContext> {
protected Logger logger;
protected static final String CALL_GRAPH_TYPE_NAME = StringUtils.replace(ResourceModel.TYPE_NAME, "::", "-");

@Override
public final ProgressEvent<ResourceModel, CallbackContext> handleRequest(
final AmazonWebServicesClientProxy proxy,
final ResourceHandlerRequest<ResourceModel> request,
final CallbackContext callbackContext,
final Logger logger) {
final AmazonWebServicesClientProxy proxy,
final ResourceHandlerRequest<ResourceModel> request,
final CallbackContext callbackContext,
final Logger logger) {
return handleRequest(
proxy,
request,
callbackContext != null ? callbackContext : new CallbackContext(),
proxy.newProxy(ClientBuilder::getClient),
logger
proxy,
request,
callbackContext != null ? callbackContext : new CallbackContext(),
proxy.newProxy(ClientBuilder::getClient),
logger
);
}

protected abstract ProgressEvent<ResourceModel, CallbackContext> handleRequest(
final AmazonWebServicesClientProxy proxy,
final ResourceHandlerRequest<ResourceModel> request,
final CallbackContext callbackContext,
final ProxyClient<RedshiftClient> proxyClient,
final Logger logger);
}
final AmazonWebServicesClientProxy proxy,
final ResourceHandlerRequest<ResourceModel> request,
final CallbackContext callbackContext,
final ProxyClient<RedshiftClient> proxyClient,
final Logger logger);

protected DescribeTagsResponse readTags(final DescribeTagsRequest awsRequest,
final ProxyClient<RedshiftClient> proxyClient) {
DescribeTagsResponse awsResponse;
awsResponse = proxyClient.injectCredentialsAndInvokeV2(awsRequest, proxyClient.client()::describeTags);
logger.log(awsResponse.toString());
logger.log(String.format("%s's tags have successfully been read.", ResourceModel.TYPE_NAME));
return awsResponse;
}

protected CreateTagsResponse updateTags(final ModifyTagsRequest awsRequest,
final ProxyClient<RedshiftClient> proxyClient) {
CreateTagsResponse awsResponse = null;

if (awsRequest.getDeleteOldTagsRequest().tagKeys().isEmpty()) {
logger.log(String.format("No tags would be deleted for the resource: %s.", ResourceModel.TYPE_NAME));
} else {
proxyClient.injectCredentialsAndInvokeV2(awsRequest.getDeleteOldTagsRequest(), proxyClient.client()::deleteTags);
logger.log(String.format("Delete tags for the resource: %s.", ResourceModel.TYPE_NAME));
}

if (awsRequest.getCreateNewTagsRequest().tags().isEmpty()) {
logger.log(String.format("No tags would be created for the resource: %s.", ResourceModel.TYPE_NAME));
} else {
awsResponse = proxyClient.injectCredentialsAndInvokeV2(awsRequest.getCreateNewTagsRequest(), proxyClient.client()::createTags);
logger.log(String.format("Create tags for the resource: %s.", ResourceModel.TYPE_NAME));
}

return awsResponse;
}

protected ProgressEvent<ResourceModel, CallbackContext> operateTagsErrorHandler(final Object awsRequest,
final Exception exception,
final ProxyClient<RedshiftClient> client,
final ResourceModel model,
final CallbackContext context) {
if (exception instanceof ResourceNotFoundException) {
return ProgressEvent.defaultFailureHandler(exception, HandlerErrorCode.NotFound);
} else if (exception instanceof InvalidTagException ||
exception instanceof InvalidClusterStateException) {
return ProgressEvent.defaultFailureHandler(exception, HandlerErrorCode.InvalidRequest);
} else {
return ProgressEvent.failed(model, context, HandlerErrorCode.UnauthorizedTaggingOperation, exception.getMessage());
}
}
}
Loading