eks-for-prod
Version:
EKS Cluster + EFS Filesystem + Aurora Serverless Cluster
112 lines (111 loc) • 5.69 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EksClusterStage = exports.EksClusterStack = exports.EksCluster = void 0;
const core_1 = require("@aws-cdk/core");
const aws_eks_1 = require("@aws-cdk/aws-eks");
const aws_load_balancer_controller_1 = require("./aws-load-balancer-controller");
const cluster_autoscaler_1 = require("./cluster-autoscaler");
const cluster_overprovisioner_1 = require("./cluster-overprovisioner");
const aws_ec2_1 = require("@aws-cdk/aws-ec2");
const aws_node_termination_handler_1 = require("./aws-node-termination-handler");
const prometheus_grafana_1 = require("./prometheus-grafana");
const metrics_server_1 = require("./metrics-server");
const aws_efs_csi_driver_1 = require("./aws-efs-csi-driver");
const external_secrets_1 = require("./external-secrets");
const utils_1 = require("./utils");
const aws_efs_1 = require("@aws-cdk/aws-efs");
const aws_rds_1 = require("@aws-cdk/aws-rds");
class EksCluster extends core_1.Construct {
constructor(scope, id) {
super(scope, id);
this.cluster = this.createEksCluster();
new aws_load_balancer_controller_1.AwsLoadBalancerController(this, 'AWSLoadBalancerController', { cluster: this.cluster });
new aws_node_termination_handler_1.AwsNodeTerminationHandler(this, 'AwsNodeTerminationHandler', { cluster: this.cluster });
new aws_efs_csi_driver_1.AwsEfsCsiDriver(this, 'AwsEfsCsiDriver', { cluster: this.cluster });
new cluster_autoscaler_1.ClusterAutoscaler(this, 'ClusterAutoScaler', { cluster: this.cluster });
new cluster_overprovisioner_1.ClusterOverprovisioner(this, 'ClusterOverProvisioner', { cluster: this.cluster });
new metrics_server_1.MetricsServer(this, 'MetricsServer', { cluster: this.cluster });
new prometheus_grafana_1.PrometheusGrafana(this, 'PrometheusGrafana', { cluster: this.cluster });
new external_secrets_1.ExternalSecrets(this, 'ExternalSecrets', { cluster: this.cluster });
this.createSpotNodeGroups(this.cluster);
}
createEksCluster() {
return new aws_eks_1.Cluster(this, 'EKSCluster', {
version: aws_eks_1.KubernetesVersion.V1_20,
clusterName: 'k8s-cluster'
});
}
createSpotNodeGroups(cluster) {
[aws_ec2_1.InstanceSize.XLARGE, aws_ec2_1.InstanceSize.XLARGE2].forEach(instanceSize => {
const nodeGroup = new aws_eks_1.Nodegroup(this, 'SpoInstancesNodeGroup' + instanceSize, {
cluster,
labels: {
lifecycle: 'Ec2Spot',
intent: 'apps'
},
capacityType: aws_eks_1.CapacityType.SPOT,
minSize: 1,
maxSize: 5,
desiredSize: 1,
subnets: cluster.vpc.selectSubnets({
subnetType: aws_ec2_1.SubnetType.PRIVATE
}),
instanceTypes: [
aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.M5, instanceSize), aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.M5D, instanceSize),
aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.M5A, instanceSize), aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.M4, instanceSize),
aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.T3, instanceSize), aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.T3A, instanceSize),
aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.T2, instanceSize),
]
});
nodeGroup.node.defaultChild.taints = [
{
key: 'spotInstance',
value: 'true',
effect: 'NO_SCHEDULE'
}
];
});
}
}
exports.EksCluster = EksCluster;
class EksClusterStack extends core_1.Stack {
constructor(scope, id, props) {
super(scope, id, props);
const eksCluster = new EksCluster(this, 'EksCluster');
const fileSystem = new aws_efs_1.FileSystem(this, 'EfsFileSystem', {
vpc: eksCluster.cluster.vpc,
enableAutomaticBackups: true,
encrypted: true,
fileSystemName: 'eks-cluster-filesystem',
lifecyclePolicy: aws_efs_1.LifecyclePolicy.AFTER_30_DAYS,
removalPolicy: core_1.RemovalPolicy.RETAIN,
vpcSubnets: eksCluster.cluster.vpc.selectSubnets({
subnetType: aws_ec2_1.SubnetType.PRIVATE
})
});
fileSystem.connections.allowDefaultPortFrom(eksCluster.cluster);
utils_1.Utils.applyYamlManifest(eksCluster.cluster, 'aws-efs-csi-driver-storage-class', manifestContent => manifestContent.replace('<FILESYSTEM_ID>', fileSystem.fileSystemId));
const database = new aws_rds_1.ServerlessCluster(this, 'Database', {
vpc: eksCluster.cluster.vpc,
vpcSubnets: eksCluster.cluster.vpc.selectSubnets({
subnetType: aws_ec2_1.SubnetType.PRIVATE
}),
engine: aws_rds_1.DatabaseClusterEngine.AURORA_MYSQL,
scaling: {
minCapacity: aws_rds_1.AuroraCapacityUnit.ACU_1,
maxCapacity: aws_rds_1.AuroraCapacityUnit.ACU_8
},
backupRetention: core_1.Duration.days(7),
removalPolicy: core_1.RemovalPolicy.RETAIN
});
database.addRotationSingleUser();
}
}
exports.EksClusterStack = EksClusterStack;
class EksClusterStage extends core_1.Stage {
constructor(scope, id, props) {
super(scope, id, props);
new EksClusterStack(this, 'EksClusterStack');
}
}
exports.EksClusterStage = EksClusterStage;