move cdk folder to scripts/cdk
This commit is contained in:
parent
57c7f67987
commit
ce19ee5bcd
20 changed files with 0 additions and 5445 deletions
|
|
@ -1,3 +0,0 @@
|
|||
LANGFLOW_AUTO_LOGIN=false
|
||||
LANGFLOW_SUPERUSER=langflow
|
||||
LANGFLOW_SUPERUSER_PASSWORD=654321
|
||||
9
deploy/scripts/cdk/.gitignore
vendored
9
deploy/scripts/cdk/.gitignore
vendored
|
|
@ -1,9 +0,0 @@
|
|||
*.js
|
||||
!jest.config.js
|
||||
*.d.ts
|
||||
node_modules
|
||||
|
||||
# CDK asset staging directory
|
||||
.cdk.staging
|
||||
cdk.out
|
||||
!/lib
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
*.ts
|
||||
!*.d.ts
|
||||
|
||||
# CDK asset staging directory
|
||||
.cdk.staging
|
||||
cdk.out
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
# 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
|
||||
* `cdk deploy` deploy this stack to your default AWS account/region
|
||||
* `cdk diff` compare deployed stack with current state
|
||||
* `cdk synth` emits the synthesized CloudFormation template
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
import 'source-map-support/register';
|
||||
import * as cdk from 'aws-cdk-lib';
|
||||
import { LangflowAppStack } from '../lib/cdk-stack';
|
||||
|
||||
const app = new cdk.App();
|
||||
new LangflowAppStack(app, 'LangflowAppStack', {
|
||||
/* If you don't specify 'env', this stack will be environment-agnostic.
|
||||
* Account/Region-dependent features and context lookups will not work,
|
||||
* but a single synthesized template can be deployed anywhere. */
|
||||
|
||||
/* Uncomment the next line to specialize this stack for the AWS Account
|
||||
* and Region that are implied by the current CLI configuration. */
|
||||
// env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },
|
||||
|
||||
/* Uncomment the next line if you know exactly what Account and Region you
|
||||
* want to deploy the stack to. */
|
||||
// env: { account: '123456789012', region: 'us-east-1' },
|
||||
|
||||
/* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
|
||||
});
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"app": "npx ts-node --prefer-ts-exts bin/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-iam:standardizedServicePrincipals": 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/core:includePrefixInUniqueNameGeneration": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
docker stop $(docker ps -aq)
|
||||
docker rm $(docker ps -aq)
|
||||
docker rmi -f $(docker images -aq)
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# aws cloudformation delete-stack --stack-name LangflowAppStack
|
||||
# aws ecr delete-repository --repository-name langflow-backend-repository --force
|
||||
# aws ecr delete-repository --repository-name langflow-frontend-repository --force
|
||||
# aws ecr describe-repositories --output json | jq -re ".repositories[].repositoryName"
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
module.exports = {
|
||||
testEnvironment: 'node',
|
||||
roots: ['<rootDir>/test'],
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.tsx?$': 'ts-jest'
|
||||
}
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
import * as cdk from 'aws-cdk-lib';
|
||||
import { Construct } from 'constructs';
|
||||
import * as ecs from 'aws-cdk-lib/aws-ecs'
|
||||
|
||||
import { Network, EcrRepository, FrontEndCluster, BackEndCluster, Rds, EcsIAM } from './construct';
|
||||
// import * as sqs from 'aws-cdk-lib/aws-sqs';
|
||||
|
||||
export class LangflowAppStack extends cdk.Stack {
|
||||
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
||||
super(scope, id, props);
|
||||
// Arch
|
||||
const arch = ecs.CpuArchitecture.X86_64
|
||||
|
||||
// VPC
|
||||
const { vpc, cluster, alb, targetGroup, cloudmapNamespace, ecsFrontSG, ecsBackSG, dbSG, albSG, backendLogGroup, frontendLogGroup} = new Network(this, 'Network')
|
||||
|
||||
// ECR
|
||||
const { ecrFrontEndRepository,ecrBackEndRepository} = new EcrRepository(this, 'Ecr', {
|
||||
cloudmapNamespace:cloudmapNamespace,
|
||||
arch:arch
|
||||
})
|
||||
|
||||
// RDS
|
||||
// VPCとSGのリソース情報をPropsとして引き渡す
|
||||
const { rdsCluster } = new Rds(this, 'Rds', { vpc, dbSG })
|
||||
|
||||
// IAM
|
||||
const { frontendTaskRole, frontendTaskExecutionRole, backendTaskRole, backendTaskExecutionRole } = new EcsIAM(this, 'EcsIAM',{
|
||||
rdsCluster:rdsCluster
|
||||
})
|
||||
|
||||
const backendService = new BackEndCluster(this, 'backend', {
|
||||
cluster:cluster,
|
||||
ecsBackSG:ecsBackSG,
|
||||
ecrBackEndRepository:ecrBackEndRepository,
|
||||
backendTaskRole:backendTaskRole,
|
||||
backendTaskExecutionRole:backendTaskExecutionRole,
|
||||
backendLogGroup:backendLogGroup,
|
||||
cloudmapNamespace:cloudmapNamespace,
|
||||
rdsCluster:rdsCluster,
|
||||
alb:alb,
|
||||
arch:arch
|
||||
})
|
||||
backendService.node.addDependency(rdsCluster);
|
||||
|
||||
const frontendService = new FrontEndCluster(this, 'frontend',{
|
||||
cluster:cluster,
|
||||
ecsFrontSG:ecsFrontSG,
|
||||
ecrFrontEndRepository:ecrFrontEndRepository,
|
||||
targetGroup: targetGroup,
|
||||
backendServiceName: backendService.backendServiceName,
|
||||
frontendTaskRole: frontendTaskRole,
|
||||
frontendTaskExecutionRole: frontendTaskExecutionRole,
|
||||
frontendLogGroup: frontendLogGroup,
|
||||
cloudmapNamespace: cloudmapNamespace,
|
||||
arch:arch
|
||||
})
|
||||
frontendService.node.addDependency(backendService);
|
||||
|
||||
|
||||
// S3+CloudFront
|
||||
// new Web(this,'Cloudfront-S3')
|
||||
}
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
import { Duration } from 'aws-cdk-lib'
|
||||
import { Construct } from 'constructs';
|
||||
import {
|
||||
aws_ec2 as ec2,
|
||||
aws_ecs as ecs,
|
||||
aws_ecr as ecr,
|
||||
aws_rds as rds,
|
||||
aws_servicediscovery as servicediscovery,
|
||||
aws_iam as iam,
|
||||
aws_logs as logs,
|
||||
aws_elasticloadbalancingv2 as elb,
|
||||
} from 'aws-cdk-lib';
|
||||
import * as dotenv from 'dotenv';
|
||||
const path = require('path');
|
||||
dotenv.config({path: path.join(__dirname, "../../.env")});
|
||||
|
||||
console.log(process.env.LANGFLOW_AUTO_LOGIN);
|
||||
console.log(process.env.LANGFLOW_SUPERUSER);
|
||||
console.log(process.env.LANGFLOW_SUPERUSER_PASSWORD);
|
||||
|
||||
interface BackEndProps {
|
||||
cluster: ecs.Cluster
|
||||
ecsBackSG:ec2.SecurityGroup
|
||||
ecrBackEndRepository:ecr.Repository
|
||||
backendTaskRole: iam.Role;
|
||||
backendTaskExecutionRole: iam.Role;
|
||||
backendLogGroup: logs.LogGroup;
|
||||
cloudmapNamespace: servicediscovery.PrivateDnsNamespace;
|
||||
rdsCluster:rds.DatabaseCluster
|
||||
alb:elb.IApplicationLoadBalancer
|
||||
arch:ecs.CpuArchitecture
|
||||
}
|
||||
|
||||
export class BackEndCluster extends Construct {
|
||||
readonly backendServiceName: string
|
||||
|
||||
constructor(scope: Construct, id: string, props:BackEndProps) {
|
||||
super(scope, id)
|
||||
const containerPort = 7860
|
||||
// Secrets ManagerからDB認証情報を取ってくる
|
||||
const secretsDB = props.rdsCluster.secret!;
|
||||
|
||||
// Create Backend Fargate Service
|
||||
const backendTaskDefinition = new ecs.FargateTaskDefinition(
|
||||
this,
|
||||
'BackEndTaskDef',
|
||||
{
|
||||
memoryLimitMiB: 3072,
|
||||
cpu: 1024,
|
||||
executionRole: props.backendTaskExecutionRole,
|
||||
runtimePlatform:{
|
||||
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
|
||||
cpuArchitecture: props.arch,
|
||||
},
|
||||
taskRole: props.backendTaskRole,
|
||||
}
|
||||
);
|
||||
backendTaskDefinition.addContainer('backendContainer', {
|
||||
image: ecs.ContainerImage.fromEcrRepository(props.ecrBackEndRepository, "latest"),
|
||||
containerName:'langflow-back-container',
|
||||
logging: ecs.LogDriver.awsLogs({
|
||||
streamPrefix: 'my-stream',
|
||||
logGroup: props.backendLogGroup,
|
||||
}),
|
||||
environment:{
|
||||
// user:pass@endpoint:port/dbname
|
||||
// "LANGFLOW_DATABASE_URL" : `mysql+pymysql://${username}:${password}@${host}:3306/${dbname}`,
|
||||
// "LANGFLOW_DATABASE_URL" : "sqlite:///./langflow.db",
|
||||
// "LANGFLOW_LANGCHAIN_CACHE" : "SQLiteCache",
|
||||
// "LANGFLOW_AUTO_LOGIN" : "false",
|
||||
// "LANGFLOW_SUPERUSER" : "admin",
|
||||
// "LANGFLOW_SUPERUSER_PASSWORD" : "1234567"
|
||||
"LANGFLOW_AUTO_LOGIN" : process.env.LANGFLOW_AUTO_LOGIN ?? 'false',
|
||||
"LANGFLOW_SUPERUSER" : process.env.LANGFLOW_SUPERUSER ?? "admin",
|
||||
"LANGFLOW_SUPERUSER_PASSWORD" : process.env.LANGFLOW_SUPERUSER_PASSWORD ?? "123456"
|
||||
},
|
||||
portMappings: [
|
||||
{
|
||||
containerPort: containerPort,
|
||||
protocol: ecs.Protocol.TCP,
|
||||
},
|
||||
],
|
||||
// Secretの設定
|
||||
secrets: {
|
||||
"dbname": ecs.Secret.fromSecretsManager(secretsDB, 'dbname'),
|
||||
"username": ecs.Secret.fromSecretsManager(secretsDB, 'username'),
|
||||
"host": ecs.Secret.fromSecretsManager(secretsDB, 'host'),
|
||||
"password": ecs.Secret.fromSecretsManager(secretsDB, 'password'),
|
||||
},
|
||||
});
|
||||
this.backendServiceName = 'backend'
|
||||
const backendService = new ecs.FargateService(this, 'BackEndService', {
|
||||
cluster: props.cluster,
|
||||
serviceName: this.backendServiceName,
|
||||
taskDefinition: backendTaskDefinition,
|
||||
enableExecuteCommand: true,
|
||||
securityGroups: [props.ecsBackSG],
|
||||
cloudMapOptions: {
|
||||
cloudMapNamespace: props.cloudmapNamespace,
|
||||
containerPort: containerPort,
|
||||
dnsRecordType: servicediscovery.DnsRecordType.A,
|
||||
dnsTtl: Duration.seconds(10),
|
||||
name: this.backendServiceName
|
||||
},
|
||||
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
import { Construct } from 'constructs';
|
||||
import * as ec2 from 'aws-cdk-lib/aws-ec2'
|
||||
import * as rds from "aws-cdk-lib/aws-rds";
|
||||
|
||||
interface RdsProps {
|
||||
vpc: ec2.Vpc
|
||||
dbSG:ec2.SecurityGroup
|
||||
}
|
||||
|
||||
export class Rds extends Construct{
|
||||
readonly rdsCluster: rds.DatabaseCluster
|
||||
|
||||
constructor(scope: Construct, id:string, props: RdsProps){
|
||||
super(scope, id);
|
||||
|
||||
const {vpc, dbSG} = props
|
||||
const instanceType = ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE4_GRAVITON, ec2.InstanceSize.MEDIUM)
|
||||
|
||||
// RDSのパスワードを自動生成してSecrets Managerに格納
|
||||
const rdsCredentials = rds.Credentials.fromGeneratedSecret('db_user',{
|
||||
secretName: 'langflow-DbSecret',
|
||||
})
|
||||
|
||||
// DB クラスターのパラメータグループ作成
|
||||
const clusterParameterGroup = new rds.ParameterGroup(scope, 'ClusterParameterGroup',{
|
||||
engine: rds.DatabaseClusterEngine.auroraMysql({
|
||||
version: rds.AuroraMysqlEngineVersion.VER_3_02_0
|
||||
}),
|
||||
description: 'for-langflow',
|
||||
})
|
||||
clusterParameterGroup.bindToCluster({})
|
||||
|
||||
// DB インスタンスのパラメタグループ作成
|
||||
const instanceParameterGroup = new rds.ParameterGroup(scope, 'InstanceParameterGroup',{
|
||||
engine: rds.DatabaseClusterEngine.auroraMysql({
|
||||
version: rds.AuroraMysqlEngineVersion.VER_3_02_0,
|
||||
}),
|
||||
description: 'for-langflow',
|
||||
})
|
||||
instanceParameterGroup.bindToInstance({})
|
||||
|
||||
this.rdsCluster = new rds.DatabaseCluster(scope, 'LangflowDbCluster', {
|
||||
engine: rds.DatabaseClusterEngine.auroraMysql({
|
||||
version: rds.AuroraMysqlEngineVersion.VER_3_02_0,
|
||||
}),
|
||||
storageEncrypted: true,
|
||||
credentials: rdsCredentials,
|
||||
instanceIdentifierBase: 'langflow-instance',
|
||||
vpc:vpc,
|
||||
vpcSubnets:vpc.selectSubnets({
|
||||
subnetGroupName: 'langflow-Isolated',
|
||||
}),
|
||||
securityGroups:[dbSG],
|
||||
writer: rds.ClusterInstance.provisioned("WriterInstance", {
|
||||
instanceType: instanceType,
|
||||
enablePerformanceInsights: true,
|
||||
parameterGroup:instanceParameterGroup,
|
||||
}),
|
||||
// 2台目以降はreaders:で設定
|
||||
parameterGroup: clusterParameterGroup,
|
||||
defaultDatabaseName: 'langflow',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
import { RemovalPolicy } from 'aws-cdk-lib'
|
||||
import * as ecr from 'aws-cdk-lib/aws-ecr'
|
||||
import * as ecrdeploy from 'cdk-ecr-deployment'
|
||||
import * as ecs from 'aws-cdk-lib/aws-ecs'
|
||||
import * as servicediscovery from 'aws-cdk-lib/aws-servicediscovery'
|
||||
import { DockerImageAsset, Platform } from 'aws-cdk-lib/aws-ecr-assets'
|
||||
import * as path from "path";
|
||||
import { Construct } from 'constructs'
|
||||
|
||||
|
||||
interface ECRProps {
|
||||
cloudmapNamespace: servicediscovery.PrivateDnsNamespace;
|
||||
arch:ecs.CpuArchitecture;
|
||||
}
|
||||
|
||||
export class EcrRepository extends Construct {
|
||||
readonly ecrFrontEndRepository: ecr.Repository
|
||||
readonly ecrBackEndRepository: ecr.Repository
|
||||
|
||||
constructor(scope: Construct, id: string, props: ECRProps) {
|
||||
super(scope, id)
|
||||
|
||||
const imagePlatform = props.arch == ecs.CpuArchitecture.ARM64 ? Platform.LINUX_ARM64 : Platform.LINUX_AMD64
|
||||
const backendPath = path.join(__dirname, "../../../../../../", "langflow")
|
||||
const frontendPath = path.join(__dirname, "../../../../../src/", "frontend")
|
||||
const excludeDir = ['node_modules','.git', 'cdk.out']
|
||||
const LifecycleRule = {
|
||||
tagStatus: ecr.TagStatus.ANY,
|
||||
description: 'Delete more than 30 image',
|
||||
maxImageCount: 30,
|
||||
}
|
||||
|
||||
// リポジトリ作成
|
||||
this.ecrFrontEndRepository = new ecr.Repository(scope, 'LangflowFrontEndRepository', {
|
||||
repositoryName: 'langflow-frontend-repository',
|
||||
removalPolicy: RemovalPolicy.RETAIN,
|
||||
imageScanOnPush: true,
|
||||
})
|
||||
this.ecrBackEndRepository = new ecr.Repository(scope, 'LangflowBackEndRepository', {
|
||||
repositoryName: 'langflow-backend-repository',
|
||||
removalPolicy: RemovalPolicy.RETAIN,
|
||||
imageScanOnPush: true,
|
||||
})
|
||||
// LifecycleRule作成
|
||||
this.ecrFrontEndRepository.addLifecycleRule(LifecycleRule)
|
||||
this.ecrBackEndRepository.addLifecycleRule(LifecycleRule)
|
||||
|
||||
// Create Docker Image Asset
|
||||
const dockerFrontEndImageAsset = new DockerImageAsset(this, "DockerFrontEndImageAsset", {
|
||||
directory: frontendPath,
|
||||
buildArgs:{
|
||||
"BACKEND_URL":`http://backend.${props.cloudmapNamespace.namespaceName}:7860`
|
||||
},
|
||||
exclude: excludeDir,
|
||||
platform: imagePlatform,
|
||||
});
|
||||
const dockerBackEndImageAsset = new DockerImageAsset(this, "DockerBackEndImageAsset", {
|
||||
directory: backendPath,
|
||||
exclude: excludeDir,
|
||||
platform: imagePlatform,
|
||||
});
|
||||
|
||||
// Deploy Docker Image to ECR Repository
|
||||
new ecrdeploy.ECRDeployment(this, "DeployFrontEndImage", {
|
||||
src: new ecrdeploy.DockerImageName(dockerFrontEndImageAsset.imageUri),
|
||||
dest: new ecrdeploy.DockerImageName(this.ecrFrontEndRepository.repositoryUri)
|
||||
});
|
||||
|
||||
// Deploy Docker Image to ECR Repository
|
||||
new ecrdeploy.ECRDeployment(this, "DeployBackEndImage", {
|
||||
src: new ecrdeploy.DockerImageName(dockerBackEndImageAsset.imageUri),
|
||||
dest: new ecrdeploy.DockerImageName(this.ecrBackEndRepository.repositoryUri)
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
import { Duration } from 'aws-cdk-lib'
|
||||
import { Construct } from 'constructs'
|
||||
import {
|
||||
aws_ec2 as ec2,
|
||||
aws_ecs as ecs,
|
||||
aws_ecr as ecr,
|
||||
aws_servicediscovery as servicediscovery,
|
||||
aws_iam as iam,
|
||||
aws_logs as logs,
|
||||
aws_elasticloadbalancingv2 as elb,
|
||||
} from 'aws-cdk-lib';
|
||||
import { CpuArchitecture } from 'aws-cdk-lib/aws-ecs';
|
||||
|
||||
interface FrontEndProps {
|
||||
cluster:ecs.Cluster
|
||||
ecsFrontSG:ec2.SecurityGroup
|
||||
ecrFrontEndRepository:ecr.Repository
|
||||
targetGroup: elb.ApplicationTargetGroup;
|
||||
backendServiceName: string;
|
||||
frontendTaskRole: iam.Role;
|
||||
frontendTaskExecutionRole: iam.Role;
|
||||
frontendLogGroup: logs.LogGroup;
|
||||
cloudmapNamespace: servicediscovery.PrivateDnsNamespace;
|
||||
arch:ecs.CpuArchitecture;
|
||||
}
|
||||
|
||||
export class FrontEndCluster extends Construct {
|
||||
constructor(scope: Construct, id: string, props:FrontEndProps) {
|
||||
super(scope, id)
|
||||
|
||||
const containerPort = 3000
|
||||
const frontendTaskDefinition = new ecs.FargateTaskDefinition(
|
||||
this,
|
||||
'FrontendTaskDef',
|
||||
{
|
||||
memoryLimitMiB: 3072,
|
||||
cpu: 1024,
|
||||
executionRole: props.frontendTaskExecutionRole,
|
||||
runtimePlatform:{
|
||||
operatingSystemFamily: ecs.OperatingSystemFamily.LINUX,
|
||||
cpuArchitecture: props.arch,
|
||||
},
|
||||
taskRole: props.frontendTaskRole,
|
||||
}
|
||||
);
|
||||
const frontendServiceName = 'frontend'
|
||||
frontendTaskDefinition.addContainer('frontendContainer', {
|
||||
image: ecs.ContainerImage.fromEcrRepository(props.ecrFrontEndRepository, "latest"),
|
||||
containerName:'langflow-front-container',
|
||||
environment: {
|
||||
BACKEND_SERVICE_NAME: props.backendServiceName,
|
||||
BACKEND_URL: `http://${props.backendServiceName}.${props.cloudmapNamespace.namespaceName}:7860/`,
|
||||
VITE_PROXY_TARGET: `http://${props.backendServiceName}.${props.cloudmapNamespace.namespaceName}:7860/`,
|
||||
},
|
||||
logging: ecs.LogDriver.awsLogs({
|
||||
streamPrefix: 'my-stream',
|
||||
logGroup: props.frontendLogGroup,
|
||||
}),
|
||||
portMappings: [
|
||||
{
|
||||
name:frontendServiceName,
|
||||
containerPort: containerPort,
|
||||
protocol: ecs.Protocol.TCP,
|
||||
appProtocol:ecs.AppProtocol.http,
|
||||
},
|
||||
],
|
||||
});
|
||||
const frontendService = new ecs.FargateService(
|
||||
this,
|
||||
'FrontendService',
|
||||
{
|
||||
serviceName: frontendServiceName,
|
||||
cluster: props.cluster,
|
||||
desiredCount: 1,
|
||||
assignPublicIp: false,
|
||||
taskDefinition: frontendTaskDefinition,
|
||||
enableExecuteCommand: true,
|
||||
securityGroups: [props.ecsFrontSG],
|
||||
cloudMapOptions: {
|
||||
cloudMapNamespace: props.cloudmapNamespace,
|
||||
containerPort: containerPort,
|
||||
dnsRecordType: servicediscovery.DnsRecordType.A,
|
||||
dnsTtl: Duration.seconds(10),
|
||||
name: frontendServiceName
|
||||
},
|
||||
healthCheckGracePeriod: Duration.seconds(1000),
|
||||
}
|
||||
);
|
||||
|
||||
props.targetGroup.addTarget(frontendService);
|
||||
|
||||
// // Create ALB and ECS Fargate Service
|
||||
// const frontService = new ecs_patterns.ApplicationLoadBalancedFargateService(
|
||||
// this,
|
||||
// "FrontEndService",
|
||||
// {
|
||||
// cluster: cluster,
|
||||
// serviceName: 'langflow-frontend-service',
|
||||
// cpu: 256,
|
||||
// memoryLimitMiB: 512,
|
||||
// listenerPort: 80,
|
||||
// assignPublicIp: true, // Public facing - ALB
|
||||
// taskSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
||||
// securityGroups:[ecsFrontSG],
|
||||
// taskImageOptions: {
|
||||
// family: 'langflow-taskdef',
|
||||
// containerName: 'langflow-front-container',
|
||||
// image: ecs.ContainerImage.fromEcrRepository(ecrFrontEndRepository, "latest"),
|
||||
// containerPort: 3000, // L2なので、TargetGroupのportが3000で設定されるはず
|
||||
// },
|
||||
// loadBalancer:alb,
|
||||
// openListener:false,
|
||||
// }
|
||||
// );
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
import { RemovalPolicy, Duration } from 'aws-cdk-lib'
|
||||
import { Construct } from 'constructs'
|
||||
import {
|
||||
aws_rds as rds,
|
||||
aws_iam as iam,
|
||||
} from 'aws-cdk-lib';
|
||||
|
||||
interface IAMProps {
|
||||
rdsCluster:rds.DatabaseCluster
|
||||
}
|
||||
|
||||
export class EcsIAM extends Construct {
|
||||
readonly frontendTaskRole: iam.Role;
|
||||
readonly frontendTaskExecutionRole: iam.Role;
|
||||
readonly backendTaskRole: iam.Role;
|
||||
readonly backendTaskExecutionRole: iam.Role;
|
||||
|
||||
constructor(scope: Construct, id: string, props:IAMProps) {
|
||||
super(scope, id)
|
||||
|
||||
// Policy Statements
|
||||
// ECS Policy State
|
||||
const ECSExecPolicyStatement = new iam.PolicyStatement({
|
||||
sid: 'allowECSExec',
|
||||
resources: ['*'],
|
||||
actions: [
|
||||
'ecr:GetAuthorizationToken',
|
||||
'ecr:BatchCheckLayerAvailability',
|
||||
'ecr:GetDownloadUrlForLayer',
|
||||
'ecr:BatchGetImage',
|
||||
],
|
||||
});
|
||||
// Bedrock Policy State
|
||||
const BedrockPolicyStatement = new iam.PolicyStatement({
|
||||
sid: 'allowBedrockAccess',
|
||||
resources: ['*'],
|
||||
actions: [
|
||||
'bedrock:*',
|
||||
],
|
||||
});
|
||||
// Kendra Policy State
|
||||
const KendraPolicyStatement = new iam.PolicyStatement({
|
||||
sid: 'allowKendraAccess',
|
||||
resources: ['*'],
|
||||
actions: [
|
||||
'kendra:*'
|
||||
],
|
||||
});
|
||||
// Create Rag Policy
|
||||
const RagAccessPolicy = new iam.Policy(this, 'RAGFullAccess', {
|
||||
statements: [KendraPolicyStatement,BedrockPolicyStatement],
|
||||
})
|
||||
// Secrets ManagerからDB認証情報を取ってくるためのPolicy
|
||||
const SecretsManagerPolicy = new iam.Policy(this, 'SMGetPolicy', {
|
||||
statements: [new iam.PolicyStatement({
|
||||
actions: ['secretsmanager:GetSecretValue'],
|
||||
resources: [props.rdsCluster.secret!.secretArn],
|
||||
})],
|
||||
})
|
||||
|
||||
// FrontEnd Task Role
|
||||
this.frontendTaskRole = new iam.Role(this, 'FrontendTaskRole', {
|
||||
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
||||
});
|
||||
this.frontendTaskRole.addToPolicy(ECSExecPolicyStatement);
|
||||
|
||||
// BackEnd Task Role
|
||||
this.backendTaskRole = new iam.Role(this, 'BackendTaskRole', {
|
||||
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
||||
});
|
||||
// ECS Exec Policyの付与
|
||||
this.backendTaskRole.addToPolicy(ECSExecPolicyStatement);
|
||||
// KendraとBedrockのアクセス権付与
|
||||
this.backendTaskRole.attachInlinePolicy(RagAccessPolicy);
|
||||
|
||||
// FrontEnd Task ExecutionRole
|
||||
this.frontendTaskExecutionRole = new iam.Role(this, 'frontendTaskExecutionRole', {
|
||||
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
||||
managedPolicies: [
|
||||
{
|
||||
managedPolicyArn:
|
||||
'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// BackEnd Task ExecutionRole
|
||||
this.backendTaskExecutionRole = new iam.Role(this, 'backendTaskExecutionRole', {
|
||||
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
|
||||
managedPolicies: [
|
||||
{
|
||||
managedPolicyArn:
|
||||
'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.backendTaskExecutionRole.attachInlinePolicy(SecretsManagerPolicy);
|
||||
this.backendTaskExecutionRole.attachInlinePolicy(RagAccessPolicy);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
export * from './db';
|
||||
export * from './ecr';
|
||||
export * from './iam';
|
||||
export * from './frontend';
|
||||
export * from './backend';
|
||||
export * from './network';
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
import { RemovalPolicy, Duration } from 'aws-cdk-lib'
|
||||
import { Construct } from 'constructs'
|
||||
import {
|
||||
aws_ec2 as ec2,
|
||||
aws_ecs as ecs,
|
||||
aws_logs as logs,
|
||||
aws_servicediscovery as servicediscovery,
|
||||
aws_elasticloadbalancingv2 as elb,
|
||||
} from 'aws-cdk-lib';
|
||||
|
||||
export class Network extends Construct {
|
||||
readonly vpc: ec2.Vpc;
|
||||
readonly cluster: ecs.Cluster;
|
||||
readonly alb: elb.IApplicationLoadBalancer;
|
||||
readonly targetGroup: elb.ApplicationTargetGroup;
|
||||
readonly cloudmapNamespace: servicediscovery.PrivateDnsNamespace;
|
||||
readonly ecsFrontSG: ec2.SecurityGroup;
|
||||
readonly ecsBackSG: ec2.SecurityGroup;
|
||||
readonly dbSG: ec2.SecurityGroup;
|
||||
readonly albSG: ec2.SecurityGroup;
|
||||
readonly backendLogGroup: logs.LogGroup;
|
||||
readonly frontendLogGroup: logs.LogGroup;
|
||||
|
||||
constructor(scope: Construct, id: string) {
|
||||
super(scope, id)
|
||||
const alb_listen_port=80
|
||||
const front_service_port=3000
|
||||
const back_service_port=7860
|
||||
|
||||
// VPC等リソースの作成
|
||||
this.vpc = new ec2.Vpc(scope, 'VPC', {
|
||||
vpcName: 'langflow-vpc',
|
||||
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
|
||||
maxAzs: 3,
|
||||
subnetConfiguration: [
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'langflow-Isolated',
|
||||
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
||||
},
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'langflow-Public',
|
||||
subnetType: ec2.SubnetType.PUBLIC,
|
||||
},
|
||||
{
|
||||
cidrMask: 24,
|
||||
name: 'langflow-Private',
|
||||
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS
|
||||
},
|
||||
],
|
||||
natGateways: 1,
|
||||
})
|
||||
// Cluster
|
||||
this.cluster = new ecs.Cluster(this, 'EcsCluster', {
|
||||
clusterName: 'langflow-cluster',
|
||||
vpc: this.vpc,
|
||||
enableFargateCapacityProviders: true,
|
||||
});
|
||||
|
||||
// Private DNS
|
||||
this.cloudmapNamespace = new servicediscovery.PrivateDnsNamespace(
|
||||
this,
|
||||
'Namespace',
|
||||
{
|
||||
name: 'ecs-deploy.com',
|
||||
vpc: this.vpc,
|
||||
}
|
||||
);
|
||||
|
||||
// ALBに設定するセキュリティグループ
|
||||
this.albSG = new ec2.SecurityGroup(scope, 'ALBSecurityGroup', {
|
||||
securityGroupName: 'alb-sg',
|
||||
description: 'for alb',
|
||||
vpc: this.vpc,
|
||||
})
|
||||
this.albSG.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(alb_listen_port))
|
||||
|
||||
this.alb = new elb.ApplicationLoadBalancer(this,'alb',{
|
||||
internetFacing: true, //インターネットからのアクセスを許可するかどうか指定
|
||||
loadBalancerName: 'alb',
|
||||
securityGroup: this.albSG, //作成したセキュリティグループを割り当てる
|
||||
vpc:this.vpc,
|
||||
})
|
||||
|
||||
const listener = this.alb.addListener('Listener', { port: alb_listen_port });
|
||||
|
||||
this.targetGroup = listener.addTargets('targetGroup', {
|
||||
port: front_service_port,
|
||||
protocol: elb.ApplicationProtocol.HTTP,
|
||||
healthCheck: {
|
||||
enabled: true,
|
||||
path: '/health',
|
||||
healthyThresholdCount: 2,
|
||||
unhealthyThresholdCount: 4,
|
||||
interval: Duration.seconds(100),
|
||||
timeout: Duration.seconds(30),
|
||||
healthyHttpCodes: '200',
|
||||
},
|
||||
});
|
||||
|
||||
// ECS FrontEndに設定するセキュリティグループ
|
||||
this.ecsFrontSG = new ec2.SecurityGroup(scope, 'ECSFrontEndSecurityGroup', {
|
||||
securityGroupName: 'langflow-ecs-front-sg',
|
||||
description: 'for langflow-front-ecs',
|
||||
vpc: this.vpc,
|
||||
})
|
||||
this.ecsFrontSG.addIngressRule(this.albSG, ec2.Port.allTcp())
|
||||
|
||||
// ECS BackEndに設定するセキュリティグループ
|
||||
this.ecsBackSG = new ec2.SecurityGroup(scope, 'ECSBackEndSecurityGroup', {
|
||||
securityGroupName: 'langflow-ecs-back-sg',
|
||||
description: 'for langflow-back-ecs',
|
||||
vpc: this.vpc,
|
||||
})
|
||||
this.ecsBackSG.addIngressRule(this.ecsFrontSG, ec2.Port.tcp(back_service_port))
|
||||
|
||||
// RDSに設定するセキュリティグループ
|
||||
this.dbSG = new ec2.SecurityGroup(scope, 'DBSecurityGroup', {
|
||||
allowAllOutbound: true,
|
||||
securityGroupName: 'langflow-db',
|
||||
description: 'for langflow-db',
|
||||
vpc: this.vpc,
|
||||
})
|
||||
// AppRunnerSecurityGroupからのポート3306:mysql(5432:postgres)のインバウンドを許可
|
||||
this.dbSG.addIngressRule(this.ecsBackSG, ec2.Port.tcp(3306))
|
||||
|
||||
// Create CloudWatch Log Group
|
||||
this.backendLogGroup = new logs.LogGroup(this, 'backendLogGroup', {
|
||||
logGroupName: 'myapp-backend',
|
||||
removalPolicy: RemovalPolicy.DESTROY,
|
||||
});
|
||||
|
||||
this.frontendLogGroup = new logs.LogGroup(this, 'frontendLogGroup', {
|
||||
logGroupName: 'myapp-frontend',
|
||||
removalPolicy: RemovalPolicy.DESTROY,
|
||||
});
|
||||
}
|
||||
}
|
||||
4601
deploy/scripts/cdk/package-lock.json
generated
4601
deploy/scripts/cdk/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"name": "cdk",
|
||||
"version": "0.1.0",
|
||||
"bin": {
|
||||
"cdk": "bin/cdk.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"watch": "tsc -w",
|
||||
"test": "jest",
|
||||
"cdk": "cdk"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/node": "20.1.7",
|
||||
"aws-cdk": "2.86.0",
|
||||
"jest": "^29.5.0",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "~5.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"aws-cdk-lib": "^2.86.0",
|
||||
"cdk-ecr-deployment": "^2.5.30",
|
||||
"constructs": "^10.0.0",
|
||||
"source-map-support": "^0.5.21"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// import * as cdk from 'aws-cdk-lib';
|
||||
// import { Template } from 'aws-cdk-lib/assertions';
|
||||
// import * as Cdk from '../lib/cdk-stack';
|
||||
|
||||
// example test. To run these tests, uncomment this file along with the
|
||||
// example resource in lib/cdk-stack.ts
|
||||
test('SQS Queue Created', () => {
|
||||
// const app = new cdk.App();
|
||||
// // WHEN
|
||||
// const stack = new Cdk.CdkStack(app, 'MyTestStack');
|
||||
// // THEN
|
||||
// const template = Template.fromStack(stack);
|
||||
|
||||
// template.hasResourceProperties('AWS::SQS::Queue', {
|
||||
// VisibilityTimeout: 300
|
||||
// });
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue