Skip to content

Commit

Permalink
DO-1534: upgrade rabbitmq construct
Browse files Browse the repository at this point in the history
  • Loading branch information
gowrizrh committed Sep 27, 2023
1 parent c010dde commit dabddc2
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 0 deletions.
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions packages/rabbitmq/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.js
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out
11 changes: 11 additions & 0 deletions packages/rabbitmq/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.ts
!lib/handlers/*.ts
!*.d.ts
!*.js

# CDK asset staging directory
.cdk.staging
cdk.out

# Samples
sample/
1 change: 1 addition & 0 deletions packages/rabbitmq/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10.1.0
1 change: 1 addition & 0 deletions packages/rabbitmq/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.7.0
Binary file added packages/rabbitmq/CDKPipeline-RabbitMQ.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 88 additions & 0 deletions packages/rabbitmq/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Aligent AWS RabbitMQ

## Overview
This repository defines a CDK construct for hosting a RabbitMQ cluster within AWS.
It can be imported and used within CDK applications.

## Example
The following CDK snippet can be used to provision the static hosting stack.

```
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { RabbitMq } from '@aligent/cdk-rabbitmq'
import { Construct } from '@aws-cdk/core';
const mqStackProps = {
env: {
region: 'ap-southeast-2',
account: 'account-id-goes-here',
},
rabbitMQProps: {
autoMinorVersionUpgrade: true,
brokerName: 'brokerName',
deploymentMode: 'SINGLE_INSTANCE',
engineType: 'RABBITMQ',
engineVersion: '3.8.6',
hostInstanceType: 'mq.t3.micro',
publiclyAccessible: false,
users: [{
username: 'username',
password: 'password'
}],
logs: { general: true },
maintenanceWindowStartTime: {
dayOfWeek: 'Sunday',
timeOfDay: '00:00',
timeZone: 'Australia/Sydney'
},
},
applicationVpcId: string;
applicationSecurityGroupId: string;
};
const app = new cdk.App();
class RabbitMQStack extends Stack {
constructor(scope: Construct, id: string, props: hostingStackProps) {
super(scope, id, props);
new RabbitMQ(scope, 'rabbitmq', props.rabbitMQProps);
}
}
new RabbitMQStack(scope, 'rabbit-mq-stack', mqStackProps);
```

## Connection and communication
Applications talk to RabbitMQ via amqps protocol(5671/tcp). For visual management, use SSH tunneling.
1. Add the below in your local `~/.ssh/config` file with *profile* and *path* updated (works only for SSM-enabled environments):

host i-*
User ec2-user
ProxyCommand sh -c "aws --profile <TargetAccountProfile> ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
IdentityFile /path/to/ssh_key/for/backend_instance

2. Find RabbitMQ endpoint hostname and the application BE instance ID to run this command that will open a ssh connection (not an interactive shell with the `-N` flag):

ssh -N -L <random_local_port>:<RabbitMQ_endpoint>:443 <BEInstanceID>

for example,

ssh -L 56710:b-abcd-ef12-3456-7890-abcdef123456.mq.ap-southeast-2.amazonaws.com:443 i-abcdef1234567890

3. Open your web browser to access to the GUI (get id/pw from environments.ts)

https://localhost:<random_local_port_from_above>

for example,

https://localhost:56710


## Local development
[NPM link](https://docs.npmjs.com/cli/v7/commands/npm-link) can be used to develop the module locally.
1. Pull this repository locally
2. `cd` into this repository
3. run `npm link`
4. `cd` into the downstream repo (target project, etc) and run `npm link 'aws-rabbitmq-stack'`
The downstream repository should now include a symlink to this module. Allowing local changes to be tested before pushing.
3 changes: 3 additions & 0 deletions packages/rabbitmq/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { RabbitMQ } from "./lib/rabbitmq-construct";

export { RabbitMQ };
68 changes: 68 additions & 0 deletions packages/rabbitmq/lib/rabbitmq-construct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Construct } from "constructs";
import { CfnOutput } from "aws-cdk-lib";
import { SecurityGroup, Vpc, Port } from "aws-cdk-lib/aws-ec2";
import { CfnBrokerProps, CfnBroker } from "aws-cdk-lib/aws-amazonmq";

export interface RabbitMQProps {
rabbitMQProps: CfnBrokerProps;
applicationVpcId: string;
applicationSecurityGroupId: string;
}

export class RabbitMQ extends Construct {
constructor(scope: Construct, id: string, props: RabbitMQProps) {
super(scope, id);

const sourceSecurityGroup = SecurityGroup.fromLookupById(
this,
id + "-sourceSecurityGroup",
props.applicationSecurityGroupId
);

const applicationVpc = Vpc.fromLookup(this, id + "-applicationVpc", {
vpcId: props.applicationVpcId,
});

const securityGroup = new SecurityGroup(this, id + "-securityGroup", {
vpc: applicationVpc,
allowAllOutbound: false,
});

securityGroup.addIngressRule(sourceSecurityGroup, Port.tcp(5671));
securityGroup.addIngressRule(sourceSecurityGroup, Port.tcp(443));

// Choose only one or two subnets out of all the available private ones
const rabbitMqSubnets: string[] = [];
if (props.rabbitMQProps.deploymentMode == "SINGLE_INSTANCE") {
rabbitMqSubnets.push(applicationVpc.privateSubnets[0].subnetId);
} else {
rabbitMqSubnets.push(applicationVpc.privateSubnets[0].subnetId);
rabbitMqSubnets.push(applicationVpc.privateSubnets[1].subnetId);
}

const rabbitMQ = new CfnBroker(this, id + "-rabbitMQBroker", {
autoMinorVersionUpgrade: props.rabbitMQProps.autoMinorVersionUpgrade,
brokerName: props.rabbitMQProps.brokerName,
deploymentMode: props.rabbitMQProps.deploymentMode,
engineType: props.rabbitMQProps.engineType,
engineVersion: props.rabbitMQProps.engineVersion,
hostInstanceType: props.rabbitMQProps.hostInstanceType,
publiclyAccessible: props.rabbitMQProps.publiclyAccessible,
users: props.rabbitMQProps.users,
logs: props.rabbitMQProps.logs,
maintenanceWindowStartTime:
props.rabbitMQProps.maintenanceWindowStartTime,
securityGroups: [securityGroup.securityGroupId],
subnetIds: rabbitMqSubnets,
});

// Cfn does not respect .split(). We will get by with Arn for now.
// const arn = rabbitmq.attrArn
// const endpoint = arn.split(":", 7) + '.mq.' + this.region + '.amazonaws.com'
new CfnOutput(this, rabbitMQ.brokerName + "Arn", {
// value: rendpoint,
value: rabbitMQ.attrArn,
exportName: rabbitMQ.brokerName + "Arn",
});
}
}
30 changes: 30 additions & 0 deletions packages/rabbitmq/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@aligent/cdk-rabbitmq",
"version": "2.0.0",
"main": "index.js",
"license": "GPL-3.0-only",
"homepage": "https://github.com/aligent/aws-rabbitmq-waf-stack#readme",
"repository": {
"type": "git",
"url": "https://github.com/aligent/aws-rabbitmq-waf-stack"
},
"types": "index.d.ts",
"scripts": {
"build": "tsc",
"prepublish": "tsc"
},
"devDependencies": {
"@types/jest": "^29.5.5",
"@types/node": "20.6.3",
"aws-cdk": "2.97.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "~5.2.2"
},
"dependencies": {
"aws-cdk-lib": "2.97.0",
"constructs": "^10.0.0",
"source-map-support": "^0.5.21"
}
}
3 changes: 3 additions & 0 deletions packages/rabbitmq/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.json"
}

0 comments on commit dabddc2

Please sign in to comment.