Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added AWS managed service provisioning #252

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
24 changes: 21 additions & 3 deletions aws-cdk/beckn-cdk/.env
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### AWS ENVIRONMENT SPECIFIC VARIABLES ###

# AWS account ID
ACCOUNT="####"
ACCOUNT="###"

# AWS region to deploy services (default: "ap-south-1")
REGION="ap-south-1"
Expand All @@ -26,8 +26,26 @@ EC2_INSTANCE_TYPE="t3.large"

# IAM role ARN for Amazon EKS master role
# (to be associated with the system:masters RBAC group for super-user access)
ROLE_ARN="arn:aws:iam::####:role/Admin"
ROLE_ARN="arn:aws:iam::###:role/Admin"

## Needed for managed services
# DocumentDB password (default: docdb1234)
DOCDB_PASSWORD="docdb1234"

# RabbitMQ password (default: rabbitmq1234)
RABBITMQ_PASSWORD="rabbitmq1234"

# Redis Nodes count
REDIS_NO_NODES="1"

#Redis Instance Type
REDIS_INSTANCE_TYPE="cache.t3.medium"

#DocumentDB Instance type
DOCDB_INSTANCE_TYPE="db.r5.large"

#RabbitMQ Instance Type
RABBITMQ_INSTANCE_TYPE="mq.m5.large"

#### BECKN-ONIX SPECIFIC MANDATORY VARIABLES ####

Expand Down Expand Up @@ -56,4 +74,4 @@ BAP_PUBLIC_KEY="####" # Pls check user guide for key generation
# BPP (Buyer Platform Provider) Configuration
BPP_EXTERNAL_DOMAIN="####" # E.g. bpp-cdk.beckn-onix-aws-cdk.becknprotocol.io
BPP_PRIVATE_KEY="####" # Pls check user guide for key generation
BPP_PUBLIC_KEY="####" # Pls check user guide for key generation
BPP_PUBLIC_KEY="####" # Pls check user guide for key generation
54 changes: 51 additions & 3 deletions aws-cdk/beckn-cdk/bin/beckn-cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { HelmGatewayStack } from '../lib/helm-gateway';
import { HelmCommonServicesStack } from '../lib/helm-beckn-common-services';
import { HelmBapStack } from '../lib/helm-bap';
import { HelmBppStack } from '../lib/helm-bpp';
import { LambdaStack } from '../lib/lambda-stack';


