Skip to content

Commit

Permalink
feat(eks): support AccessConfig for the Cluster construct (#30016)
Browse files Browse the repository at this point in the history
###  Background

Amazon EKS originally uses `ConfigMap` as its access management and in aws-eks we use AwsAuth to leverage the kubectl from kubectl-lambda-layer to create the AwsAuth configmap for that. The ConfigMap has been very difficult to maintain due to its lack support of EKS API but thanks to the AwsAuth class, it's been very smooth in CDK.

In AWS reInvent 2023 we [announced](https://aws.amazon.com/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/) the access API support that simplifies the management as a replacement of the traditional ConfigMap. In CloudFormation we have the [AccessConfig](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-accessconfig) with [AuthenticationMode](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-accessconfig.html#cfn-eks-cluster-accessconfig-authenticationmode) and `BootstrapClusterCreatorAdminPermissions` now.

The `AuthenticationMode` supports `CONFIG_MAP`, which is the default, `API_AND_CONFIG_MAP` and `CONFIG_MAP`. It allows users to switch the mode on cluster creation or update. When the mode has API support, users have to define the `AccessEntry` to map the access policies and the IAM principals. This PR introduces the `AccessEntry` and `AccessPolicy` classes for that to simplify it with similar experience just as the [iam.ManagedPolicy ](https://github.com/aws/aws-cdk/blob/3928eae1ee92a03ba9959288f05f59d6bd5edcba/packages/aws-cdk-lib/aws-iam/lib/managed-policy.ts#L104)class. This PR also introduces the `grantAccess()` method that allows a cluster to `grant` its access to a specific principal and abstracts away the complexity.

Overview of the API experience from this PR:

```ts
const cluster = new eks.Cluster(this, 'Cluster', {
  vpc,
  mastersRole: clusterAdminRole,
  version: eks.KubernetesVersion.V1_30,
  kubectlLayer: new KubectlV29Layer(this, 'KubectlLayer'),
  authenticationMode: eks.AuthenticationMode.API_AND_CONFIG_MAP,
});

// Cluster Admin role for this cluster
cluster.grantAccess('clusterAdminAccess', clusterAdminRole.roleArn, [
  eks.AccessPolicy.fromAccessPolicyName('AmazonEKSClusterAdminPolicy', {
    accessScopeType: eks.AccessScopeType.CLUSTER,
  }),
]);

// EKS Admin role for specified namespaces of thie cluster
cluster.grantAccess('eksAdminRoleAccess', eksAdminRole.roleArn, [
  eks.AccessPolicy.fromAccessPolicyName('AmazonEKSAdminPolicy', {
    accessScopeType: eks.AccessScopeType.NAMESPACE,
    namespaces: ['foo', 'bar'],
  }),
]);

// EKS Admin Viewer role for specified namespaces of thie cluster
cluster.grantAccess('eksAdminViewRoleAccess', eksAdminViewRole.roleArn, [
  eks.AccessPolicy.fromAccessPolicyName('AmazonEKSAdminViewPolicy', {
    accessScopeType: eks.AccessScopeType.NAMESPACE,
    namespaces: ['foo', 'bar'],
  }),
]);
```


### Issue # (if applicable)

Closes  #28588

This PR introduces the `authenticationMode`, `AccessEntry` and `AccessPolicy` for both `Cluster` and `FargateCluster` construct.

- [x] bump `@aws-sdk/client-eks` to [v3.476.0](https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.476.0)(the minimal version with EKS Cluster Access Management support)
- [x] make sure it deploys with the new AccessConfig support for a new cluster
- [x] make sure an existing cluster can update by adding this new prop
- [x] make sure it deploys with a new FargateCluster
- [x] make sure an existing FargateCluster can update by adding this new prop
- [x] make sure it works with CfnAccessEntry L1 resources
- [x] AccessEntry L2 construct support
- [x] AccessPolicy class
- [x] bootstrapClusterCreatorAdminPermissions
- [x] unit tests
- [x] integ tests
- [x] update README
- [x] add PR notes

### Notes

1. Switching authentication modes on an existing cluster is a one-way operation like:

undefined(CONFIG_MAP) -> API_AND_CONFIG_MAP -> API

You can switch from undefined or CONFIG_MAP to API_AND_CONFIG_MAP. You can then switch from API_AND_CONFIG_MAP to API. You cannot revert these operations in the opposite direction. Meaning you cannot switch back to CONFIG_MAP or API_AND_CONFIG_MAP from API. And you cannot switch back to CONFIG_MAP from API_AND_CONFIG_MAP. (see [here](https://aws.amazon.com/blogs/containers/a-deep-dive-into-simplified-amazon-eks-access-management-controls/)) This PR adds relevant checks in the custom resource and add docstring in the `authenticationMode` prop.

2. Switching `bootstrapClusterCreatorAdminPermissions` would cause cluster replacement, we callout in the README and construct prop docstring as a headsup. This option is [available](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-accessconfig.html#cfn-eks-cluster-accessconfig-bootstrapclustercreatoradminpermissions) in CFN which triggers replacement on resource update as well. I have created #30107 for further improvement.

3. This feature does not support AWS China regions at this moment as the JS SDK version of lambda node18 runtime in China regions is `3.462.0` while this feature requires SDK [3.476.0](https://github.com/aws/aws-sdk-js-v3/releases/tag/v3.476.0) or above. It's `3.552.0` in us-east-1. Use [this example](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html#nodejs-sdk-included) to check the version.


### Reason for this change



### Description of changes



### Description of how you validated changes



### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pahud authored Jun 12, 2024
1 parent 87e27e6 commit f45f2ca
Show file tree
Hide file tree
Showing 145 changed files with 3,929 additions and 2,212 deletions.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -758,15 +758,16 @@
],
"endpointPublicAccess": true,
"endpointPrivateAccess": true
}
},
"accessConfig": {}
},
"AssumeRoleArn": {
"Fn::GetAtt": [
"ClusterCreationRole360249B6",
"Arn"
]
},
"AttributesRevision": 2
"AttributesRevision": 3
},
"DependsOn": [
"ClusterCreationRoleDefaultPolicyE8BDFC7B",
Expand Down Expand Up @@ -1055,7 +1056,7 @@
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"/e9d9890827c645c3a2c82d768d4693e81fa2931a46a36cde032d4250757beab0.json"
"/12013bd7d8559f6883e853e9624275cf3f32d86c166243ab85c46269c009b249.json"
]
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "98b432f1b1df9de4026df7e718c23783d833d67973da5291085b4dc7be1a568a.zip"
"S3Key": "e360285e7bd78b792c3d120b19dff9840b2c1a235eba49ce3ab0105470358b6f.zip"
},
"Description": "onEvent handler for EKS cluster resource provider",
"Environment": {
Expand Down Expand Up @@ -123,7 +123,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "98b432f1b1df9de4026df7e718c23783d833d67973da5291085b4dc7be1a568a.zip"
"S3Key": "e360285e7bd78b792c3d120b19dff9840b2c1a235eba49ce3ab0105470358b6f.zip"
},
"Description": "isComplete handler for EKS cluster resource provider",
"Environment": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -790,15 +790,16 @@
],
"endpointPublicAccess": true,
"endpointPrivateAccess": true
}
},
"accessConfig": {}
},
"AssumeRoleArn": {
"Fn::GetAtt": [
"ClusterCreationRole360249B6",
"Arn"
]
},
"AttributesRevision": 2
"AttributesRevision": 3
},
"DependsOn": [
"ClusterCreationRoleDefaultPolicyE8BDFC7B",
Expand Down Expand Up @@ -1090,7 +1091,7 @@
{
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"/5183cc422a19a5604be88f1ee0a9036e003ed1667674934ea69783dc23d26858.json"
"/0b7ef3ca06eaead821362aa05ba1bb17d7176815cd57a424ec9be01db5f23a4c.json"
]
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "98b432f1b1df9de4026df7e718c23783d833d67973da5291085b4dc7be1a568a.zip"
"S3Key": "e360285e7bd78b792c3d120b19dff9840b2c1a235eba49ce3ab0105470358b6f.zip"
},
"Description": "onEvent handler for EKS cluster resource provider",
"Environment": {
Expand Down Expand Up @@ -123,7 +123,7 @@
"S3Bucket": {
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
},
"S3Key": "98b432f1b1df9de4026df7e718c23783d833d67973da5291085b4dc7be1a568a.zip"
"S3Key": "e360285e7bd78b792c3d120b19dff9840b2c1a235eba49ce3ab0105470358b6f.zip"
},
"Description": "isComplete handler for EKS cluster resource provider",
"Environment": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f45f2ca

Please sign in to comment.