Skip to content

Commit 973d234

Browse files
authored
fix(rds): cannot use connections in rds.DatabaseInstance.fromLookup (#35193)
### Issue # (if applicable) Closes #35192 ### Reason for this change This change fixes an issue in DatabaseInstance.fromLookup() where port values aren't properly converted from strings to numbers. This causes validation errors when setting up access permissions using the connections interface, as CfnSecurityGroupIngressProps requires port values to be numbers, not strings. ### Description of changes Modified `instance.ts` in the `fromLookup` method to convert the port string to a number. ### Describe any new or updated permissions being added N/A ### Description of how you validated changes Add a unit test. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 8a26869 commit 973d234

File tree

2 files changed

+88
-35
lines changed

2 files changed

+88
-35
lines changed

packages/aws-cdk-lib/aws-rds/lib/instance.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
188188

189189
return this.fromDatabaseInstanceAttributes(scope, id, {
190190
instanceEndpointAddress: instance['Endpoint.Address'],
191-
port: instance['Endpoint.Port'],
191+
port: Number(instance['Endpoint.Port']),
192192
instanceIdentifier: options.instanceIdentifier,
193193
securityGroups: securityGroups,
194194
instanceResourceId: instance.DbiResourceId,

packages/aws-cdk-lib/aws-rds/test/instance.from-lookup.test.ts

Lines changed: 87 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Match, Template } from '../../assertions';
2+
import * as ec2 from '../../aws-ec2';
13
import * as cxschema from '../../cloud-assembly-schema';
24
import { ContextProvider, Stack } from '../../core';
35
import * as rds from '../lib';
@@ -66,71 +68,71 @@ describe('DatabaseInstanceBase from lookup', () => {
6668
});
6769
});
6870