const config = getConfig();
Expand Down Expand Up @@ -74,6 +75,12 @@ const deployBAP = () => {
const vpcStack = new VpcStack(app, 'BapVpcStack', { config: config, env });
const eksStack = new EksStack(app, 'BapEksStack', {config: config, vpc: vpcStack.vpc, env });

// if(service === 'managed'){
// new DocumentDbStack(app, 'DocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
// new RedisStack(app, 'RedisStack', { vpc: vpcStack.vpc, env });
// new RabbitMqStack(app, 'RabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
// }else {

// bitnami - common services on eks - self hosted
new HelmCommonServicesStack(app, 'HelmBapCommonServicesStack', {
config: config,
Expand All @@ -82,6 +89,8 @@ const deployBAP = () => {
env,
});

// }

new HelmBapStack(app, 'HelmBapStack', {
config: config,
eksCluster: eksStack.cluster,
Expand All @@ -91,20 +100,29 @@ const deployBAP = () => {
env,
});

return vpcStack;
};

// Function to deploy BPP environment
const deployBPP = () => {
const vpcStack = new VpcStack(app, 'BppVpcStack', {config: config, env });
const eksStack = new EksStack(app, 'BppEksStack', {config: config, vpc: vpcStack.vpc, env });

// if(service === 'managed'){
// new DocumentDbStack(app, 'DocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
// new RedisStack(app, 'RedisStack', { vpc: vpcStack.vpc, env });
// new RabbitMqStack(app, 'RabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
// }else {

// if bitnami
new HelmCommonServicesStack(app, 'HelmBapCommonServicesStack', {
config: config,
eksCluster: eksStack.cluster,
service: 'bpp',
env,
});

// }

new HelmBppStack(app, 'HelmBppStack', {
config: config,
Expand All @@ -114,6 +132,8 @@ const deployBPP = () => {
isSandbox: false,
env,
});

return vpcStack;
};

// Function to deploy sandbox environment (all stacks)
Expand All @@ -122,6 +142,13 @@ const deploySandbox = () => {
const vpcStack = new VpcStack(app, 'VpcStack', {config: config, env });
const eksStack = new EksStack(app, 'EksStack', {config: config, vpc: vpcStack.vpc, env });
const rdsStack = new RdsStack(app, 'RdsStack', { config: config, vpc: vpcStack.vpc, envC: envC, env });

new LambdaStack(app, 'LambdaStack', {
rdsHost: rdsStack.rdsHost,
rdsUser: config.RDS_USER,
rdsPassword: rdsStack.rdsPassword,
vpc: vpcStack.vpc, env
});

new HelmRegistryStack(app, 'HelmRegistryStack', {
config: config,
Expand All @@ -139,6 +166,12 @@ const deploySandbox = () => {
env,
});

// if(service === 'managed'){
// new DocumentDbStack(app, 'DocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
// new RedisStack(app, 'RedisStack', { vpc: vpcStack.vpc, env });
// new RabbitMqStack(app, 'RabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
// } else {

// default - bitnami
new HelmCommonServicesStack(app, 'BapHelmCommonServicesStack', {
config: config,
Expand All @@ -154,6 +187,8 @@ const deploySandbox = () => {
env,
});

// }

new HelmBapStack(app, 'HelmBapStack', {
config: config,
eksCluster: eksStack.cluster,
Expand All @@ -171,16 +206,27 @@ const deploySandbox = () => {
isSandbox: true,
env,
});

return vpcStack;
};

const deployManagedStack = (vpcStack: VpcStack) => {
new DocumentDbStack(app, 'DocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
new RedisStack(app, 'RedisStack', { config: config, vpc: vpcStack.vpc, env });
new RabbitMqStack(app, 'RabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
}

// Retrieve the environment from CDK context
const environment = app.node.tryGetContext('env');
// const service = app.node.tryGetContext('service') || 'common'; // can be common or managed
const bap_bpp_managed = app.node.tryGetContext('bap_bpp_managed') || 'common';

// Deploy based on the selected environment
switch (environment) {
case 'sandbox':
console.log('Deploying sandbox environment...');
deploySandbox();
const vpcStack_sandbox = deploySandbox();
if(bap_bpp_managed === 'managed') deployManagedStack(vpcStack_sandbox);
break;
case 'registry':
console.log('Deploying registry environment...');
Expand All @@ -192,11 +238,13 @@ switch (environment) {
break;
case 'bap':
console.log('Deploying BAP environment...');
deployBAP();
const vpcStack_bap = deployBAP();
if(bap_bpp_managed === 'managed') deployManagedStack(vpcStack_bap);
break;
case 'bpp':
console.log('Deploying BPP environment...');
deployBPP();
const vpcStack_bpp = deployBPP();
if(bap_bpp_managed === 'managed') deployManagedStack(vpcStack_bpp);
break;
default:
console.error('Unknown environment specified.');
Expand Down
9 changes: 8 additions & 1 deletion aws-cdk/beckn-cdk/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export type ConfigProps = {
GATEWAY_EXTERNAL_DOMAIN: string;
BAP_EXTERNAL_DOMAIN: string;
BPP_EXTERNAL_DOMAIN: string;

REDIS_NO_INSTANCE: number;
REDIS_INSTANCE_TYPE: string;
DOCDB_INSTANCE_TYPE: string;
RABBITMQ_INSTANCE_TYPE: string;
};

export const getConfig = (): ConfigProps => ({
Expand All @@ -53,6 +56,10 @@ export const getConfig = (): ConfigProps => ({
ROLE_ARN: process.env.ROLE_ARN || "",
DOCDB_PASSWORD: process.env.DOCDB_PASSWORD || "",
RABBITMQ_PASSWORD: process.env.RABBITMQ_PASSWORD || "",
REDIS_NO_INSTANCE: Number(process.env.REDIS_NO_INSTANCE) || 1,
REDIS_INSTANCE_TYPE: process.env.REDIS_INSTANCE_TYPE || "cache.t3.medium",
DOCDB_INSTANCE_TYPE: process.env.DOCDB_INSTANCE_TYPE || "db.r5.large",
RABBITMQ_INSTANCE_TYPE: process.env.RABBITMQ_INSTANCE_TYPE || "mq.m5.large",
NAMESPACE: "-common-services",
BAP_PUBLIC_KEY: process.env.BAP_PUBLIC_KEY || "",
BAP_PRIVATE_KEY: process.env.BAP_PRIVATE_KEY || "",
Expand Down
4 changes: 2 additions & 2 deletions aws-cdk/beckn-cdk/lib/documentdb-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ export class DocumentDbStack extends cdk.Stack {
// Create 2 DocumentDB instances
new docdb.CfnDBInstance(this, 'DocDbInstance1', {
dbClusterIdentifier: docDbCluster.ref,
dbInstanceClass: 'db.r5.large',
dbInstanceClass: props.config.DOCDB_INSTANCE_TYPE,
});

new docdb.CfnDBInstance(this, 'DocDbInstance2', {
dbClusterIdentifier: docDbCluster.ref,
dbInstanceClass: 'db.r5.large',
dbInstanceClass: props.config.DOCDB_INSTANCE_TYPE,
});
}
}
64 changes: 64 additions & 0 deletions aws-cdk/beckn-cdk/lib/lambda-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as cr from 'aws-cdk-lib/custom-resources';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as path from 'path';
import { Construct } from 'constructs';

export interface LambdaStackProps extends cdk.StackProps {
vpc: ec2.Vpc;
rdsHost: string;
rdsUser: string;
rdsPassword: string;
}

export class LambdaStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: LambdaStackProps) {
super(scope, id, props);

const dbCreationLambda = new lambda.Function(this, 'DbCreationFunction', {
runtime: lambda.Runtime.NODEJS_LATEST,
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda')), // Path to your Lambda function code
handler: 'index.handler',
environment: {
DB_CONFIG: JSON.stringify({
host: props.rdsHost,
user: props.rdsUser,
password: props.rdsPassword,
}),
},
vpc: props.vpc,
securityGroups: [/* your security group here */],
vpcSubnets: {
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
});

dbCreationLambda.addToRolePolicy(new iam.PolicyStatement({
actions: ['rds-data:ExecuteStatement'],
resources: [`arn:aws:rds:${this.region}:${this.account}:cluster:your-cluster-name`], // Update with your RDS cluster ARN
}));

new cr.AwsCustomResource(this, 'InvokeDbCreation', {
onCreate: {
service: 'Lambda',
action: 'invoke',
parameters: {
FunctionName: dbCreationLambda.functionArn,
InvocationType: 'Event', // Use 'RequestResponse' if you want to wait for it to finish
},
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()), // Unique ID to force recreation if needed
},
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
actions: ['lambda:InvokeFunction'],
resources: [dbCreationLambda.functionArn],
}),
]),
});

// Grant the Lambda function permissions to read the RDS password
// props.rdsPassword.grantRead(dbCreationLambda);
}
}
Loading