Skip to content

Commit

Permalink
Merge branch 'master' into pahud/aws-eks-managed-nodegroup-11827
Browse files Browse the repository at this point in the history
  • Loading branch information
iliapolo committed Dec 22, 2020
2 parents 6104476 + 579b923 commit 394cefe
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 31 deletions.
34 changes: 28 additions & 6 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ export class Project extends ProjectBase {
this.projectName = this.getResourceNameAttribute(resource.ref);

this.addToRolePolicy(this.createLoggingPermission());
this.addParameterStorePermission(props);
this.addEnvVariablesPermissions(props.environmentVariables);
// add permissions to create and use test report groups
// with names starting with the project's name,
// unless the customer explicitly opts out of it
Expand Down Expand Up @@ -922,12 +922,13 @@ export class Project extends ProjectBase {
});
}

private addParameterStorePermission(props: ProjectProps) {
if (!props.environmentVariables) {
return;
}
private addEnvVariablesPermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
this.addParameterStorePermissions(environmentVariables);
this.addSecretsManagerPermissions(environmentVariables);
}

const resources = Object.values(props.environmentVariables)
private addParameterStorePermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
const resources = Object.values(environmentVariables || {})
.filter(envVariable => envVariable.type === BuildEnvironmentVariableType.PARAMETER_STORE)
.map(envVariable =>
// If the parameter name starts with / the resource name is not separated with a double '/'
Expand All @@ -951,6 +952,27 @@ export class Project extends ProjectBase {
}));
}

private addSecretsManagerPermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
const resources = Object.values(environmentVariables || {})
.filter(envVariable => envVariable.type === BuildEnvironmentVariableType.SECRETS_MANAGER)
.map(envVariable => Stack.of(this).formatArn({
service: 'secretsmanager',
resource: 'secret',
// we don't know the exact ARN of the Secret just from its name, but we can get close
resourceName: `${envVariable.value}-??????`,
sep: ':',
}));

if (resources.length === 0) {
return;
}

this.addToRolePolicy(new iam.PolicyStatement({
actions: ['secretsmanager:GetSecretValue'],
resources,
}));
}

private renderEnvironment(
env: BuildEnvironment = {},
projectVars: { [name: string]: BuildEnvironmentVariable } = {}): CfnProject.EnvironmentProperty {
Expand Down
38 changes: 38 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/test.project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -889,5 +889,43 @@ export = {

test.done();
},

"grants the Project's Role read permissions to the SecretsManager environment variables"(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.PipelineProject(stack, 'Project', {
environmentVariables: {
'ENV_VAR1': {
type: codebuild.BuildEnvironmentVariableType.SECRETS_MANAGER,
value: 'my-secret',
},
},
});

// THEN
expect(stack).to(haveResourceLike('AWS::IAM::Policy', {
'PolicyDocument': {
'Statement': arrayWith({
'Action': 'secretsmanager:GetSecretValue',
'Effect': 'Allow',
'Resource': {
'Fn::Join': ['', [
'arn:',
{ Ref: 'AWS::Partition' },
':secretsmanager:',
{ Ref: 'AWS::Region' },
':',
{ Ref: 'AWS::AccountId' },
':secret:my-secret-??????',
]],
},
}),
},
}));

test.done();
},
},
};
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 @@ -879,6 +879,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 @@ -3977,7 +3977,7 @@
},
"/",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3BucketBE7D619F"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3Bucket133A4850"
},
"/",
{
Expand All @@ -3987,7 +3987,7 @@
"Fn::Split": [
"||",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3VersionKeyB0752C6A"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70"
}
]
}
Expand All @@ -4000,7 +4000,7 @@
"Fn::Split": [
"||",
{
"Ref": "AssetParameters9a25dd6d9e57e25d745576dc7750da1634d4b890ca4f11546b8c1cf5411957c2S3VersionKeyB0752C6A"
"Ref": "AssetParametersc73abc34737d53a79bc2f339e8ae561af314b1fc67c51905129dcec3771ba09dS3VersionKeyC4C77F70"
}
]
}
Expand All @@ -4022,11 +4022,11 @@
"Arn"
]
},
"referencetoawscdkeksclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3Bucket13E8DC72Ref": {
"Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3BucketD473D2B6"
"referencetoawscdkeksclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket174F3576Ref": {
"Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3Bucket008DBB35"
},
"referencetoawscdkeksclustertestAssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKeyEDAB3239Ref": {
"Ref": "AssetParameterse4ce1c625ef8590bc63f26160777b1c74421c8f5290dc5d15227810eedff2e6cS3VersionKey8213FD47"
"referencetoawscdkeksclustertestAssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKeyE8595856Ref": {
"Ref": "AssetParametersbafd50ae9f214e496ff8c72c6425f93dca3ccd590e20963706d5d610d9c75757S3VersionKey97C3E1A0"
},
"referencetoawscdkeksclustertestVpcPrivateSubnet1Subnet32A4EC2ARef": {
"Ref": "VpcPrivateSubnet1Subnet536B997A"
Expand Down Expand Up @@ -4079,6 +4079,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 @@ -4685,17 +4713,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 @@ -4745,17 +4773,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 @@ -61,6 +61,8 @@ class EksClusterStack extends TestStack {

this.assertSimpleManifest();

this.assertManifestWithoutValidation();

this.assertSimpleHelmChart();

this.assertSimpleCdk8sChart();
Expand Down Expand Up @@ -139,6 +141,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 394cefe

Please sign in to comment.