feat: Add AWS CDK project and Helm charts for Beckn-Onix deployment on AWS cloud
This commit is contained in:
9
aws-cdk/beckn-cdk/.gitignore
vendored
Normal file
9
aws-cdk/beckn-cdk/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.js
|
||||
!jest.config.js
|
||||
*.d.ts
|
||||
node_modules
|
||||
|
||||
# CDK asset staging directory
|
||||
.cdk.staging
|
||||
cdk.out
|
||||
.env
|
||||
6
aws-cdk/beckn-cdk/.npmignore
Normal file
6
aws-cdk/beckn-cdk/.npmignore
Normal file
@@ -0,0 +1,6 @@
|
||||
*.ts
|
||||
!*.d.ts
|
||||
|
||||
# CDK asset staging directory
|
||||
.cdk.staging
|
||||
cdk.out
|
||||
14
aws-cdk/beckn-cdk/README.md
Normal file
14
aws-cdk/beckn-cdk/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Welcome to your CDK TypeScript project
|
||||
|
||||
This is a blank project for CDK development with TypeScript.
|
||||
|
||||
The `cdk.json` file tells the CDK Toolkit how to execute your app.
|
||||
|
||||
## Useful commands
|
||||
|
||||
* `npm run build` compile typescript to js
|
||||
* `npm run watch` watch for changes and compile
|
||||
* `npm run test` perform the jest unit tests
|
||||
* `npx cdk deploy` deploy this stack to your default AWS account/region
|
||||
* `npx cdk diff` compare deployed stack with current state
|
||||
* `npx cdk synth` emits the synthesized CloudFormation template
|
||||
220
aws-cdk/beckn-cdk/bin/beckn-cdk.ts
Normal file
220
aws-cdk/beckn-cdk/bin/beckn-cdk.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
#!/usr/bin/env node
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { StackProps } from 'aws-cdk-lib';
|
||||
import { ConfigProps, getConfig } from '../lib/config';
|
||||
|
||||
import { VpcStack } from '../lib/vpc-stack';
|
||||
import { RdsStack } from '../lib/rds-stack';
|
||||
import { EksStack } from '../lib/eks-stack';
|
||||
import { RedisStack } from '../lib/redis-stack';
|
||||
import { DocumentDbStack } from '../lib/documentdb-stack';
|
||||
import { RabbitMqStack } from '../lib/rabbitmq-stack';
|
||||
|
||||
import { HelmRegistryStack } from '../lib/helm-registry';
|
||||
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';
|
||||
|
||||
|
||||
const config = getConfig();
|
||||
const app = new cdk.App();
|
||||
|
||||
type AwsEnvStackProps = StackProps & {
|
||||
config: ConfigProps;
|
||||
};
|
||||
|
||||
// Retrieve AWS Account ID and Region from the environment
|
||||
const accountId = config.ACCOUNT;
|
||||
const region = config.REGION;
|
||||
|
||||
if (!accountId || !region) {
|
||||
console.error("AWS_ACCOUNT_ID or AWS_REGION is missing from .env file");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Common environment configuration for all stacks
|
||||
const env = { account: accountId, region: region };
|
||||
|
||||
// Function to deploy registry environment
|
||||
const deployRegistry = () => {
|
||||
var envC = "registry";
|
||||
const vpcStack = new VpcStack(app, 'RegistryVpcStack', { config: config, env });
|
||||
const eksStack = new EksStack(app, 'RegistryEksStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
const rdsStack = new RdsStack(app, 'RegistryRdsStack', { config: config, vpc: vpcStack.vpc, envC: envC, env });
|
||||
|
||||
new HelmRegistryStack(app, 'HelmRegistryStack', {
|
||||
config: config,
|
||||
rdsHost: rdsStack.rdsHost,
|
||||
rdsPassword: rdsStack.rdsPassword,
|
||||
eksCluster: eksStack.cluster,
|
||||
env,
|
||||
});
|
||||
};
|
||||
|
||||
// Function to deploy gateway environment
|
||||
const deployGateway = () => {
|
||||
var envC = "gateway";
|
||||
const vpcStack = new VpcStack(app, 'GatewayVpcStack', { config: config, env });
|
||||
const eksStack = new EksStack(app, 'GatewayEksStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
const rdsStack = new RdsStack(app, 'GatewayRdsStack', { config: config, vpc: vpcStack.vpc, envC: envC, env });
|
||||
|
||||
new HelmGatewayStack(app, 'HelmGatewayStack', {
|
||||
config: config,
|
||||
rdsHost: rdsStack.rdsHost,
|
||||
rdsPassword: rdsStack.rdsPassword,
|
||||
eksCluster: eksStack.cluster,
|
||||
env,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// Function to deploy BAP environment
|
||||
const deployBAP = () => {
|
||||
const vpcStack = new VpcStack(app, 'BapVpcStack', { config: config, env });
|
||||
const eksStack = new EksStack(app, 'BapEksStack', {config: config, vpc: vpcStack.vpc, env });
|
||||
|
||||
// aws common services deployed through aws managed services
|
||||
// rabbit mq -
|
||||
// new DocumentDbStack(app, 'BapDocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
// new RedisStack(app, 'BapRedisStack', { vpc: vpcStack.vpc, env });
|
||||
// new RabbitMqStack(app, 'BapRabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
|
||||
// bitnami - common services on eks - self hosted
|
||||
new HelmCommonServicesStack(app, 'HelmBapCommonServicesStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
service: 'bap',
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmBapStack(app, 'HelmBapStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
vpc: vpcStack.vpc,
|
||||
eksSecGrp: eksStack.eksSecGrp,
|
||||
isSandbox: false,
|
||||
env,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// 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 aws
|
||||
// new DocumentDbStack(app, 'BppDocumentDbStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
// new RedisStack(app, 'BppRedisStack', { vpc: vpcStack.vpc, env });
|
||||
// new RabbitMqStack(app, 'BppRabbitMqStack', { config: config, vpc: vpcStack.vpc, env });
|
||||
|
||||
// if bitnami
|
||||
new HelmCommonServicesStack(app, 'HelmBapCommonServicesStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
service: 'bpp',
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmBppStack(app, 'HelmBppStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
vpc: vpcStack.vpc,
|
||||
eksSecGrp: eksStack.eksSecGrp,
|
||||
isSandbox: false,
|
||||
env,
|
||||
});
|
||||
};
|
||||
|
||||
// Function to deploy sandbox environment (all stacks)
|
||||
const deploySandbox = () => {
|
||||
var envC = "sandbox";
|
||||
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 HelmRegistryStack(app, 'HelmRegistryStack', {
|
||||
config: config,
|
||||
rdsHost: rdsStack.rdsHost,
|
||||
rdsPassword: rdsStack.rdsPassword,
|
||||
eksCluster: eksStack.cluster,
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmGatewayStack(app, 'HelmGatewayStack', {
|
||||
config: config,
|
||||
rdsHost: rdsStack.rdsHost,
|
||||
rdsPassword: rdsStack.rdsPassword,
|
||||
eksCluster: eksStack.cluster,
|
||||
env,
|
||||
});
|
||||
|
||||
// aws
|
||||
// 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 });
|
||||
|
||||
// default - bitnami
|
||||
new HelmCommonServicesStack(app, 'BapHelmCommonServicesStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
service: 'bap',
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmCommonServicesStack(app, 'BppHelmCommonServicesStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
service: 'bpp',
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmBapStack(app, 'HelmBapStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
vpc: vpcStack.vpc,
|
||||
eksSecGrp: eksStack.eksSecGrp,
|
||||
isSandbox: true,
|
||||
env,
|
||||
});
|
||||
|
||||
new HelmBppStack(app, 'HelmBppStack', {
|
||||
config: config,
|
||||
eksCluster: eksStack.cluster,
|
||||
vpc: vpcStack.vpc,
|
||||
eksSecGrp: eksStack.eksSecGrp,
|
||||
isSandbox: true,
|
||||
env,
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the environment from CDK context
|
||||
const environment = app.node.tryGetContext('env');
|
||||
|
||||
// Deploy based on the selected environment
|
||||
switch (environment) {
|
||||
case 'sandbox':
|
||||
console.log('Deploying sandbox environment...');
|
||||
deploySandbox();
|
||||
break;
|
||||
case 'registry':
|
||||
console.log('Deploying registry environment...');
|
||||
deployRegistry();
|
||||
break;
|
||||
case 'gateway':
|
||||
console.log('Deploying gateway environment...');
|
||||
deployGateway();
|
||||
break;
|
||||
case 'bap':
|
||||
console.log('Deploying BAP environment...');
|
||||
deployBAP();
|
||||
break;
|
||||
case 'bpp':
|
||||
console.log('Deploying BPP environment...');
|
||||
deployBPP();
|
||||
break;
|
||||
default:
|
||||
console.error('Unknown environment specified.');
|
||||
process.exit(1);
|
||||
}
|
||||
12
aws-cdk/beckn-cdk/cdk.context.json
Normal file
12
aws-cdk/beckn-cdk/cdk.context.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"availability-zones:account=365975017663:region=ap-south-1": [
|
||||
"ap-south-1a",
|
||||
"ap-south-1b",
|
||||
"ap-south-1c"
|
||||
],
|
||||
"availability-zones:account=471112672919:region=ap-south-1": [
|
||||
"ap-south-1a",
|
||||
"ap-south-1b",
|
||||
"ap-south-1c"
|
||||
]
|
||||
}
|
||||
72
aws-cdk/beckn-cdk/cdk.json
Normal file
72
aws-cdk/beckn-cdk/cdk.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"app": "npx ts-node --prefer-ts-exts bin/beckn-cdk.ts",
|
||||
"watch": {
|
||||
"include": [
|
||||
"**"
|
||||
],
|
||||
"exclude": [
|
||||
"README.md",
|
||||
"cdk*.json",
|
||||
"**/*.d.ts",
|
||||
"**/*.js",
|
||||
"tsconfig.json",
|
||||
"package*.json",
|
||||
"yarn.lock",
|
||||
"node_modules",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
|
||||
"@aws-cdk/core:checkSecretUsage": true,
|
||||
"@aws-cdk/core:target-partitions": [
|
||||
"aws",
|
||||
"aws-cn"
|
||||
],
|
||||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
|
||||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
|
||||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
|
||||
"@aws-cdk/aws-iam:minimizePolicies": true,
|
||||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
|
||||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
|
||||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
|
||||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
|
||||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
|
||||
"@aws-cdk/core:enablePartitionLiterals": true,
|
||||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
|
||||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
|
||||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
|
||||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
|
||||
"@aws-cdk/aws-route53-patters:useCertificate": true,
|
||||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
|
||||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
|
||||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
|
||||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
|
||||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
|
||||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
|
||||
"@aws-cdk/aws-redshift:columnId": true,
|
||||
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
|
||||
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
|
||||
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
|
||||
"@aws-cdk/aws-kms:aliasNameRef": true,
|
||||
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
|
||||
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
|
||||
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
|
||||
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
|
||||
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
|
||||
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
|
||||
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
|
||||
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
|
||||
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
|
||||
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
|
||||
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
|
||||
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
|
||||
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
|
||||
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
|
||||
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
|
||||
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
|
||||
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
|
||||
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
|
||||
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false
|
||||
}
|
||||
}
|
||||
8
aws-cdk/beckn-cdk/jest.config.js
Normal file
8
aws-cdk/beckn-cdk/jest.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
roots: ['<rootDir>/test'],
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest'
|
||||
}
|
||||
};
|
||||
67
aws-cdk/beckn-cdk/lib/config.ts
Normal file
67
aws-cdk/beckn-cdk/lib/config.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import * as dotenv from "dotenv";
|
||||
import path = require("path");
|
||||
|
||||
dotenv.config({ path: path.resolve(__dirname, "../.env") });
|
||||
|
||||
export type ConfigProps = {
|
||||
REGION: string,
|
||||
ACCOUNT: string,
|
||||
REPOSITORY: string,
|
||||
REGISTRY_RELEASE_NAME: string;
|
||||
GATEWAY_RELEASE_NAME: string;
|
||||
BAP_RELEASE_NAME: string;
|
||||
BPP_RELEASE_NAME: string,
|
||||
RDS_USER: string,
|
||||
CERT_ARN: string,
|
||||
REGISTRY_URL: string,
|
||||
MAX_AZS: number,
|
||||
EKS_CLUSTER_NAME: string,
|
||||
CIDR: string,
|
||||
EC2_NODES_COUNT: number;
|
||||
EC2_INSTANCE_TYPE: string;
|
||||
ROLE_ARN: string;
|
||||
DOCDB_PASSWORD: string;
|
||||
RABBITMQ_PASSWORD: string;
|
||||
NAMESPACE: string;
|
||||
BAP_PUBLIC_KEY: string;
|
||||
BAP_PRIVATE_KEY: string;
|
||||
BPP_PUBLIC_KEY: string;
|
||||
BPP_PRIVATE_KEY: string;
|
||||
REGISTRY_EXTERNAL_DOMAIN: string,
|
||||
GATEWAY_EXTERNAL_DOMAIN: string;
|
||||
BAP_EXTERNAL_DOMAIN: string;
|
||||
BPP_EXTERNAL_DOMAIN: string;
|
||||
|
||||
};
|
||||
|
||||
export const getConfig = (): ConfigProps => ({
|
||||
REGION: process.env.REGION || "ap-south-1",
|
||||
ACCOUNT: process.env.ACCOUNT || "",
|
||||
REPOSITORY: process.env.BECKN_ONIX_HELM_REPOSITORY || "",
|
||||
MAX_AZS: Number(process.env.MAZ_AZs) || 2,
|
||||
REGISTRY_RELEASE_NAME: "beckn-onix-registry",
|
||||
GATEWAY_RELEASE_NAME: "beckn-onix-gateway",
|
||||
BAP_RELEASE_NAME: "beckn-onix-bap",
|
||||
BPP_RELEASE_NAME: "beckn-onix-bpp",
|
||||
RDS_USER: process.env.RDS_USER || "postgres",
|
||||
CERT_ARN: process.env.CERT_ARN || "", // user must provide it
|
||||
REGISTRY_URL: process.env.REGISTRY_URL || "", // beckn-onix reg url
|
||||
EKS_CLUSTER_NAME: process.env.EKS_CLUSTER_NAME || "beckn-onix",
|
||||
CIDR: process.env.CIDR || "10.20.0.0/16",
|
||||
EC2_NODES_COUNT: Number(process.env.EC2_NODES_COUNT) || 2,
|
||||
EC2_INSTANCE_TYPE: process.env.EC2_INSTANCE_TYPE || "t3.large",
|
||||
ROLE_ARN: process.env.ROLE_ARN || "",
|
||||
DOCDB_PASSWORD: process.env.DOCDB_PASSWORD || "",
|
||||
RABBITMQ_PASSWORD: process.env.RABBITMQ_PASSWORD || "",
|
||||
NAMESPACE: "-common-services",
|
||||
BAP_PUBLIC_KEY: process.env.BAP_PUBLIC_KEY || "",
|
||||
BAP_PRIVATE_KEY: process.env.BAP_PRIVATE_KEY || "",
|
||||
BPP_PUBLIC_KEY: process.env.BPP_PUBLIC_KEY || "",
|
||||
BPP_PRIVATE_KEY: process.env.BPP_PRIVATE_KEY || "",
|
||||
REGISTRY_EXTERNAL_DOMAIN: process.env.REGISTRY_EXTERNAL_DOMAIN || "", // user must provide it
|
||||
GATEWAY_EXTERNAL_DOMAIN: process.env.GATEWAY_EXTERNAL_DOMAIN || "", // user must provide it
|
||||
BAP_EXTERNAL_DOMAIN: process.env.BAP_EXTERNAL_DOMAIN || "", // user must provide it
|
||||
BPP_EXTERNAL_DOMAIN: process.env.BPP_EXTERNAL_DOMAIN || "", // user must provide it
|
||||
|
||||
|
||||
});
|
||||
64
aws-cdk/beckn-cdk/lib/documentdb-stack.ts
Normal file
64
aws-cdk/beckn-cdk/lib/documentdb-stack.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as docdb from 'aws-cdk-lib/aws-docdb';
|
||||
import * as dotenv from 'dotenv';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
// Load environment variables from .env file
|
||||
dotenv.config();
|
||||
|
||||
interface DocumentDbStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class DocumentDbStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props: DocumentDbStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
// Use environment variable from .env file or fallback to a default value
|
||||
const docDbPassword = new cdk.CfnParameter(this, 'DocDbPassword', {
|
||||
type: 'String',
|
||||
description: 'The password for the DocumentDB cluster admin user',
|
||||
noEcho: true,
|
||||
default: props.config.DOCDB_PASSWORD || '', // Use environment variable
|
||||
});
|
||||
|
||||
// Security group for DocumentDB
|
||||
const docDbSecurityGroup = new ec2.SecurityGroup(this, 'DocDbSecurityGroup', {
|
||||
vpc: props.vpc,
|
||||
description: 'Security group for DocumentDB',
|
||||
allowAllOutbound: true,
|
||||
});
|
||||
|
||||
docDbSecurityGroup.addIngressRule(ec2.Peer.ipv4(props.vpc.vpcCidrBlock), ec2.Port.tcp(27017), 'Allow DocumentDB traffic on port 27017');
|
||||
|
||||
// DocumentDB subnet group
|
||||
const docDbSubnetGroup = new docdb.CfnDBSubnetGroup(this, 'DocDbSubnetGroup', {
|
||||
dbSubnetGroupDescription: 'Subnet group for DocumentDB',
|
||||
subnetIds: props.vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }).subnetIds,
|
||||
});
|
||||
|
||||
// DocumentDB cluster
|
||||
const docDbCluster = new docdb.CfnDBCluster(this, 'DocDbCluster', {
|
||||
masterUsername: 'beckn',
|
||||
masterUserPassword: docDbPassword.valueAsString, // Password entered by the user
|
||||
dbClusterIdentifier: 'MyDocDbCluster',
|
||||
engineVersion: '4.0.0',
|
||||
vpcSecurityGroupIds: [docDbSecurityGroup.securityGroupId],
|
||||
dbSubnetGroupName: docDbSubnetGroup.ref,
|
||||
});
|
||||
|
||||
// Create 2 DocumentDB instances
|
||||
new docdb.CfnDBInstance(this, 'DocDbInstance1', {
|
||||
dbClusterIdentifier: docDbCluster.ref,
|
||||
dbInstanceClass: 'db.r5.large',
|
||||
});
|
||||
|
||||
new docdb.CfnDBInstance(this, 'DocDbInstance2', {
|
||||
dbClusterIdentifier: docDbCluster.ref,
|
||||
dbInstanceClass: 'db.r5.large',
|
||||
});
|
||||
}
|
||||
}
|
||||
149
aws-cdk/beckn-cdk/lib/eks-stack.ts
Normal file
149
aws-cdk/beckn-cdk/lib/eks-stack.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as iam from 'aws-cdk-lib/aws-iam';
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { KubectlV30Layer } from '@aws-cdk/lambda-layer-kubectl-v30';
|
||||
// import { CfnAutoScalingGroup } from 'aws-cdk-lib/aws-autoscaling';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
export interface EksStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class EksStack extends cdk.Stack {
|
||||
public readonly cluster: eks.Cluster;
|
||||
public readonly eksSecGrp: ec2.SecurityGroup;
|
||||
|
||||
constructor(scope: Construct, id: string, props: EksStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const config = props.config;
|
||||
|
||||
|
||||
const vpc = props.vpc;
|
||||
const cidr = config.CIDR; // from config file
|
||||
const EKS_CLUSTER_NAME = config.EKS_CLUSTER_NAME; // take it from config file
|
||||
// const ROLE_ARN = 'ROLE_ARN'; // take form config file
|
||||
const ROLE_ARN = config.ROLE_ARN;
|
||||
|
||||
const securityGroupEKS = new ec2.SecurityGroup(this, "EKSSecurityGroup", {
|
||||
vpc: vpc,
|
||||
allowAllOutbound: true,
|
||||
description: "Security group for EKS",
|
||||
});
|
||||
|
||||
securityGroupEKS.addIngressRule(
|
||||
ec2.Peer.ipv4(cidr),
|
||||
ec2.Port.allTraffic(),
|
||||
"Allow EKS traffic"
|
||||
|
||||
);
|
||||
// securityGroupEKS.addIngressRule(
|
||||
// ec2.Peer.securityGroupId(securityGroupEKS.securityGroupId),
|
||||
// ec2.Port.allTraffic(),
|
||||
// "Allow EKS traffic"
|
||||
// );
|
||||
|
||||
const iamRole = iam.Role.fromRoleArn(this, "MyIAMRole", ROLE_ARN);
|
||||
|
||||
// Create the EKS cluster
|
||||
this.cluster = new eks.Cluster(this, 'EksCluster', {
|
||||
vpc: vpc,
|
||||
vpcSubnets: [{ subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }],
|
||||
defaultCapacity: 0,
|
||||
// defaultCapacityInstance: new ec2.InstanceType(config.EC2_INSTANCE_TYPE),
|
||||
kubectlLayer: new KubectlV30Layer(this, 'KubectlLayer'),
|
||||
version: eks.KubernetesVersion.V1_30,
|
||||
securityGroup: securityGroupEKS,
|
||||
endpointAccess: eks.EndpointAccess.PUBLIC_AND_PRIVATE,
|
||||
ipFamily: eks.IpFamily.IP_V4,
|
||||
clusterName: EKS_CLUSTER_NAME,
|
||||
mastersRole: iamRole, // Assign the admin role to the cluster
|
||||
outputClusterName: true,
|
||||
outputConfigCommand: true,
|
||||
authenticationMode: eks.AuthenticationMode.API_AND_CONFIG_MAP,
|
||||
bootstrapClusterCreatorAdminPermissions: true,
|
||||
|
||||
albController: {
|
||||
version: eks.AlbControllerVersion.V2_8_1,
|
||||
repository: "public.ecr.aws/eks/aws-load-balancer-controller",
|
||||
},
|
||||
});
|
||||
|
||||
const key1 = this.cluster.openIdConnectProvider.openIdConnectProviderIssuer;
|
||||
const stringEquals = new cdk.CfnJson(this, 'ConditionJson', {
|
||||
value: {
|
||||
[`${key1}:sub`]: ['system:serviceaccount:kube-system:ebs-csi-controller-sa', 'system:serviceaccount:kube-system:efs-csi-controller-sa'],
|
||||
[`${key1}:aud`]: 'sts.amazonaws.com'
|
||||
},
|
||||
})
|
||||
|
||||
const oidcEKSCSIRole = new iam.Role(this, "OIDCRole", {
|
||||
assumedBy: new iam.FederatedPrincipal(
|
||||
`arn:aws:iam::${this.account}:oidc-provider/${this.cluster.clusterOpenIdConnectIssuer}`,
|
||||
{
|
||||
StringEquals: stringEquals,
|
||||
|
||||
},
|
||||
"sts:AssumeRoleWithWebIdentity"
|
||||
),
|
||||
});
|
||||
|
||||
// Attach a managed policy to the role
|
||||
oidcEKSCSIRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonEBSCSIDriverPolicy"))
|
||||
oidcEKSCSIRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AmazonEFSCSIDriverPolicy"))
|
||||
|
||||
const ebscsi = new eks.CfnAddon(this, "addonEbsCsi",
|
||||
{
|
||||
addonName: "aws-ebs-csi-driver",
|
||||
clusterName: this.cluster.clusterName,
|
||||
serviceAccountRoleArn: oidcEKSCSIRole.roleArn
|
||||
}
|
||||
);
|
||||
|
||||
const efscsi = new eks.CfnAddon(this, "addonEfsCsi",
|
||||
{
|
||||
addonName: "aws-efs-csi-driver",
|
||||
clusterName: this.cluster.clusterName,
|
||||
serviceAccountRoleArn: oidcEKSCSIRole.roleArn
|
||||
}
|
||||
);
|
||||
|
||||
new cdk.CfnOutput(this, String("OIDC-issuer"), {
|
||||
value: this.cluster.clusterOpenIdConnectIssuer,
|
||||
});
|
||||
|
||||
new cdk.CfnOutput(this, String("OIDC-issuerURL"), {
|
||||
value: this.cluster.clusterOpenIdConnectIssuerUrl,
|
||||
});
|
||||
|
||||
new cdk.CfnOutput(this, "EKS Cluster Name", {
|
||||
value: this.cluster.clusterName,
|
||||
});
|
||||
new cdk.CfnOutput(this, "EKS Cluster Arn", {
|
||||
value: this.cluster.clusterArn,
|
||||
});
|
||||
|
||||
const launchTemplate = new ec2.CfnLaunchTemplate(this, 'MyLaunchTemplate', {
|
||||
launchTemplateData: {
|
||||
instanceType: config.EC2_INSTANCE_TYPE,
|
||||
securityGroupIds: [this.cluster.clusterSecurityGroupId, securityGroupEKS.securityGroupId],
|
||||
}
|
||||
});
|
||||
|
||||
// Create node group using the launch template
|
||||
this.cluster.addNodegroupCapacity('CustomNodeGroup', {
|
||||
amiType: eks.NodegroupAmiType.AL2_X86_64,
|
||||
desiredSize: config.EC2_NODES_COUNT,
|
||||
launchTemplateSpec: {
|
||||
id: launchTemplate.ref,
|
||||
version: launchTemplate.attrLatestVersionNumber,
|
||||
},
|
||||
subnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
||||
});
|
||||
|
||||
this.eksSecGrp = securityGroupEKS;
|
||||
}
|
||||
}
|
||||
113
aws-cdk/beckn-cdk/lib/helm-bap.ts
Normal file
113
aws-cdk/beckn-cdk/lib/helm-bap.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as helm from 'aws-cdk-lib/aws-eks';
|
||||
import { Stack, StackProps } from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
import * as efs from 'aws-cdk-lib/aws-efs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as iam from 'aws-cdk-lib/aws-iam';
|
||||
|
||||
|
||||
interface HelmBapStackProps extends StackProps {
|
||||
config: ConfigProps;
|
||||
eksCluster: eks.Cluster;
|
||||
isSandbox: boolean;
|
||||
eksSecGrp: ec2.SecurityGroup;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class HelmBapStack extends Stack {
|
||||
constructor(scope: Construct, id: string, props: HelmBapStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const eksCluster = props.eksCluster;
|
||||
const externalDomain = props.config.BAP_EXTERNAL_DOMAIN;
|
||||
const certArn = props.config.CERT_ARN;
|
||||
const releaseName = props.config.BAP_RELEASE_NAME;
|
||||
const repository = props.config.REPOSITORY;
|
||||
const registryUrl = props.config.REGISTRY_URL;
|
||||
const bapPrivateKey = props.config.BAP_PRIVATE_KEY;
|
||||
const bapPublicKey = props.config.BAP_PUBLIC_KEY;
|
||||
|
||||
const isSandbox = props.isSandbox;
|
||||
|
||||
const myFileSystemPolicy = new iam.PolicyDocument({
|
||||
statements: [new iam.PolicyStatement({
|
||||
actions: [
|
||||
'elasticfilesystem:ClientRootAccess',
|
||||
'elasticfilesystem:ClientWrite',
|
||||
'elasticfilesystem:ClientMount',
|
||||
],
|
||||
principals: [new iam.ArnPrincipal('*')],
|
||||
resources: ['*'],
|
||||
conditions: {
|
||||
Bool: {
|
||||
'elasticfilesystem:AccessedViaMountTarget': 'true',
|
||||
},
|
||||
},
|
||||
})],
|
||||
});
|
||||
|
||||
const efsBapFileSystemId = new efs.FileSystem(this, 'Beckn-Onix-Bap', {
|
||||
vpc: props.vpc,
|
||||
securityGroup: props.eksSecGrp,
|
||||
fileSystemPolicy: myFileSystemPolicy,
|
||||
});
|
||||
|
||||
// let efsBapFileSystemId: string | undefined;
|
||||
// const existingFileSystemId = cdk.Fn.importValue('EfsBapFileSystemId');
|
||||
|
||||
// if(existingFileSystemId){
|
||||
// efsBapFileSystemId = existingFileSystemId;
|
||||
// } else{
|
||||
// const efsBapFileSystem = new efs.FileSystem(this, 'Beckn-Onix-Bap', {
|
||||
// vpc: props.vpc,
|
||||
// securityGroup: props.eksSecGrp,
|
||||
// });
|
||||
|
||||
// efsBapFileSystemId = efsBapFileSystem.fileSystemId;
|
||||
|
||||
// new cdk.CfnOutput(this, 'EfsBapFileSystemId', {
|
||||
// value: efsBapFileSystemId,
|
||||
// exportName: 'EfsBapFileSystemId',
|
||||
// })
|
||||
// }
|
||||
|
||||
// const efsBapFileSystemId = new efs.FileSystem(this, 'Beckn-Onix-Bap', {
|
||||
// vpc: props.vpc,
|
||||
// });
|
||||
|
||||
new helm.HelmChart(this, 'baphelm', {
|
||||
cluster: eksCluster,
|
||||
chart: 'beckn-onix-bap',
|
||||
release: releaseName,
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
global: {
|
||||
isSandbox: isSandbox,
|
||||
externalDomain: externalDomain,
|
||||
registry_url: registryUrl,
|
||||
bap: {
|
||||
privateKey: bapPrivateKey,
|
||||
publicKey: bapPublicKey,
|
||||
},
|
||||
efs: {
|
||||
fileSystemId: efsBapFileSystemId.fileSystemId,
|
||||
},
|
||||
ingress: {
|
||||
tls: {
|
||||
certificateArn: certArn,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
new cdk.CfnOutput(this, String("EksFileSystemId"), {
|
||||
value: efsBapFileSystemId.fileSystemId,
|
||||
});
|
||||
}
|
||||
}
|
||||
90
aws-cdk/beckn-cdk/lib/helm-beckn-common-services.ts
Normal file
90
aws-cdk/beckn-cdk/lib/helm-beckn-common-services.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as helm from 'aws-cdk-lib/aws-eks';
|
||||
import { Stack, StackProps } from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
|
||||
interface HelmCommonServicesStackProps extends StackProps {
|
||||
config: ConfigProps;
|
||||
eksCluster: eks.Cluster;
|
||||
service: string,
|
||||
}
|
||||
|
||||
export class HelmCommonServicesStack extends Stack {
|
||||
constructor(scope: Construct, id: string, props: HelmCommonServicesStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const eksCluster = props.eksCluster;
|
||||
const service = props.service;
|
||||
const repository = "https://charts.bitnami.com/bitnami";
|
||||
const namespace = props.config.NAMESPACE;
|
||||
|
||||
const generateRandomPassword = (length: number) => {
|
||||
return crypto.randomBytes(length).toString('hex').slice(0, length);
|
||||
};
|
||||
const rabbitMQPassword = generateRandomPassword(12);
|
||||
|
||||
new helm.HelmChart(this, "RedisHelmChart", {
|
||||
cluster: eksCluster,
|
||||
chart: "redis",
|
||||
namespace: service + namespace,
|
||||
release: "redis",
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
auth: {
|
||||
enabled: false
|
||||
},
|
||||
replica: {
|
||||
replicaCount: 0
|
||||
},
|
||||
master: {
|
||||
persistence: {
|
||||
storageClass: "gp2"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new helm.HelmChart(this, "MongoDBHelmChart", {
|
||||
cluster: eksCluster,
|
||||
chart: "mongodb",
|
||||
namespace: service + namespace,
|
||||
release: "mongodb",
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
persistence: {
|
||||
storageClass: "gp2"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new helm.HelmChart(this, "RabbitMQHelmChart", {
|
||||
cluster: eksCluster,
|
||||
chart: "rabbitmq",
|
||||
namespace: service + namespace,
|
||||
release: "rabbitmq",
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
persistence: {
|
||||
enabled: true,
|
||||
storageClass: "gp2"
|
||||
},
|
||||
auth: {
|
||||
username: "beckn",
|
||||
password: "beckn1234"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// new cdk.CfnOutput(this, String("RabbimqPassword"), {
|
||||
// value: rabbitMQPassword,
|
||||
// });
|
||||
|
||||
}
|
||||
}
|
||||
89
aws-cdk/beckn-cdk/lib/helm-bpp.ts
Normal file
89
aws-cdk/beckn-cdk/lib/helm-bpp.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as helm from 'aws-cdk-lib/aws-eks';
|
||||
import { Stack, StackProps } from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as efs from 'aws-cdk-lib/aws-efs';
|
||||
import * as iam from 'aws-cdk-lib/aws-iam';
|
||||
|
||||
interface HelmBppStackProps extends StackProps {
|
||||
config: ConfigProps;
|
||||
vpc: ec2.Vpc;
|
||||
isSandbox: boolean;
|
||||
eksSecGrp: ec2.SecurityGroup;
|
||||
eksCluster: eks.Cluster;
|
||||
}
|
||||
|
||||
export class HelmBppStack extends Stack {
|
||||
constructor(scope: Construct, id: string, props: HelmBppStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const eksCluster = props.eksCluster;
|
||||
const externalDomain = props.config.BPP_EXTERNAL_DOMAIN;
|
||||
const certArn = props.config.CERT_ARN;
|
||||
const releaseName = props.config.BPP_RELEASE_NAME;
|
||||
const repository = props.config.REPOSITORY;
|
||||
const registryUrl = props.config.REGISTRY_URL;
|
||||
|
||||
const bppPrivateKey = props.config.BPP_PRIVATE_KEY;
|
||||
const bppPublicKey = props.config.BPP_PUBLIC_KEY;
|
||||
|
||||
const isSandbox = props.isSandbox;
|
||||
|
||||
const myFileSystemPolicy = new iam.PolicyDocument({
|
||||
statements: [new iam.PolicyStatement({
|
||||
actions: [
|
||||
'elasticfilesystem:ClientRootAccess',
|
||||
'elasticfilesystem:ClientWrite',
|
||||
'elasticfilesystem:ClientMount',
|
||||
],
|
||||
principals: [new iam.ArnPrincipal('*')],
|
||||
resources: ['*'],
|
||||
conditions: {
|
||||
Bool: {
|
||||
'elasticfilesystem:AccessedViaMountTarget': 'true',
|
||||
},
|
||||
},
|
||||
})],
|
||||
});
|
||||
|
||||
const efsBppFileSystemId = new efs.FileSystem(this, 'Beckn-Onix-Bpp', {
|
||||
vpc: props.vpc,
|
||||
securityGroup: props.eksSecGrp,
|
||||
fileSystemPolicy: myFileSystemPolicy,
|
||||
});
|
||||
|
||||
new helm.HelmChart(this, 'Bpphelm', {
|
||||
cluster: eksCluster,
|
||||
chart: 'beckn-onix-bpp',
|
||||
release: releaseName,
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
global: {
|
||||
isSandbox: isSandbox,
|
||||
externalDomain: externalDomain,
|
||||
registry_url: registryUrl,
|
||||
bpp: {
|
||||
privateKey: bppPrivateKey,
|
||||
publicKey: bppPublicKey,
|
||||
},
|
||||
efs: {
|
||||
fileSystemId: efsBppFileSystemId.fileSystemId,
|
||||
},
|
||||
ingress: {
|
||||
tls: {
|
||||
certificateArn: certArn,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
new cdk.CfnOutput(this, String("EksFileSystemId"), {
|
||||
value: efsBppFileSystemId.fileSystemId,
|
||||
});
|
||||
}
|
||||
}
|
||||
54
aws-cdk/beckn-cdk/lib/helm-gateway.ts
Normal file
54
aws-cdk/beckn-cdk/lib/helm-gateway.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as helm from 'aws-cdk-lib/aws-eks';
|
||||
import { Stack, StackProps } from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
interface HelmGAtewayStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
eksCluster: eks.Cluster;
|
||||
rdsHost: string;
|
||||
rdsPassword: string;
|
||||
}
|
||||
|
||||
export class HelmGatewayStack extends Stack {
|
||||
constructor(scope: Construct, id: string, props: HelmGAtewayStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const eksCluster = props.eksCluster;
|
||||
const externalDomain = props.config.GATEWAY_EXTERNAL_DOMAIN;
|
||||
const certArn = props.config.CERT_ARN;
|
||||
const registryUrl = props.config.REGISTRY_URL;
|
||||
|
||||
const releaseName = props.config.GATEWAY_RELEASE_NAME;
|
||||
const repository = props.config.REPOSITORY;
|
||||
|
||||
const rdsHost = props.rdsHost;
|
||||
const rdsPassword = props.rdsPassword;
|
||||
|
||||
new helm.HelmChart(this, "gatewayhelm", {
|
||||
cluster: eksCluster,
|
||||
chart: "beckn-onix-gateway",
|
||||
release: releaseName,
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
externalDomain: externalDomain,
|
||||
registry_url: registryUrl,
|
||||
database: {
|
||||
host: rdsHost,
|
||||
password: rdsPassword,
|
||||
},
|
||||
ingress: {
|
||||
tls:
|
||||
{
|
||||
certificateArn: certArn,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
50
aws-cdk/beckn-cdk/lib/helm-registry.ts
Normal file
50
aws-cdk/beckn-cdk/lib/helm-registry.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as eks from 'aws-cdk-lib/aws-eks';
|
||||
import * as helm from 'aws-cdk-lib/aws-eks';
|
||||
import { Stack, StackProps } from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
interface HelmRegistryStackProps extends StackProps {
|
||||
config: ConfigProps;
|
||||
eksCluster: eks.Cluster;
|
||||
rdsHost: string;
|
||||
rdsPassword: string;
|
||||
}
|
||||
|
||||
export class HelmRegistryStack extends Stack {
|
||||
constructor(scope: Construct, id: string, props: HelmRegistryStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const eksCluster = props.eksCluster;
|
||||
const externalDomain = props.config.REGISTRY_EXTERNAL_DOMAIN;
|
||||
const certArn = props.config.CERT_ARN;
|
||||
const releaseName = props.config.REGISTRY_RELEASE_NAME;
|
||||
const repository = props.config.REPOSITORY;
|
||||
|
||||
const rdsHost = props.rdsHost;
|
||||
const rdsPassword = props.rdsPassword;
|
||||
|
||||
new helm.HelmChart(this, "registryhelm", {
|
||||
cluster: eksCluster,
|
||||
chart: "beckn-onix-registry",
|
||||
release: releaseName,
|
||||
wait: false,
|
||||
repository: repository,
|
||||
values: {
|
||||
externalDomain: externalDomain,
|
||||
database: {
|
||||
host: rdsHost,
|
||||
password: rdsPassword
|
||||
},
|
||||
ingress: {
|
||||
tls:
|
||||
{
|
||||
certificateArn: certArn,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
66
aws-cdk/beckn-cdk/lib/rabbitmq-stack.ts
Normal file
66
aws-cdk/beckn-cdk/lib/rabbitmq-stack.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as amazonmq from 'aws-cdk-lib/aws-amazonmq';
|
||||
import * as dotenv from 'dotenv';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
// Load environment variables from .env file
|
||||
dotenv.config();
|
||||
|
||||
interface RabbitMqStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class RabbitMqStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props: RabbitMqStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
// Prompt for the RabbitMQ admin password using environment variable
|
||||
const rabbitMqPassword = new cdk.CfnParameter(this, 'RabbitMqPassword', {
|
||||
type: 'String',
|
||||
description: 'The password for the RabbitMQ broker admin user',
|
||||
noEcho: true, // Ensure the password is hidden from the console
|
||||
default: props.config.RABBITMQ_PASSWORD || '', // Use the password from .env or set a fallback
|
||||
});
|
||||
|
||||
// Security group for RabbitMQ
|
||||
const rabbitMqSecurityGroup = new ec2.SecurityGroup(this, 'RabbitMqSecurityGroup', {
|
||||
vpc: props.vpc,
|
||||
description: 'Security group for RabbitMQ broker',
|
||||
allowAllOutbound: true,
|
||||
});
|
||||
|
||||
rabbitMqSecurityGroup.addIngressRule(ec2.Peer.ipv4(props.vpc.vpcCidrBlock), ec2.Port.tcp(5672), 'Allow RabbitMQ traffic on port 5672');
|
||||
rabbitMqSecurityGroup.addIngressRule(ec2.Peer.ipv4(props.vpc.vpcCidrBlock), ec2.Port.tcp(15672), 'Allow RabbitMQ management traffic');
|
||||
|
||||
// Select a single private subnet for the RabbitMQ Broker
|
||||
const privateSubnets = props.vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }).subnets;
|
||||
|
||||
// Ensure there's at least one subnet, and use the first one
|
||||
if (privateSubnets.length === 0) {
|
||||
throw new Error('No private subnets found in the VPC');
|
||||
}
|
||||
|
||||
const selectedSubnet = privateSubnets[0]; // Use the first subnet
|
||||
|
||||
// RabbitMQ Broker
|
||||
new amazonmq.CfnBroker(this, 'RabbitMqBroker', {
|
||||
brokerName: 'MyRabbitMqBroker',
|
||||
engineType: 'RABBITMQ',
|
||||
engineVersion: '3.10.25',
|
||||
deploymentMode: 'SINGLE_INSTANCE',
|
||||
publiclyAccessible: false,
|
||||
hostInstanceType: 'mq.m5.large', // Adjust the instance type as needed
|
||||
subnetIds: [selectedSubnet.subnetId], // Pass a single subnet
|
||||
securityGroups: [rabbitMqSecurityGroup.securityGroupId],
|
||||
users: [
|
||||
{
|
||||
username: 'becknadmin', // Fixed username
|
||||
password: rabbitMqPassword.valueAsString, // Password entered by the user or set from the .env file
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
50
aws-cdk/beckn-cdk/lib/rds-stack-dummy.ts
Normal file
50
aws-cdk/beckn-cdk/lib/rds-stack-dummy.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as rds from 'aws-cdk-lib/aws-rds';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
import cluster from 'cluster';
|
||||
|
||||
export interface RdsStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class RdsStack extends cdk.Stack {
|
||||
public readonly rdsSecret: string;
|
||||
public readonly rdsHost: string;
|
||||
|
||||
constructor(scope: Construct, id: string, props: RdsStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
// Security group for RDS
|
||||
const dbSecurityGroup = new ec2.SecurityGroup(this, 'DatabaseSecurityGroup', {
|
||||
vpc: props.vpc,
|
||||
description: 'Security group for Aurora PostgreSQL database',
|
||||
allowAllOutbound: true,
|
||||
});
|
||||
|
||||
dbSecurityGroup.addIngressRule(ec2.Peer.ipv4(props.vpc.vpcCidrBlock), ec2.Port.tcp(5432), 'Allow Postgres access');
|
||||
|
||||
// Create Aurora PostgreSQL database cluster
|
||||
const cluster = new rds.DatabaseCluster(this, 'AuroraCluster', {
|
||||
engine: rds.DatabaseClusterEngine.auroraPostgres({
|
||||
version: rds.AuroraPostgresEngineVersion.VER_13_15,
|
||||
}),
|
||||
instances: 2,
|
||||
instanceProps: {
|
||||
vpc: props.vpc,
|
||||
vpcSubnets: {
|
||||
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
||||
},
|
||||
securityGroups: [dbSecurityGroup],
|
||||
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MEDIUM),
|
||||
},
|
||||
credentials: rds.Credentials.fromGeneratedSecret('dbadmin'),
|
||||
defaultDatabaseName: 'MyDatabase',
|
||||
removalPolicy: cdk.RemovalPolicy.DESTROY, // Destroy cluster when stack is deleted (useful for development)
|
||||
});
|
||||
|
||||
this.rdsHost = cluster.clusterEndpoint.hostname;
|
||||
}
|
||||
}
|
||||
84
aws-cdk/beckn-cdk/lib/rds-stack.ts
Normal file
84
aws-cdk/beckn-cdk/lib/rds-stack.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as rds from 'aws-cdk-lib/aws-rds';
|
||||
import { Construct } from 'constructs';
|
||||
import { ConfigProps } from './config';
|
||||
import cluster from 'cluster';
|
||||
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
|
||||
|
||||
export interface RdsStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
envC: string;
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class RdsStack extends cdk.Stack {
|
||||
public readonly rdsSecret: string;
|
||||
public readonly rdsHost: string;
|
||||
public readonly rdsPassword: string;
|
||||
|
||||
constructor(scope: Construct, id: string, props: RdsStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const vpc = props.vpc;
|
||||
const dbName = props.envC;
|
||||
const rdsUser = props.config.RDS_USER; // take input from user / make it
|
||||
const rdsPassword = this.createPassword();
|
||||
const rdsSecGrpIngress = props.config.CIDR;
|
||||
|
||||
const securityGroupRDS = new ec2.SecurityGroup(this, 'RdsSecurityGroup', {
|
||||
vpc: vpc,
|
||||
allowAllOutbound: true,
|
||||
description: 'Security group for Aurora PostgreSQL database',
|
||||
});
|
||||
|
||||
securityGroupRDS.addIngressRule(
|
||||
ec2.Peer.ipv4(rdsSecGrpIngress),
|
||||
ec2.Port.tcp(5432),
|
||||
"Allow Postgress Access"
|
||||
);
|
||||
|
||||
const creds = new Secret(this, "rdsSecret", {
|
||||
secretObjectValue: {
|
||||
username: cdk.SecretValue.unsafePlainText(rdsUser.toString()),
|
||||
password: cdk.SecretValue.unsafePlainText(rdsPassword.toString()),
|
||||
},
|
||||
});
|
||||
|
||||
const cluster = new rds.DatabaseCluster(this, 'AuroraCluster', {
|
||||
engine: rds.DatabaseClusterEngine.auroraPostgres({
|
||||
version: rds.AuroraPostgresEngineVersion.VER_14_6,
|
||||
}),
|
||||
credentials: rds.Credentials.fromSecret(creds),
|
||||
instances: 1,
|
||||
instanceProps: {
|
||||
vpc: props.vpc,
|
||||
vpcSubnets: {
|
||||
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
||||
},
|
||||
securityGroups: [securityGroupRDS],
|
||||
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MEDIUM),
|
||||
},
|
||||
defaultDatabaseName: dbName,
|
||||
});
|
||||
|
||||
this.rdsSecret = creds.secretArn;
|
||||
this.rdsHost = cluster.clusterEndpoint.hostname;
|
||||
this.rdsPassword = rdsPassword;
|
||||
|
||||
new cdk.CfnOutput(this, 'RDSPasswordOutput', {
|
||||
value: rdsPassword,
|
||||
exportName: `RDSPassword-${dbName}`,
|
||||
})
|
||||
}
|
||||
|
||||
//generate password function
|
||||
private createPassword(length: number = 12): string {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,-.:;<=>?[]^_`{|}~';
|
||||
let password = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
password += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return password;
|
||||
}
|
||||
}
|
||||
38
aws-cdk/beckn-cdk/lib/redis-stack.ts
Normal file
38
aws-cdk/beckn-cdk/lib/redis-stack.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as elasticache from 'aws-cdk-lib/aws-elasticache';
|
||||
|
||||
interface RedisStackProps extends cdk.StackProps {
|
||||
vpc: ec2.Vpc;
|
||||
}
|
||||
|
||||
export class RedisStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props: RedisStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
// Security group for ElastiCache
|
||||
const elasticacheSecurityGroup = new ec2.SecurityGroup(this, 'ElastiCacheSecurityGroup', {
|
||||
vpc: props.vpc,
|
||||
description: 'Security group for Redis',
|
||||
allowAllOutbound: true,
|
||||
});
|
||||
|
||||
elasticacheSecurityGroup.addIngressRule(ec2.Peer.ipv4(props.vpc.vpcCidrBlock), ec2.Port.tcp(6379), 'Allow Redis traffic');
|
||||
|
||||
// Redis subnet group
|
||||
const redisSubnetGroup = new elasticache.CfnSubnetGroup(this, 'RedisSubnetGroup', {
|
||||
description: 'Subnet group for Redis cluster',
|
||||
subnetIds: props.vpc.selectSubnets({ subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }).subnetIds,
|
||||
});
|
||||
|
||||
// Redis Cluster
|
||||
new elasticache.CfnCacheCluster(this, 'RedisCluster', {
|
||||
cacheNodeType: 'cache.t3.medium', // Adjust the node type based on your needs
|
||||
engine: 'redis',
|
||||
numCacheNodes: 1,
|
||||
vpcSecurityGroupIds: [elasticacheSecurityGroup.securityGroupId],
|
||||
cacheSubnetGroupName: redisSubnetGroup.ref,
|
||||
});
|
||||
}
|
||||
}
|
||||
76
aws-cdk/beckn-cdk/lib/vpc-stack.ts
Normal file
76
aws-cdk/beckn-cdk/lib/vpc-stack.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2';
|
||||
import * as elb from 'aws-cdk-lib/aws-elasticloadbalancingv2';
|
||||
import { ConfigProps } from './config';
|
||||
|
||||
export interface VpcStackProps extends cdk.StackProps {
|
||||
config: ConfigProps;
|
||||
}
|
||||
|
||||
export class VpcStack extends cdk.Stack {
|
||||
public readonly vpc: ec2.Vpc;
|
||||
// public readonly alb: elb.ApplicationLoadBalancer;
|
||||
|
||||
constructor(scope: Construct, id: string, props: VpcStackProps) {
|
||||
super(scope, id, props);
|
||||
|
||||
const config = props.config;
|
||||
|
||||
// Create a new VPC
|
||||
this.vpc = new ec2.Vpc(this, 'beckn-onix-vpc', {
|
||||
maxAzs: config.MAX_AZS, // Maximum number of availability zones
|
||||
cidr: config.CIDR,
|
||||
natGateways: 1, // Single NAT Gateway in the public subnet
|
||||
subnetConfiguration: [
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'Public',
|
||||
subnetType: ec2.SubnetType.PUBLIC,
|
||||
},
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'AppLayer',
|
||||
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS, // Use the newer "PRIVATE_WITH_EGRESS" instead of PRIVATE_WITH_NAT
|
||||
},
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'DatabaseLayer',
|
||||
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Output the VPC CIDR block for other stacks to reference
|
||||
new cdk.CfnOutput(this, 'VpcCidrBlock', {
|
||||
value: this.vpc.vpcCidrBlock,
|
||||
exportName: 'VpcCidrBlock-env', // Export name to reference in other stacks
|
||||
});
|
||||
|
||||
// Output the VPC ID for other stacks
|
||||
new cdk.CfnOutput(this, 'VpcId', {
|
||||
value: this.vpc.vpcId,
|
||||
exportName: 'VpcId', // Export name to reference in other stacks
|
||||
});
|
||||
|
||||
// Output the Public Subnet IDs
|
||||
new cdk.CfnOutput(this, 'PublicSubnetIds', {
|
||||
value: this.vpc.publicSubnets.map(subnet => subnet.subnetId).join(','),
|
||||
exportName: 'PublicSubnetIds', // Export name to reference in other stacks
|
||||
});
|
||||
|
||||
// Output the App Layer Subnet IDs (for application instances or services)
|
||||
new cdk.CfnOutput(this, 'AppLayerSubnetIds', {
|
||||
value: this.vpc.selectSubnets({ subnetGroupName: 'AppLayer' }).subnetIds.join(','),
|
||||
exportName: 'AppLayerSubnetIds', // Export name to reference in other stacks
|
||||
});
|
||||
|
||||
// Output the Database Layer Subnet IDs (for database instances)
|
||||
new cdk.CfnOutput(this, 'DatabaseSubnetIds', {
|
||||
value: this.vpc.selectSubnets({ subnetGroupName: 'DatabaseLayer' }).subnetIds.join(','),
|
||||
exportName: 'DatabaseSubnetIds', // Export name to reference in other stacks
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4587
aws-cdk/beckn-cdk/package-lock.json
generated
Normal file
4587
aws-cdk/beckn-cdk/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
aws-cdk/beckn-cdk/package.json
Normal file
29
aws-cdk/beckn-cdk/package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "beckn-cdk",
|
||||
"version": "0.1.0",
|
||||
"bin": {
|
||||
"beckn-cdk": "bin/beckn-cdk.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"watch": "tsc -w",
|
||||
"test": "jest",
|
||||
"cdk": "cdk"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^22.5.4",
|
||||
"aws-cdk": "2.158.0",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "~5.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-cdk/lambda-layer-kubectl-v30": "^2.0.1",
|
||||
"aws-cdk-lib": "2.158.0",
|
||||
"constructs": "^10.0.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"source-map-support": "^0.5.21"
|
||||
}
|
||||
}
|
||||
17
aws-cdk/beckn-cdk/test/beckn-cdk.test.ts
Normal file
17
aws-cdk/beckn-cdk/test/beckn-cdk.test.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// import * as cdk from 'aws-cdk-lib';
|
||||
// import { Template } from 'aws-cdk-lib/assertions';
|
||||
// import * as BecknCdkNew from '../lib/beckn-cdk-stack';
|
||||
|
||||
// example test. To run these tests, uncomment this file along with the
|
||||
// example resource in lib/beckn-cdk-stack.ts
|
||||
test('SQS Queue Created', () => {
|
||||
// const app = new cdk.App();
|
||||
// // WHEN
|
||||
// const stack = new BecknCdkNew.BecknCdkNewStack(app, 'MyTestStack');
|
||||
// // THEN
|
||||
// const template = Template.fromStack(stack);
|
||||
|
||||
// template.hasResourceProperties('AWS::SQS::Queue', {
|
||||
// VisibilityTimeout: 300
|
||||
// });
|
||||
});
|
||||
31
aws-cdk/beckn-cdk/tsconfig.json
Normal file
31
aws-cdk/beckn-cdk/tsconfig.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
],
|
||||
"declaration": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"experimentalDecorators": true,
|
||||
"strictPropertyInitialization": false,
|
||||
"typeRoots": [
|
||||
"./node_modules/@types"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"cdk.out"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user