diff --git a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts index 1bde911f690e1..a5eefcbe44fd6 100644 --- a/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts +++ b/packages/aws-cdk-lib/aws-eks/lib/managed-nodegroup.ts @@ -371,6 +371,15 @@ export interface NodegroupOptions { * @default - disabled */ readonly enableNodeAutoRepair?: boolean; + + /** + * Specifies the roles that will be added to the node role mapping in aws-auth configmap. + * If not specified, the default roles `system:bootstrappers` and `system:nodes` will be added. + * If the AMI type is Windows, `eks:kube-proxy-windows` will also be added to support Windows nodes. + * + * @default - `system:bootstrappers` and `system:nodes` will be added, and `eks:kube-proxy-windows` if AMI type is Windows. + */ + readonly nodeRoleGroups?: string[]; } /** @@ -576,12 +585,20 @@ export class Nodegroup extends Resource implements INodegroup { // only when ConfigMap is supported const supportConfigMap = props.cluster.authenticationMode !== AuthenticationMode.API ? true : false; if (supportConfigMap) { - this.cluster.awsAuth.addRoleMapping(this.role, { - username: 'system:node:{{EC2PrivateDNSName}}', - groups: [ + let groups: string[] | undefined = props.nodeRoleGroups; + if (!groups) { + groups = [ 'system:bootstrappers', 'system:nodes', - ], + ]; + if (props.amiType && windowsAmiTypes.includes(props.amiType)) { + groups.push('eks:kube-proxy-windows'); + } + } + + this.cluster.awsAuth.addRoleMapping(this.role, { + username: 'system:node:{{EC2PrivateDNSName}}', + groups, }); } // the controller runs on the worker nodes so they cannot diff --git a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts index 372e9621a71a9..540c8349940ad 100644 --- a/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts +++ b/packages/aws-cdk-lib/aws-eks/test/nodegroup.test.ts @@ -1108,6 +1108,126 @@ describe('node group', () => { }); }); + test('aws-auth will be updated with nodeRoleGroups when provided', () => { + // GIVEN + const { stack, vpc } = testFixture(); + + // WHEN + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + mastersRole: new iam.Role(stack, 'MastersRole', { + assumedBy: new iam.ArnPrincipal('arn:aws:iam:123456789012:user/user-name'), + }), + kubectlLayer: new KubectlV31Layer(stack, 'KubectlLayer'), + }); + new eks.Nodegroup(stack, 'Nodegroup', { cluster, nodeRoleGroups: ['system:fake-role'] }); + + // THEN + Template.fromStack(stack).hasResourceProperties(eks.KubernetesManifest.RESOURCE_TYPE, { + Manifest: { + 'Fn::Join': [ + '', + [ + '[{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"aws-auth","namespace":"kube-system","labels":{"aws.cdk.eks/prune-c82ececabf77e03e3590f2ebe02adba8641d1b3e76":""}},"data":{"mapRoles":"[{\\"rolearn\\":\\"', + { + 'Fn::GetAtt': [ + 'MastersRole0257C11B', + 'Arn', + ], + }, + '\\",\\"username\\":\\"', + { + 'Fn::GetAtt': [ + 'MastersRole0257C11B', + 'Arn', + ], + }, + '\\",\\"groups\\":[\\"system:masters\\"]},{\\"rolearn\\":\\"', + { + 'Fn::GetAtt': [ + 'NodegroupNodeGroupRole038A128B', + 'Arn', + ], + }, + '\\",\\"username\\":\\"system:node:{{EC2PrivateDNSName}}\\",\\"groups\\":[\\"system:fake-role\\"]}]","mapUsers":"[]","mapAccounts":"[]"}}]', + ], + ], + }, + ClusterName: { + Ref: 'Cluster9EE0221C', + }, + RoleArn: { + 'Fn::GetAtt': [ + 'ClusterCreationRole360249B6', + 'Arn', + ], + }, + PruneLabel: 'aws.cdk.eks/prune-c82ececabf77e03e3590f2ebe02adba8641d1b3e76', + }); + }); + + test('aws-auth will be updated with eks:kube-proxy-windows when AMI OS is Windows', () => { + // GIVEN + const { stack, vpc } = testFixture(); + + // WHEN + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + mastersRole: new iam.Role(stack, 'MastersRole', { + assumedBy: new iam.ArnPrincipal('arn:aws:iam:123456789012:user/user-name'), + }), + kubectlLayer: new KubectlV31Layer(stack, 'KubectlLayer'), + }); + new eks.Nodegroup(stack, 'Nodegroup', { cluster, amiType: NodegroupAmiType.WINDOWS_FULL_2022_X86_64 }); + + // THEN + Template.fromStack(stack).hasResourceProperties(eks.KubernetesManifest.RESOURCE_TYPE, { + Manifest: { + 'Fn::Join': [ + '', + [ + '[{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"aws-auth","namespace":"kube-system","labels":{"aws.cdk.eks/prune-c82ececabf77e03e3590f2ebe02adba8641d1b3e76":""}},"data":{"mapRoles":"[{\\"rolearn\\":\\"', + { + 'Fn::GetAtt': [ + 'MastersRole0257C11B', + 'Arn', + ], + }, + '\\",\\"username\\":\\"', + { + 'Fn::GetAtt': [ + 'MastersRole0257C11B', + 'Arn', + ], + }, + '\\",\\"groups\\":[\\"system:masters\\"]},{\\"rolearn\\":\\"', + { + 'Fn::GetAtt': [ + 'NodegroupNodeGroupRole038A128B', + 'Arn', + ], + }, + '\\",\\"username\\":\\"system:node:{{EC2PrivateDNSName}}\\",\\"groups\\":[\\"system:bootstrappers\\",\\"system:nodes\\",\\"eks:kube-proxy-windows\\"]}]","mapUsers":"[]","mapAccounts":"[]"}}]', + ], + ], + }, + ClusterName: { + Ref: 'Cluster9EE0221C', + }, + RoleArn: { + 'Fn::GetAtt': [ + 'ClusterCreationRole360249B6', + 'Arn', + ], + }, + PruneLabel: 'aws.cdk.eks/prune-c82ececabf77e03e3590f2ebe02adba8641d1b3e76', + }); + }); + test('create nodegroup correctly with security groups provided', () => { // GIVEN const { stack, vpc } = testFixture();