diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index fb70871bfe8e..69aae3320d05 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -341,6 +341,38 @@ CDK. This means that if the resource is deleted from your code (or the stack is deleted), the next `cdk deploy` will issue a `kubectl delete` command and the Kubernetes resources will be deleted. +#### Dependencies + +There are cases where Kubernetes resources must be deployed in a specific order. +For example, you cannot define a resource in a Kubernetes namespace before the +namespace was created. + +You can represent dependencies between `KubernetesResource`s using +`resource.node.addDependency()`: + +```ts +const namespace = cluster.addResource('my-namespace', { + apiVersion: 'v1', + kind: 'Namespace', + metadata: { name: 'my-app' } +}); + +const service = cluster.addResource('my-service', { + metadata: { + name: 'myservice', + namespace: 'my-app' + }, + spec: // ... +}); + +service.node.addDependency(namespace); // will apply `my-namespace` before `my-service`. +``` + +NOTE: when a `KubernetesResource` includes multiple resources (either directly +or through `cluster.addResource()`) (e.g. `cluster.addResource('foo', r1, r2, +r3,...))`), these resources will be applied as a single manifest via `kubectl` +and will be applied sequentially (the standard behavior in `kubectl`). + ### Patching Kubernetes Resources The KubernetesPatch construct can be used to update existing kubernetes @@ -524,8 +556,20 @@ deleted), the next `cdk deploy` will issue a `helm uninstall` command and the Helm chart will be deleted. When there is no `release` defined, the chart will be installed using the `node.uniqueId`, -which will be lower cassed and truncated to the last 63 characters. +which will be lower cased and truncated to the last 63 characters. +By default, all Helm charts will be installed concurrently. In some cases, this +could cause race conditions where two Helm charts attempt to deploy the same +resource or if Helm charts depend on each other. You can use +`chart.node.addDependency()` in order to declare a dependency order between +charts: + +```ts +const chart1 = cluster.addChart(...); +const chart2 = cluster.addChart(...); + +chart2.node.addDependency(chart1); +``` ### Bottlerocket diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index 0329b152b426..dfe7768ca82a 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -2361,6 +2361,29 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "ClustermanifestnginxnamespaceA68B4CE0": { + "Type": "Custom::AWSCDK-EKS-KubernetesResource", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B", + "Outputs.awscdkeksclustertestawscdkawseksKubectlProviderframeworkonEventC681B49AArn" + ] + }, + "Manifest": "[{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"name\":\"nginx\"}}]", + "ClusterName": { + "Ref": "Cluster9EE0221C" + }, + "RoleArn": { + "Fn::GetAtt": [ + "ClusterCreationRole360249B6", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, "Clusterchartnginxingress1193EC3F": { "Type": "Custom::AWSCDK-EKS-HelmChart", "Properties": { @@ -2383,10 +2406,12 @@ "Chart": "nginx-ingress", "Wait": true, "Timeout": "900s", - "Namespace": "kube-system", - "Repository": "https://helm.nginx.com/stable", - "CreateNamespace": true + "Namespace": "nginx", + "Repository": "https://helm.nginx.com/stable" }, + "DependsOn": [ + "ClustermanifestnginxnamespaceA68B4CE0" + ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index ddee987d81d3..b2e1e1242cad 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -72,20 +72,34 @@ class EksClusterStack extends TestStack { // apply a kubernetes manifest cluster.addResource('HelloApp', ...hello.resources); - // add two Helm charts to the cluster. This will be the Kubernetes dashboard and the Nginx Ingress Controller + // deploy the Kubernetes dashboard through a helm chart cluster.addChart('dashboard', { chart: 'kubernetes-dashboard', repository: 'https://kubernetes.github.io/dashboard/', }); - cluster.addChart('nginx-ingress', { + // deploy an nginx ingress in a namespace + + const nginxNamespace = cluster.addResource('nginx-namespace', { + apiVersion: 'v1', + kind: 'Namespace', + metadata: { + name: 'nginx', + }, + }); + + const nginxIngress = cluster.addChart('nginx-ingress', { chart: 'nginx-ingress', repository: 'https://helm.nginx.com/stable', - namespace: 'kube-system', + namespace: 'nginx', wait: true, + createNamespace: false, timeout: Duration.minutes(15), }); + // make sure namespace is deployed before the chart + nginxIngress.node.addDependency(nginxNamespace); + // add a service account connected to a IAM role cluster.addServiceAccount('MyServiceAccount');