11import { Easy_EKS_Config_Data } from './Easy_EKS_Config_Data' ;
22import * as cdk from 'aws-cdk-lib' ;
33import * as eks from 'aws-cdk-lib/aws-eks' ;
4+ import * as iam from 'aws-cdk-lib/aws-iam' ;
5+ import { IConstruct } from 'constructs' ;
6+ import { Karpenter } from 'cdk-eks-karpenter' //npm install cdk-eks-karpenter
7+
8+ export interface Karpenter_Helm_Config {
9+ helm_chart_version : string ,
10+ helm_chart_values ?: Record < string , any > | undefined ,
11+ }
412
513export interface Karpenter_Manifest_Loop_Inputs {
614 arch : string ,
@@ -9,6 +17,8 @@ export interface Karpenter_Manifest_Loop_Inputs {
917 nodepools_cpu_limit : number ,
1018}
1119
20+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21+
1222export class Karpenter_YAML_Generator {
1323
1424 config : Easy_EKS_Config_Data ;
@@ -54,7 +64,7 @@ export class Karpenter_YAML_Generator{
5464 } ,
5565 "spec" : {
5666 "amiFamily" : "Bottlerocket" ,
57- "role" : `${ config . baselineNodeRole . roleName } ` ,
67+ "role" : `${ config . workerNodeRole . roleName } ` ,
5868 "subnetSelectorTerms" : subnetSelectorTerms ,
5969 "securityGroupSelectorTerms" : [ { "tags" : { "aws:eks:cluster-name" : `${ cluster . clusterName } ` } } ] ,
6070 "tags" : { //ARM64-bottlerocket-spot
@@ -132,9 +142,83 @@ export class Karpenter_YAML_Generator{
132142 array_of_yaml_manifests_to_return . push ( karpenter_bottlerocket_NodePool ) ;
133143 } //end for
134144
135-
136-
137145 return array_of_yaml_manifests_to_return ;
138146 } //end generate_manifests
139147
140148} //end class Karepnter_Manifests
149+
150+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151+
152+ export function Apply_Karpenter_YAMLs_with_fixes ( stack : cdk . Stack , cluster : eks . Cluster , config : Easy_EKS_Config_Data ,
153+ karpenter_helm_config : Karpenter_Helm_Config ,
154+ karpenter_YAMLs : { [ key : string ] : any ; } [ ] ,
155+ readiness_dependency : IConstruct ) {
156+
157+ //v-- Creates a ton of prerequisites and a release/instance of karpenter helm chart
158+ const karpenter = new Karpenter ( stack , 'Karpenter' , {
159+ cluster : cluster ,
160+ namespace : 'kube-system' ,
161+ version : karpenter_helm_config . helm_chart_version ,
162+ nodeRole : config . workerNodeRole ,
163+ helmExtraValues : karpenter_helm_config . helm_chart_values ,
164+ } ) ;
165+ //v-- The following 2 lines update cdk's order of operations to wait to deploy karpenter, until cluster is ready
166+ karpenter . node . addDependency ( readiness_dependency ) ; //Expected value of awsLoadBalancerController Helm Release
167+ karpenter . node . addDependency ( cluster . awsAuth ) ;
168+ //v-- Patch fix for https://github.com/aws-samples/cdk-eks-karpenter/issues/231
169+ Patch_Karpenters_IAM_Role ( stack , config ) ;
170+ //v-- The following 2 lines help prevent cdk destroy issue
171+ const karpenter_helm_chart_CFR = ( stack . node . tryFindChild ( config . id ) ?. node . tryFindChild ( 'chart-karpenter' ) ?. node . defaultChild as cdk . CfnResource ) ;
172+ if ( karpenter_helm_chart_CFR ) { karpenter_helm_chart_CFR . applyRemovalPolicy ( cdk . RemovalPolicy . RETAIN ) ; }
173+
174+ //v-- kubectl apply -f karpenter_YAMLs
175+ const apply_karpenter_YAML = new eks . KubernetesManifest ( stack , 'karpenter_YAMLs' ,
176+ {
177+ cluster : cluster ,
178+ manifest : karpenter_YAMLs ,
179+ overwrite : true ,
180+ prune : true ,
181+ }
182+ ) ;
183+ //v-- Inform cdk of order of operations
184+ apply_karpenter_YAML . node . addDependency ( karpenter ) ;
185+ //v-- The following 2 lines prevent cdk destroy issue
186+ const apply_karpenter_YAML_CFR = ( apply_karpenter_YAML . node . defaultChild as cdk . CfnResource ) ;
187+ if ( apply_karpenter_YAML_CFR ) { apply_karpenter_YAML_CFR . applyRemovalPolicy ( cdk . RemovalPolicy . RETAIN ) ; }
188+
189+ } //end function Apply_Karpenter_YAMLs_with_fixes
190+
191+ function Patch_Karpenters_IAM_Role ( stack : cdk . Stack , config : Easy_EKS_Config_Data ) {
192+ //Patch fix for https://github.com/aws-samples/cdk-eks-karpenter/issues/231
193+ let karpenter_controller_pods_role = stack . node . tryFindChild ( config . id ) ?. node . tryFindChild ( 'karpenter' ) ?. node . tryFindChild ( 'Role' ) as iam . Role ;
194+ const karpenter_IAM_Policy_JSON = {
195+ "Version" : "2012-10-17" ,
196+ "Statement" : [
197+ {
198+ "Sid" : "AllowInstanceProfileActions" ,
199+ "Effect" : "Allow" ,
200+ "Resource" : `arn:aws:iam::${ process . env . CDK_DEFAULT_ACCOUNT ! } :instance-profile/*` ,
201+ "Action" : [
202+ "iam:GetInstanceProfile" ,
203+ "iam:AddRoleToInstanceProfile" ,
204+ "iam:RemoveRoleFromInstanceProfile" ,
205+ ] ,
206+ } ,
207+ { //v-- This isn't a hard requirement, but enables faster convergence
208+ // without it karpenter logs temporarily mention an IAM rights failure, that fixes itself within 11 mins.
209+ "Sid" : "LessRestrictivePassRoleForFasterConvergence" ,
210+ "Effect" : "Allow" ,
211+ "Resource" : `arn:aws:iam::${ process . env . CDK_DEFAULT_ACCOUNT ! } :role/*` ,
212+ "Action" : [
213+ "iam:PassRole" ,
214+ ] ,
215+ } ,
216+ ]
217+ } ;
218+ const karpenter_IAM_Policy = new iam . Policy ( stack , `karpenter_controller_pod_IAM_policy_for_EKS` , {
219+ document : iam . PolicyDocument . fromJson ( karpenter_IAM_Policy_JSON ) ,
220+ } ) ;
221+ karpenter_controller_pods_role . attachInlinePolicy ( karpenter_IAM_Policy ) ;
222+ }
223+
224+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0 commit comments