diff --git a/packages/aws-cdk-lib/aws-rds/lib/instance.ts b/packages/aws-cdk-lib/aws-rds/lib/instance.ts index 2b5151895cb97..3e2abb8476cd0 100644 --- a/packages/aws-cdk-lib/aws-rds/lib/instance.ts +++ b/packages/aws-cdk-lib/aws-rds/lib/instance.ts @@ -188,7 +188,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase return this.fromDatabaseInstanceAttributes(scope, id, { instanceEndpointAddress: instance['Endpoint.Address'], - port: instance['Endpoint.Port'], + port: Number(instance['Endpoint.Port']), instanceIdentifier: options.instanceIdentifier, securityGroups: securityGroups, instanceResourceId: instance.DbiResourceId, diff --git a/packages/aws-cdk-lib/aws-rds/test/instance.from-lookup.test.ts b/packages/aws-cdk-lib/aws-rds/test/instance.from-lookup.test.ts index bd3e6e492ad89..dd38df6fd4463 100644 --- a/packages/aws-cdk-lib/aws-rds/test/instance.from-lookup.test.ts +++ b/packages/aws-cdk-lib/aws-rds/test/instance.from-lookup.test.ts @@ -1,3 +1,5 @@ +import { Match, Template } from '../../assertions'; +import * as ec2 from '../../aws-ec2'; import * as cxschema from '../../cloud-assembly-schema'; import { ContextProvider, Stack } from '../../core'; import * as rds from '../lib'; @@ -66,71 +68,71 @@ describe('DatabaseInstanceBase from lookup', () => { }); }); -describe("DatabaseInstanceBase from lookup with DBSG", () => { - test("return correct instance info", () => { +describe('DatabaseInstanceBase from lookup with DBSG', () => { + test('return correct instance info', () => { // GIVEN const resultObjs = [ { - DBInstanceArn: "arn:aws:rds:us-east-1:123456789012:db:instance-1", - "Endpoint.Address": "instance-1.testserver.us-east-1.rds.amazonaws.com", - "Endpoint.Port": "5432", - DbiResourceId: "db-ABCDEFGHI", - DBSecurityGroups: ["dbsg-1", "dbsg-2"], - VPCSecurityGroups: [], - Identifier: "instance-1", + 'DBInstanceArn': 'arn:aws:rds:us-east-1:123456789012:db:instance-1', + 'Endpoint.Address': 'instance-1.testserver.us-east-1.rds.amazonaws.com', + 'Endpoint.Port': '5432', + 'DbiResourceId': 'db-ABCDEFGHI', + 'DBSecurityGroups': ['dbsg-1', 'dbsg-2'], + 'VPCSecurityGroups': [], + 'Identifier': 'instance-1', }, ]; const value = { value: resultObjs, }; - const mock = jest.spyOn(ContextProvider, "getValue").mockReturnValue(value); + const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value); // WHEN const stack = new Stack(undefined, undefined, { - env: { region: "us-east-1", account: "123456789012" }, + env: { region: 'us-east-1', account: '123456789012' }, }); - const instance = rds.DatabaseInstance.fromLookup(stack, "MyInstance", { - instanceIdentifier: "instance-1", + const instance = rds.DatabaseInstance.fromLookup(stack, 'MyInstance', { + instanceIdentifier: 'instance-1', }); // THEN - expect(instance.instanceIdentifier).toEqual("instance-1"); + expect(instance.instanceIdentifier).toEqual('instance-1'); expect(instance.dbInstanceEndpointAddress).toEqual( - "instance-1.testserver.us-east-1.rds.amazonaws.com" + 'instance-1.testserver.us-east-1.rds.amazonaws.com' ); - expect(instance.dbInstanceEndpointPort).toEqual("5432"); - expect(instance.instanceResourceId).toEqual("db-ABCDEFGHI"); + expect(instance.dbInstanceEndpointPort).toEqual('5432'); + expect(instance.instanceResourceId).toEqual('db-ABCDEFGHI'); expect(instance.connections.securityGroups.length).toEqual(2); expect(instance.connections.securityGroups[0].securityGroupId).toEqual( - "dbsg-1" + 'dbsg-1' ); expect(instance.connections.securityGroups[1].securityGroupId).toEqual( - "dbsg-2" + 'dbsg-2' ); expect(mock).toHaveBeenCalledWith(stack, { provider: cxschema.ContextProvider.CC_API_PROVIDER, props: { - typeName: "AWS::RDS::DBInstance", - exactIdentifier: "instance-1", + typeName: 'AWS::RDS::DBInstance', + exactIdentifier: 'instance-1', propertiesToReturn: [ - "DBInstanceArn", - "Endpoint.Address", - "Endpoint.Port", - "DbiResourceId", - "DBSecurityGroups", - "VPCSecurityGroups", + 'DBInstanceArn', + 'Endpoint.Address', + 'Endpoint.Port', + 'DbiResourceId', + 'DBSecurityGroups', + 'VPCSecurityGroups', ], } as cxschema.CcApiContextQuery, dummyValue: [ { - Identifier: "TEST", - DBInstanceArn: "TESTARN", - "Endpoint.Address": "TESTADDRESS", - "Endpoint.Port": "5432", - DbiResourceId: "TESTID", - DBSecurityGroups: [], - VPCSecurityGroups: [], + 'Identifier': 'TEST', + 'DBInstanceArn': 'TESTARN', + 'Endpoint.Address': 'TESTADDRESS', + 'Endpoint.Port': '5432', + 'DbiResourceId': 'TESTID', + 'DBSecurityGroups': [], + 'VPCSecurityGroups': [], }, ], }); @@ -203,4 +205,55 @@ describe('DatabaseInstanceBase from lookup with VPCSecurityGroups', () => { mock.mockRestore(); }); }); + +describe('DatabaseInstanceBase connections', () => { + test('allows adding security group ingress rules', () => { + // GIVEN + const resultObjs = [ + { + 'DBInstanceArn': 'arn:aws:rds:us-east-1:123456789012:db:instance-1', + 'Endpoint.Address': 'instance-1.testserver.us-east-1.rds.amazonaws.com', + 'Endpoint.Port': '5432', + 'DbiResourceId': 'db-ABCDEFGHI', + 'DBSecurityGroups': [], + 'VPCSecurityGroups': ['sg-1', 'sg-2'], + 'Identifier': 'instance-1', + }, + ]; + const value = { value: resultObjs }; + const mock = jest.spyOn(ContextProvider, 'getValue').mockReturnValue(value); + + // WHEN + const stack = new Stack(undefined, undefined, { env: { region: 'us-east-1', account: '123456789012' } }); + + const securityGroup = ec2.SecurityGroup.fromSecurityGroupId(stack, 'TestSG', 'sg-test'); + + const instance = rds.DatabaseInstance.fromLookup(stack, 'MyInstance', { + instanceIdentifier: 'instance-1', + }); + + instance.connections.allowDefaultPortFrom(securityGroup, 'Allow from test SG'); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', { + IpProtocol: 'tcp', + FromPort: 5432, + ToPort: 5432, + Description: 'Allow from test SG', + SourceSecurityGroupId: 'sg-test', + GroupId: 'sg-1' + }); + + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', { + IpProtocol: 'tcp', + FromPort: 5432, + ToPort: 5432, + Description: 'Allow from test SG', + SourceSecurityGroupId: 'sg-test', + GroupId: 'sg-2' + }); + + mock.mockRestore(); + }); +}); /* eslint-enable */