69-
describe("DatabaseInstanceBase from lookup with DBSG", () => {
70-
test("return correct instance info", () => {
71+
describe('DatabaseInstanceBase from lookup with DBSG', () => {
72+
test('return correct instance info', () => {
7173
// GIVEN
7274
const resultObjs = [
7375
{
74-
DBInstanceArn: "arn:aws:rds:us-east-1:123456789012:db:instance-1",
75-
"Endpoint.Address": "instance-1.testserver.us-east-1.rds.amazonaws.com",
76-
"Endpoint.Port": "5432",
77-
DbiResourceId: "db-ABCDEFGHI",
78-
DBSecurityGroups: ["dbsg-1", "dbsg-2"],
79-
VPCSecurityGroups: [],
80-
Identifier: "instance-1",
76+
'DBInstanceArn': 'arn:aws:rds:us-east-1:123456789012:db:instance-1',
77+
'Endpoint.Address': 'instance-1.testserver.us-east-1.rds.amazonaws.com',
78+
'Endpoint.Port': '5432',
79+
'DbiResourceId': 'db-ABCDEFGHI',
80+
'DBSecurityGroups': ['dbsg-1', 'dbsg-2'],
81+
'VPCSecurityGroups': [],
82+
'Identifier': 'instance-1',
8183
},
8284
];
8385
const value = {
8486
value: resultObjs,
8587
};
86-
const mock = jest.spyOn(ContextProvider, "getValue").mockReturnValue(value);
88+
const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value);
8789

8890
// WHEN
8991
const stack = new Stack(undefined, undefined, {
90-
env: { region: "us-east-1", account: "123456789012" },
92+
env: { region: 'us-east-1', account: '123456789012' },
9193
});
92-
const instance = rds.DatabaseInstance.fromLookup(stack, "MyInstance", {
93-
instanceIdentifier: "instance-1",
94+
const instance = rds.DatabaseInstance.fromLookup(stack, 'MyInstance', {
95+
instanceIdentifier: 'instance-1',
9496
});
9597

9698
// THEN
97-
expect(instance.instanceIdentifier).toEqual("instance-1");
99+
expect(instance.instanceIdentifier).toEqual('instance-1');
98100
expect(instance.dbInstanceEndpointAddress).toEqual(
99-
"instance-1.testserver.us-east-1.rds.amazonaws.com"
101+
'instance-1.testserver.us-east-1.rds.amazonaws.com'
100102
);
101-
expect(instance.dbInstanceEndpointPort).toEqual("5432");
102-
expect(instance.instanceResourceId).toEqual("db-ABCDEFGHI");
103+
expect(instance.dbInstanceEndpointPort).toEqual('5432');
104+
expect(instance.instanceResourceId).toEqual('db-ABCDEFGHI');
103105
expect(instance.connections.securityGroups.length).toEqual(2);
104106
expect(instance.connections.securityGroups[0].securityGroupId).toEqual(
105-
"dbsg-1"
107+
'dbsg-1'
106108
);
107109
expect(instance.connections.securityGroups[1].securityGroupId).toEqual(
108-
"dbsg-2"
110+
'dbsg-2'
109111
);
110112

111113
expect(mock).toHaveBeenCalledWith(stack, {
112114
provider: cxschema.ContextProvider.CC_API_PROVIDER,
113115
props: {
114-
typeName: "AWS::RDS::DBInstance",
115-
exactIdentifier: "instance-1",
116+
typeName: 'AWS::RDS::DBInstance',
117+
exactIdentifier: 'instance-1',
116118
propertiesToReturn: [
117-
"DBInstanceArn",
118-
"Endpoint.Address",
119-
"Endpoint.Port",
120-
"DbiResourceId",
121-
"DBSecurityGroups",
122-
"VPCSecurityGroups",
119+
'DBInstanceArn',
120+
'Endpoint.Address',
121+
'Endpoint.Port',
122+
'DbiResourceId',
123+
'DBSecurityGroups',
124+
'VPCSecurityGroups',
123125
],
124126
} as cxschema.CcApiContextQuery,
125127
dummyValue: [
126128
{
127-
Identifier: "TEST",
128-
DBInstanceArn: "TESTARN",
129-
"Endpoint.Address": "TESTADDRESS",
130-
"Endpoint.Port": "5432",
131-
DbiResourceId: "TESTID",
132-
DBSecurityGroups: [],
133-
VPCSecurityGroups: [],
129+
'Identifier': 'TEST',
130+
'DBInstanceArn': 'TESTARN',
131+
'Endpoint.Address': 'TESTADDRESS',
132+
'Endpoint.Port': '5432',
133+
'DbiResourceId': 'TESTID',
134+
'DBSecurityGroups': [],
135+
'VPCSecurityGroups': [],
134136
},
135137
],
136138
});
@@ -203,4 +205,55 @@ describe('DatabaseInstanceBase from lookup with VPCSecurityGroups', () => {
203205
mock.mockRestore();
204206
});
205207
});
208+
209+
describe('DatabaseInstanceBase connections', () => {
210+
test('allows adding security group ingress rules', () => {
211+
// GIVEN
212+
const resultObjs = [
213+
{
214+
'DBInstanceArn': 'arn:aws:rds:us-east-1:123456789012:db:instance-1',
215+
'Endpoint.Address': 'instance-1.testserver.us-east-1.rds.amazonaws.com',
216+
'Endpoint.Port': '5432',
217+
'DbiResourceId': 'db-ABCDEFGHI',
218+
'DBSecurityGroups': [],
219+
'VPCSecurityGroups': ['sg-1', 'sg-2'],
220+
'Identifier': 'instance-1',
221+
},
222+
];
223+
const value = { value: resultObjs };
224+
const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value);
225+
226+
// WHEN
227+
const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' } });
228+
229+
const securityGroup = ec2.SecurityGroup.fromSecurityGroupId(stack, 'TestSG', 'sg-test');
230+
231+
const instance = rds.DatabaseInstance.fromLookup(stack, 'MyInstance', {
232+
instanceIdentifier: 'instance-1',
233+
});
234+
235+
instance.connections.allowDefaultPortFrom(securityGroup, 'Allow from test SG');
236+
237+
// THEN
238+
Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', {
239+
IpProtocol: 'tcp',
240+
FromPort: 5432,
241+
ToPort: 5432,
242+
Description: 'Allow from test SG',
243+
SourceSecurityGroupId: 'sg-test',
244+
GroupId: 'sg-1'
245+
});
246+
247+
Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', {
248+
IpProtocol: 'tcp',
249+
FromPort: 5432,
250+
ToPort: 5432,
251+
Description: 'Allow from test SG',
252+
SourceSecurityGroupId: 'sg-test',
253+
GroupId: 'sg-2'
254+
});
255+
256+
mock.mockRestore();
257+
});
258+
});
206259
/* eslint-enable */

0 commit comments

Comments
 (0)