diff --git a/Makefile b/Makefile index 8e1b8014..525b2420 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,10 @@ formatted_pattern_names := $(patsubst %.ts,%,$(pattern_files)) # Dependecies HOMEBREW_LIBS := nvm typescript argocd +list: + @$ echo "To work with patterns use: \n\t$$ make pattern " + @$ echo "Example:\n\t$$ make pattern fargate deploy \n\nPatterns: \n" + @$ $(foreach pattern, $(formatted_pattern_names), echo "\t$(pattern)";) deps: bootstrap npm install @@ -29,11 +33,6 @@ build: compile: $(TSC) --build --incremental -list: - @$ echo "To work with patterns use: \n\t$$ make pattern " - @$ echo "Example:\n\t$$ make pattern fargate deploy \n\nPatterns: \n" - @$ $(foreach pattern, $(formatted_pattern_names), echo "\t$(pattern)";) - mkdocs: mkdocs serve diff --git a/lib/common/windows-builder.ts b/lib/common/windows-builder.ts deleted file mode 100644 index 5b829ade..00000000 --- a/lib/common/windows-builder.ts +++ /dev/null @@ -1,130 +0,0 @@ -import * as blueprints from '@aws-quickstart/eks-blueprints'; -import * as utils from '@aws-quickstart/eks-blueprints/dist/utils'; -import { NestedStack, NestedStackProps } from 'aws-cdk-lib'; -import { Construct } from 'constructs'; -import * as eks from "aws-cdk-lib/aws-eks"; -import * as ec2 from "aws-cdk-lib/aws-ec2"; -import * as iam from 'aws-cdk-lib/aws-iam'; -import { NodegroupAmiType } from 'aws-cdk-lib/aws-eks'; - - -export interface WindowsOptions { - kubernetesVersion: eks.KubernetesVersion, - instanceClass: ec2.InstanceClass, - instanceSize: ec2.InstanceSize, - desiredNodeSize: number, - minNodeSize: number, - maxNodeSize: number, - blockDeviceSize: number, - noScheduleForWindowsNodes: boolean, - clusterProviderTags: { - [key: string]: string; - }, - genericNodeGroupTags: { - [key: string]: string; - } - windowsNodeGroupTags: { - [key: string]: string; - } -} - -export class WindowsBuilder extends blueprints.BlueprintBuilder { - - public static builder(options: WindowsOptions): WindowsBuilder { - const builder = new WindowsBuilder(); - - builder - .clusterProvider( - new blueprints.GenericClusterProvider({ - version: options.kubernetesVersion, - tags: options.clusterProviderTags, - role: blueprints.getResource(context => { - return new iam.Role(context.scope, 'ClusterRole', { - assumedBy: new iam.ServicePrincipal("eks.amazonaws.com"), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonEKSClusterPolicy"), - iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonEKSVPCResourceController") - ] - }); - }), - managedNodeGroups: [ - addGenericNodeGroup(options), - addWindowsNodeGroup(options) - ] - }) - ) - .addOns( - new blueprints.NestedStackAddOn({ - id: "usage-tracking-addon", - builder: UsageTrackingAddOn.builder(), - }) - ); - return builder; - } -} - -/** - * Nested stack that is used as tracker for Windows Accelerator - */ -export class UsageTrackingAddOn extends NestedStack { - - static readonly USAGE_ID = "qs-1ubotj5kl"; - - public static builder(): blueprints.NestedStackBuilder { - return { - build(scope: Construct, id: string, props: NestedStackProps) { - return new UsageTrackingAddOn(scope, id, props); - } - }; - } - - constructor(scope: Construct, id: string, props: NestedStackProps) { - super(scope, id, utils.withUsageTracking(UsageTrackingAddOn.USAGE_ID, props)); - } -} - -function addGenericNodeGroup(options: WindowsOptions): blueprints.ManagedNodeGroup { - - return { - id: "mng-linux", - amiType: NodegroupAmiType.AL2_X86_64, - instanceTypes: [new ec2.InstanceType('m5.4xlarge')], - desiredSize: options.desiredNodeSize, - minSize: options.minNodeSize, - maxSize: options.maxNodeSize, - nodeRole: blueprints.getNamedResource("node-role") as iam.Role, - nodeGroupSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }, - launchTemplate: { - tags: options.genericNodeGroupTags, - requireImdsv2: false - } - }; -} - - -function addWindowsNodeGroup(options: WindowsOptions): blueprints.ManagedNodeGroup { - const result : blueprints.ManagedNodeGroup = { - id: "mng-windows", - amiType: NodegroupAmiType.WINDOWS_CORE_2022_X86_64, - instanceTypes: [new ec2.InstanceType(`${options.instanceClass}.${options.instanceSize}`)], - desiredSize: options.desiredNodeSize, - minSize: options.minNodeSize, - maxSize: options.maxNodeSize, - nodeRole: blueprints.getNamedResource("node-role") as iam.Role, - nodeGroupSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }, - diskSize: options.blockDeviceSize, - tags: options.windowsNodeGroupTags - }; - - if(options.noScheduleForWindowsNodes) { - blueprints.utils.setPath(result, "taints", [ - { - key: "os", - value: "windows", - effect: eks.TaintEffect.NO_SCHEDULE - } - ]); - } - - return result; -} diff --git a/lib/karpenter-construct/index.ts b/lib/karpenter-construct/index.ts index 081bd3c6..6410685b 100644 --- a/lib/karpenter-construct/index.ts +++ b/lib/karpenter-construct/index.ts @@ -10,28 +10,32 @@ export default class KarpenterConstruct { const karpenterAddOn = new blueprints.addons.KarpenterAddOn({ version: 'v0.33.1', nodePoolSpec: { - labels: { - type: "karpenter-test" - }, - annotations: { - "eks-blueprints/owner": "eks-blueprints" - }, - taints: [{ - key: "workload", - value: "test", - effect: "NoSchedule", - }], requirements: [ - { key: 'node.kubernetes.io/instance-type', operator: 'In', values: ['m5.2xlarge'] }, + { key: 'node.kubernetes.io/instance-type', operator: 'In', values: ['m5.large'] }, { key: 'topology.kubernetes.io/zone', operator: 'In', values: [`${region}a`,`${region}b`, `${region}c`]}, { key: 'kubernetes.io/arch', operator: 'In', values: ['amd64','arm64']}, - { key: 'karpenter.sh/capacity-type', operator: 'In', values: ['spot']}, - ] + { key: 'karpenter.sh/capacity-type', operator: 'In', values: ['on-demand']}, + ], + disruption: { + consolidationPolicy: "WhenUnderutilized", + expireAfter: "259200s" + }, + weight: 20, + }, - ec2NodeClassSpec: { - amiFamily: "AL2", - subnetSelectorTerms: [{ tags: { "Name": "my-stack-name/my-stack-name-vpc/PrivateSubnet*" }}], - securityGroupSelectorTerms: [{ tags: { "aws:eks:cluster-name": "karpenter" }}], + ec2NodeClassSpec:{ + subnetSelectorTerms: [ + { + tags: { "Name": `${stackID}/${stackID}-vpc/*` } + } + ], + securityGroupSelectorTerms: [ + { + tags: { [`kubernetes.io/cluster/${stackID}`]: "owned" } + } + ], + + amiFamily: "AL2" }, interruptionHandling: true, }); diff --git a/lib/security/data-at-rest-encryption/index.ts b/lib/security/data-at-rest-encryption/index.ts index d7c2b1a2..6c55c534 100644 --- a/lib/security/data-at-rest-encryption/index.ts +++ b/lib/security/data-at-rest-encryption/index.ts @@ -16,9 +16,9 @@ const targetRevision = "main"; export default class DataAtRestEncryptionConstruct { async buildAsync(scope: Construct, id: string) { - + await prevalidateSecrets(DataAtRestEncryptionConstruct.name, process.env.CDK_DEFAULT_REGION!, SECRET_ARGO_ADMIN_PWD); - + const stackId = `${id}-blueprint`; const ebsKmsKeyName = "ebs-kms-encryption-key"; diff --git a/lib/windows-construct/index.ts b/lib/windows-construct/index.ts index e1a39bc8..b8d33eee 100644 --- a/lib/windows-construct/index.ts +++ b/lib/windows-construct/index.ts @@ -3,8 +3,8 @@ 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 { Construct } from "constructs"; -import { WindowsBuilder, WindowsOptions } from '../common/windows-builder'; -// import { WindowsVpcCni } from "./vpc-cni"; +import { WindowsBuilder, WindowsOptions, KarpenterAddOnProps } from "@aws-quickstart/eks-blueprints"; +import { WindowsVpcCni } from "./vpc-cni"; export default class WindowsConstruct { build(scope: Construct, id: string) { @@ -21,11 +21,11 @@ export default class WindowsConstruct { ]); const options: WindowsOptions = { - kubernetesVersion: eks.KubernetesVersion.of("1.27"), - instanceClass: ec2.InstanceClass.M5, - instanceSize: ec2.InstanceSize.XLARGE4, - desiredNodeSize: 2, - minNodeSize: 2, + kubernetesVersion: eks.KubernetesVersion.V1_29, + instanceClass: ec2.InstanceClass.T3, + instanceSize: ec2.InstanceSize.MEDIUM, + desiredNodeCount: 1, + minNodeSize: 1, maxNodeSize: 3, blockDeviceSize: 50, noScheduleForWindowsNodes: true, @@ -33,27 +33,60 @@ export default class WindowsConstruct { "Name": "blueprints-windows-eks-cluster", "Type": "generic-windows-cluster" }, - genericNodeGroupTags: { - "Name": "Mng-linux", - "Type": "Managed-linux-Node-Group", - "LaunchTemplate": "Linux-Launch-Template", + genericNodeGroupOptions: { + nodegroupName: "Mng-linux", + tags: { + "kubernetes.io/cluster/windows-eks-blueprint": "owned" + } }, - windowsNodeGroupTags: { - "Name": "Managed-Node-Group", - "Type": "Windows-Node-Group", - "LaunchTemplate": "WindowsLT", - "kubernetes.io/cluster/windows-eks-blueprint": "owned" + windowsNodeGroupOptions: { + nodegroupName: "Mng-windows", + tags: { + "kubernetes.io/cluster/windows-eks-blueprint": "owned" + } } }; const addOns: Array = [ - // new WindowsVpcCni() + new WindowsVpcCni(), ]; + const karpenterProps :KarpenterAddOnProps = { + nodePoolSpec: { + requirements: [ + { key: 'kubernetes.io/os', operator: 'In', values: ['windows']}, + ], + taints: [ + { + key: "os", + value: "windows", + effect: "NoSchedule" + } + ], + disruption: { + consolidationPolicy: "WhenEmpty", + consolidateAfter: "300s", + expireAfter: "2592000s" + }, + weight: 20 + }, + ec2NodeClassSpec : { + subnetSelectorTerms: [ + { tags: { "Name": `${stackID}/${stackID}-vpc/Private*` }} + ], + securityGroupSelectorTerms: [ + {tags: { [`kubernetes.io/cluster/${stackID}`]: "owned",}} + ], + amiFamily: "Windows2022" + }, + }; + WindowsBuilder.builder(options) .addOns(...addOns) .account(account) .region(region) + .withKarpenterProps(karpenterProps) + .enableKarpenter() .resourceProvider("node-role", nodeRole) .resourceProvider( blueprints.GlobalResources.Vpc, diff --git a/lib/windows-construct/vpc-cni/index.ts b/lib/windows-construct/vpc-cni/index.ts index c1624596..e86a30ea 100644 --- a/lib/windows-construct/vpc-cni/index.ts +++ b/lib/windows-construct/vpc-cni/index.ts @@ -1,4 +1,5 @@ import * as blueprints from '@aws-quickstart/eks-blueprints'; +import { KubernetesManifest } from 'aws-cdk-lib/aws-eks'; import { Construct } from 'constructs'; export class WindowsVpcCni implements blueprints.ClusterAddOn { @@ -6,17 +7,18 @@ export class WindowsVpcCni implements blueprints.ClusterAddOn { deploy(clusterInfo: blueprints.ClusterInfo): void | Promise { const cluster = clusterInfo.cluster; - const configmap = cluster.addManifest("amazon-vpc-cni", { - apiVersion: "v1", - kind: "ConfigMap", - metadata: { - name: "amazon-vpc-cni", - namespace: "kube-system", - }, - data:{ - "enable-windows-ipam": "true" - }, - }); + const configmap = new KubernetesManifest(cluster, 'amazon-vpc-cni', { cluster: cluster, + manifest : [{ + apiVersion: "v1", + kind: "ConfigMap", + metadata: { + name: "amazon-vpc-cni", + namespace: "kube-system", + }, + data:{ + "enable-windows-ipam": "true" + }, + }], overwrite: true }); return Promise.resolve(configmap); }