langflow/deploy/scripts/cdk/lib/construct/network.ts
2023-11-20 19:20:26 +09:00

180 lines
No EOL
5.7 KiB
TypeScript

import { RemovalPolicy, Duration } from 'aws-cdk-lib'
import { Construct } from 'constructs'
import {
aws_ec2 as ec2,
aws_ecs as ecs,
aws_dynamodb as dynamodb,
aws_iam as iam,
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 backendTaskRole: iam.Role;
readonly TaskExecutionRole: iam.Role;
readonly frontendTaskRole: iam.Role;
readonly backendLogGroup: logs.LogGroup;
readonly frontendLogGroup: logs.LogGroup;
constructor(scope: Construct, id: string) {
super(scope, id)
// 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,
})
this.cluster = new ecs.Cluster(this, 'EcsCluster', {
clusterName: 'langflow-cluster',
vpc: this.vpc,
});
// 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(80))
this.alb = new elb.ApplicationLoadBalancer(this,'alb',{
internetFacing: true, //インターネットからのアクセスを許可するかどうか指定
loadBalancerName: 'alb',
securityGroup: this.albSG, //作成したセキュリティグループを割り当てる
vpc:this.vpc,
})
const listener = this.alb.addListener('Listener', { port: 80 });
this.targetGroup = listener.addTargets('targetGroup', {
port: 3000,
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(7860))
// 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))
// ECS Policy State
const ECSExecPolicyStatement = new iam.PolicyStatement({
sid: 'allowECSExec',
resources: ['*'],
actions: [
'ecr:GetAuthorizationToken',
'ecr:BatchCheckLayerAvailability',
'ecr:GetDownloadUrlForLayer',
'ecr:BatchGetImage',
'ssmmessages:CreateControlChannel',
'ssmmessages:CreateDataChannel',
'ssmmessages:OpenControlChannel',
'ssmmessages:OpenDataChannel',
'logs:CreateLogStream',
'logs:DescribeLogGroups',
'logs:DescribeLogStreams',
'logs:PutLogEvents',
],
});
this.backendTaskRole = new iam.Role(this, 'BackendTaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
this.backendTaskRole.addToPolicy(ECSExecPolicyStatement);
this.frontendTaskRole = new iam.Role(this, 'FrontendTaskRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
});
this.frontendTaskRole.addToPolicy(ECSExecPolicyStatement);
this.TaskExecutionRole = new iam.Role(this, 'TaskExecutionRole', {
assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'),
managedPolicies: [
{
managedPolicyArn:
'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy',
},
],
});
// 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,
});
}
}