Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eks): Support cdk8s charts #10562

Merged
merged 42 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0af939c
rename addChart => addHelmChart
iliapolo Sep 24, 2020
ffaa5b1
rename capacity methods
iliapolo Sep 24, 2020
107214b
rename launchTemplate to launchTemplateSpec
iliapolo Sep 24, 2020
3110f3e
Merge branch 'master' into epolon/10364-eks-dev-preview
iliapolo Sep 24, 2020
f24e819
flip maturity to dev preview
iliapolo Sep 24, 2020
8db2646
fix test
iliapolo Sep 27, 2020
3add737
working on new readme
iliapolo Sep 27, 2020
6e00ef1
mid work
iliapolo Sep 27, 2020
d661f85
mid work
iliapolo Sep 27, 2020
1829e5c
use published version cdk8s
iliapolo Sep 27, 2020
c7fa886
mid work
iliapolo Sep 27, 2020
d5aa7e4
mid work
iliapolo Sep 27, 2020
9bbc1bc
mid work
iliapolo Sep 27, 2020
dc1770d
mid work
iliapolo Sep 27, 2020
217f090
add cdk8s as a dependency to mono packages
iliapolo Sep 28, 2020
c9e929b
mid work
iliapolo Sep 28, 2020
42a4f72
mid work
iliapolo Sep 28, 2020
20d17a6
mid work
iliapolo Sep 28, 2020
2e23a1d
mid work
iliapolo Sep 28, 2020
4396001
mid work
iliapolo Sep 28, 2020
55dbfad
mid work
iliapolo Sep 28, 2020
aae7274
mid work
iliapolo Sep 28, 2020
14fa878
refactor
iliapolo Sep 28, 2020
37bb76a
refactor
iliapolo Sep 28, 2020
b6279e0
Merge branch 'epolon/10364-eks-dev-preview' into epolon/eks-cdk8s
iliapolo Sep 28, 2020
c9da142
added cdk8s docs
iliapolo Sep 28, 2020
9d9a3bb
mid work
iliapolo Sep 28, 2020
9b343e9
Merge branch 'master' into epolon/eks-cdk8s
iliapolo Sep 30, 2020
1c100b9
added cdk8s version requirement
iliapolo Sep 30, 2020
9fabc39
extend cdk8s chart in integ test
iliapolo Oct 1, 2020
127f60c
use cdk8s-plus
iliapolo Oct 2, 2020
7f49189
Merge branch 'master' into epolon/eks-cdk8s
iliapolo Oct 4, 2020
9240ea6
imports order
iliapolo Oct 5, 2020
1c897a1
integ
iliapolo Oct 5, 2020
3db119c
touchups
iliapolo Oct 6, 2020
aa2904e
remove misleading caveat
iliapolo Oct 6, 2020
01eb951
Merge branch 'master' into epolon/eks-cdk8s
iliapolo Oct 6, 2020
85efd7f
use 0.30.0 of cdk8s
iliapolo Oct 6, 2020
037b940
use 0.30.0 of cdk8s
iliapolo Oct 6, 2020
65f1045
review comments
iliapolo Oct 6, 2020
d243687
touchup
iliapolo Oct 6, 2020
3b34b82
Merge branch 'master' into epolon/eks-cdk8s
mergify[bot] Oct 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Table Of Contents
* [Applying Kubernetes Resources](#applying-kubernetes-resources)
* [Kubernetes Manifests](#kubernetes-manifests)
* [Helm Charts](#helm-charts)
* [CDK8s Charts](#cdk8s-charts)
* [Patching Kuberentes Resources](#patching-kubernetes-resources)
* [Querying Kubernetes Resources](#querying-kubernetes-resources)
* [Using existing clusters](#using-existing-clusters)
Expand Down Expand Up @@ -811,6 +812,135 @@ const chart2 = cluster.addHelmChart(...);
chart2.node.addDependency(chart1);
```

#### CDK8s Charts

[CDK8s](https://cdk8s.io/) is an open-source library that enables Kubernetes manifest authoring using familiar programming languages. It is founded on the same technologies as the AWS CDK, such as [`constructs`](https://github.com/aws/constructs) and [`jsii`](https://github.com/aws/jsii).

> To learn more about cdk8s, visit the [Getting Started](https://github.com/awslabs/cdk8s/tree/master/docs/getting-started) tutorials.

The EKS module natively integrates with cdk8s and allows you to apply cdk8s charts on AWS EKS clusters via the `cluster.addCdk8sChart` method.

In addition to `cdk8s`, you can also use [`cdk8s+`](https://github.com/awslabs/cdk8s/tree/master/packages/cdk8s-plus), which provides higher level abstraction for the core kubernetes api objects.
iliapolo marked this conversation as resolved.
Show resolved Hide resolved
You can think of it like the `L2` constructs for Kubernetes.

To get started, add the following dependencies to your `package.json` file:

```json
dependencies: {
"cdk8s": "0.30.0",
"cdk8s-plus": "0.30.0",
"constructs": "3.0.4",
}
iliapolo marked this conversation as resolved.
Show resolved Hide resolved
```

> Note that the version of `cdk8s` must be `>=0.30.0`.

We recommend to seperate the `cdk8s` charts to a different file and extend the `cdk8s.Chart` class.
iliapolo marked this conversation as resolved.
Show resolved Hide resolved
You can use `aws-cdk` construct attributes and properties inside your `cdk8s` construct freely.

In this example we create a chart that accepts an `s3.Bucket` and passes its name to a kubernetes pod as an environment variable.

```ts
import * as s3 from '@aws-cdk/aws-s3';
import * as constructs from 'constructs';
import * as cdk8s from 'cdk8s';
import * as kplus from 'cdk8s-plus';

export interface MyChartProps {

readonly bucket: s3.Bucket;
}
iliapolo marked this conversation as resolved.
Show resolved Hide resolved

export class MyChart extends cdk8s.Chart {
constructor(scope: constructs.Construct, id: string, props: MyChartProps} ) {
super(scope, id);

new kplus.Pod(this, 'Pod', {
spec: {
containers: [
new kplus.Container({
image: 'my-image',
env: {
BUCKET_NAME: bucket.bucketName,
}
})
]
}
});

iliapolo marked this conversation as resolved.
Show resolved Hide resolved
}
}
```

Then, in your cdk app:
iliapolo marked this conversation as resolved.
Show resolved Hide resolved

```ts
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk8s from 'cdk8s';
import { MyChart } from './my-chart'

// some bucket..
const bucket = new s3.Bucket(this, 'Bucket');

// create a cdk8s chart and use `cdk8s.App` as the scope.
const myChart = new MyChart(new cdk8s.App(), 'MyChart', { bucket });

// add the cdk8s chart to the cluster
cluster.addCdk8sChart('my-chart', myChart);
```

Note that at this moment, you cannot use AWS CDK constructs as scopes for CDK8s constructs, or vise versa.
This is why we use `new cdk8s.App()` as the scope of the chart itself.
iliapolo marked this conversation as resolved.
Show resolved Hide resolved

##### Custom CDK8s Constructs
iliapolo marked this conversation as resolved.
Show resolved Hide resolved

You can also compose a few stock `cdk8s+` constructs into your own custom construct. However, since mixing scopes between `aws-cdk` and `cdk8s` is currently not supported, the `Construct` class
you'll need to use is the one from the [`constructs`](https://github.com/aws/constructs) module, and not from `@aws-cdk/core` like you normally would.
This is why we used `new cdk8s.App()` as the scope of the chart above.

```ts
import * as constructs from 'constructs';
import * as cdk8s from 'cdk8s';
import * as kplus from 'cdk8s-plus';

export interface LoadBalancedWebService {
readonly port: number;
readonly image: string;
readonly replicas: number;
}

export class LoadBalancedWebService extends constructs.Construct {
constructor(scope: constructs.Construct, id: string, props: LoadBalancedWebService) {
super(scope, id);

const deployment = new kplus.Deployment(chart, 'Deployment', {
spec: {
replicas: props.replicas,
podSpecTemplate: {
containers: [ new kplus.Container({ image: props.image }) ]
}
},
});

deployment.expose({port: props.port, serviceType: kplus.ServiceType.LOAD_BALANCER})

}
}
```

##### Caveat

`cdk8s+` is vended with a static version of the kubernetes API spec. See ...

At the moment, there is no way to control which spec version `cdk8s+` uses, so if you need other versions, please refer to [Manual importing](#manually-importing-k8s-specs-and-crds) below.
This would unfortunately mean you won't be able to utilize `cdk8s+` capabilities.

##### Manually importing k8s specs and CRD's

If you find yourself unable to use `cdk8s+`, or just like to directly use the `k8s` native objects or CRD's, you can do so by manually importing them using the `cdk8s-cli`.

See [Importing kubernetes objects](https://github.com/awslabs/cdk8s/tree/master/packages/cdk8s-cli#import) for detailed instructions.

## Patching Kubernetes Resources

The `KubernetesPatch` construct can be used to update existing kubernetes
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-eks/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as kms from '@aws-cdk/aws-kms';
import * as lambda from '@aws-cdk/aws-lambda';
import * as ssm from '@aws-cdk/aws-ssm';
import { Annotations, CfnOutput, CfnResource, IResource, Resource, Stack, Tags, Token, Duration } from '@aws-cdk/core';
import * as cdk8s from 'cdk8s';
import { Construct, Node } from 'constructs';
import * as YAML from 'yaml';
import { AwsAuth } from './aws-auth';
Expand Down Expand Up @@ -132,6 +133,16 @@ export interface ICluster extends IResource, ec2.IConnectable {
* @returns a `HelmChart` construct
*/
addHelmChart(id: string, options: HelmChartOptions): HelmChart;

/**
* Defines a CDK8s chart in this cluster.
*
* @param id logical id of this chart.
* @param chart the cdk8s chart.
* @returns a `KubernetesManifest` construct representing the chart.
*/
addCdk8sChart(id: string, chart: cdk8s.Chart): KubernetesManifest;

}

/**
Expand Down Expand Up @@ -617,6 +628,17 @@ abstract class ClusterBase extends Resource implements ICluster {
public addHelmChart(id: string, options: HelmChartOptions): HelmChart {
return new HelmChart(this, `chart-${id}`, { cluster: this, ...options });
}

/**
* Defines a CDK8s chart in this cluster.
*
* @param id logical id of this chart.
* @param chart the cdk8s chart.
* @returns a `KubernetesManifest` construct representing the chart.
*/
public addCdk8sChart(id: string, chart: cdk8s.Chart): KubernetesManifest {
return this.addManifest(id, ...chart.toJson());
iliapolo marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
Expand Down
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-eks/lib/legacy-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as ec2 from '@aws-cdk/aws-ec2';
import * as iam from '@aws-cdk/aws-iam';
import * as kms from '@aws-cdk/aws-kms';
import * as ssm from '@aws-cdk/aws-ssm';
import * as cdk8s from 'cdk8s';
import { Annotations, CfnOutput, Resource, Stack, Token, Tags } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { ICluster, ClusterAttributes, KubernetesVersion, NodeType, DefaultCapacityType, EksOptimizedImage, AutoScalingGroupCapacityOptions, MachineImageType, AutoScalingGroupOptions, CommonClusterOptions } from './cluster';
Expand Down Expand Up @@ -371,6 +372,10 @@ export class LegacyCluster extends Resource implements ICluster {
throw new Error('legacy cluster does not support adding helm charts');
}

public addCdk8sChart(_id: string, _chart: cdk8s.Chart): KubernetesManifest {
throw new Error('legacy cluster does not support adding cdk8s charts');
}

/**
* Opportunistically tag subnets with the required tags.
*
Expand Down Expand Up @@ -429,6 +434,10 @@ class ImportedCluster extends Resource implements ICluster {
throw new Error('legacy cluster does not support adding helm charts');
}

public addCdk8sChart(_id: string, _chart: cdk8s.Chart): KubernetesManifest {
throw new Error('legacy cluster does not support adding cdk8s charts');
}

public get vpc() {
if (!this.props.vpc) {
throw new Error('"vpc" is not defined for this imported cluster');
Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-eks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@
"cfn2ts": "0.0.0",
"nodeunit": "^0.11.3",
"pkglint": "0.0.0",
"sinon": "^9.1.0"
"sinon": "^9.1.0",
"cdk8s-plus": "^0.29.0"
},
"dependencies": {
"@aws-cdk/aws-autoscaling": "0.0.0",
Expand All @@ -90,6 +91,7 @@
"@aws-cdk/aws-ssm": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-cdk/custom-resources": "0.0.0",
"cdk8s": "^0.29.0",
"constructs": "^3.0.4",
"yaml": "1.10.0"
},
Expand All @@ -106,6 +108,7 @@
"@aws-cdk/aws-ssm": "0.0.0",
"@aws-cdk/core": "0.0.0",
"@aws-cdk/custom-resources": "0.0.0",
"cdk8s": "^0.29.0",
"constructs": "^3.0.4"
},
"engines": {
Expand Down
Loading