Skip to content

Commit

Permalink
feat(eks): option to disable manifest validation (aws#12012)
Browse files Browse the repository at this point in the history
Closes aws#11763

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
ayush987goyal authored and flochaz committed Jan 5, 2021
1 parent ba7b2f3 commit c20afe7
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 25 deletions.
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,19 @@ new Cluster(this, 'MyCluster', {
});
```

#### Manifests Validation

The `kubectl` CLI supports applying a manifest by skipping the validation.
This can be accomplished by setting the `skipValidation` flag to `true` in the `KubernetesManifest` props.

```ts
new eks.KubernetesManifest(this, 'HelloAppWithoutValidation', {
cluster: this.cluster,
manifest: [ deployment, service ],
skipValidation: true,
});
```

### Helm Charts

The `HelmChart` construct or `cluster.addHelmChart` method can be used
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-eks/lib/k8s-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ export interface KubernetesManifestOptions {
* otherwise specified.
*/
readonly prune?: boolean;

/**
* A flag to signify if the manifest validation should be skipped
*
* @default false
*/
readonly skipValidation?: boolean;
}

/**
Expand Down Expand Up @@ -122,6 +129,7 @@ export class KubernetesManifest extends CoreConstruct {
RoleArn: provider.roleArn, // TODO: bake into provider's environment
PruneLabel: pruneLabel,
Overwrite: props.overwrite,
SkipValidation: props.skipValidation,
},
});
}
Expand Down
18 changes: 12 additions & 6 deletions packages/@aws-cdk/aws-eks/lib/kubectl-handler/apply/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def apply_handler(event, context):
manifest_text = props['Manifest']
role_arn = props['RoleArn']
prune_label = props.get('PruneLabel', None)
overwrite = props.get('Overwrite', False)
overwrite = props.get('Overwrite', 'false').lower() == 'true'
skip_validation = props.get('SkipValidation', 'false').lower() == 'true'

# "log in" to the cluster
cmd = [ 'aws', 'eks', 'update-kubeconfig',
Expand All @@ -43,20 +44,25 @@ def apply_handler(event, context):

logger.info("manifest written to: %s" % manifest_file)

kubectl_opts = []
if skip_validation:
kubectl_opts.extend(['--validate=false'])

if request_type == 'Create':
# if "overwrite" is enabled, then we use "apply" for CREATE operations
# which technically means we can determine the desired state of an
# existing resource.
if overwrite:
kubectl('apply', manifest_file)
kubectl('apply', manifest_file, *kubectl_opts)
else:
# --save-config will allow us to use "apply" later
kubectl('create', manifest_file, '--save-config')
kubectl_opts.extend(['--save-config'])
kubectl('create', manifest_file, *kubectl_opts)
elif request_type == 'Update':
opts = []
if prune_label is not None:
opts = ['--prune', '-l', prune_label]
kubectl('apply', manifest_file, *opts)
kubectl_opts.extend(['--prune', '-l', prune_label])

kubectl('apply', manifest_file, *kubectl_opts)
elif request_type == "Delete":
try:
kubectl('delete', manifest_file)
Expand Down
66 changes: 47 additions & 19 deletions packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -3867,7 +3867,7 @@
},
"/",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3BucketBE7D619F"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3Bucket133A4850"
},
"/",
{
Expand All @@ -3877,7 +3877,7 @@
"Fn::Split": [
"||",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3VersionKeyB0752C6A"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70"
}
]
}
Expand All @@ -3890,7 +3890,7 @@
"Fn::Split": [
"||",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3VersionKeyB0752C6A"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70"
}
]
}
Expand All @@ -3912,11 +3912,11 @@
"Arn"
]
},
"referencetoawscdkeksclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3Bucket13E8DC72Ref": {
"Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3BucketD473D2B6"
"referencetoawscdkeksclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket174F3576Ref": {
"Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35"
},
"referencetoawscdkeksclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKeyEDAB3239Ref": {
"Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKey8213FD47"
"referencetoawscdkeksclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKeyE8595856Ref": {
"Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0"
},
"referencetoawscdkeksclustertestVpcPrivateSubnet1Subnet32A4EC2ARef": {
"Ref": "VpcPrivateSubnet1Subnet536B997A"
Expand Down Expand Up @@ -3969,6 +3969,34 @@
}
}
},
"HelloAppWithoutValidation7C638ACB": {
"Type": "Custom::AWSCDK-EKS-KubernetesResource",
"Properties": {
"ServiceToken": {
"Fn::GetAtt": [
"awscdkawseksKubectlProviderNestedStackawscdkawseksKubectlProviderNestedStackResourceA7AEBA6B",
"Outputs.awscdkeksclustertestawscdkawseksKubectlProviderframeworkonEventC681B49AArn"
]
},
"Manifest": "[{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"data\":{\"hello\":\"world\"},\"metadata\":{\"name\":\"config-map\",\"labels\":{\"aws.cdk.eks/prune-c89cbcc5d9bdd35cfc69c0334c0a9af21d1e0e372e\":\"\"}},\"unknown\":{\"key\":\"value\"}}]",
"ClusterName": {
"Ref": "Cluster9EE0221C"
},
"RoleArn": {
"Fn::GetAtt": [
"ClusterCreationRole360249B6",
"Arn"
]
},
"PruneLabel": "aws.cdk.eks/prune-c89cbcc5d9bdd35cfc69c0334c0a9af21d1e0e372e",
"SkipValidation": true
},
"DependsOn": [
"ClusterKubectlReadyBarrier200052AF"
],
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"CustomAWSCDKOpenIdConnectProviderCustomResourceProviderRole517FED65": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -4575,17 +4603,17 @@
"Type": "String",
"Description": "Artifact hash for asset \"daeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1\""
},
"AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3BucketD473D2B6": {
"AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35": {
"Type": "String",
"Description": "S3 bucket for asset \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\""
"Description": "S3 bucket for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\""
},
"AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKey8213FD47": {
"AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0": {
"Type": "String",
"Description": "S3 key for asset version \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\""
"Description": "S3 key for asset version \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\""
},
"AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cArtifactHashDEE5AB5C": {
"AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757ArtifactHashF584A7D8": {
"Type": "String",
"Description": "Artifact hash for asset \"e4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6c\""
"Description": "Artifact hash for asset \"bafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757\""
},
"AssetParametersb075459e6bf309093fbd4b9a9e576a5f172b91c14d84eedb0f069566f6abb0deS3Bucket14156880": {
"Type": "String",
Expand Down Expand Up @@ -4635,17 +4663,17 @@
"Type": "String",
"Description": "Artifact hash for asset \"a69aadbed84d554dd9f2eb7987ffe5d8f76b53a86f1909059df07050e57bef0c\""
},
"AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3BucketBE7D619F": {
"AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3Bucket133A4850": {
"Type": "String",
"Description": "S3 bucket for asset \"9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2\""
"Description": "S3 bucket for asset \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\""
},
"AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3VersionKeyB0752C6A": {
"AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70": {
"Type": "String",
"Description": "S3 key for asset version \"9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2\""
"Description": "S3 key for asset version \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\""
},
"AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2ArtifactHash332C2FA3": {
"AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dArtifactHash7484ACD9": {
"Type": "String",
"Description": "Artifact hash for asset \"9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2\""
"Description": "Artifact hash for asset \"c73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09d\""
},
"SsmParameterValueawsserviceeksoptimizedami118amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": {
"Type": "AWS::SSM::Parameter::Value<String>",
Expand Down
16 changes: 16 additions & 0 deletions packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class EksClusterStack extends TestStack {

this.assertSimpleManifest();

this.assertManifestWithoutValidation();

this.assertSimpleHelmChart();

this.assertSimpleCdk8sChart();
Expand Down Expand Up @@ -137,6 +139,20 @@ class EksClusterStack extends TestStack {
// apply a kubernetes manifest
this.cluster.addManifest('HelloApp', ...hello.resources);
}
private assertManifestWithoutValidation() {
// apply a kubernetes manifest
new eks.KubernetesManifest(this, 'HelloAppWithoutValidation', {
cluster: this.cluster,
manifest: [{
apiVersion: 'v1',
kind: 'ConfigMap',
data: { hello: 'world' },
metadata: { name: 'config-map' },
unknown: { key: 'value' },
}],
skipValidation: true,
});
}
private assertNodeGroupX86() {
// add a extra nodegroup
this.cluster.addNodegroupCapacity('extra-ng', {
Expand Down

0 comments on commit c20afe7

Please sign in to comment.