Skip to content

Commit

Permalink
Merge branch 'master' into njlynch/rds-secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Sep 23, 2020
2 parents 53d950a + c179699 commit 4ec1c28
Show file tree
Hide file tree
Showing 19 changed files with 144 additions and 74 deletions.
68 changes: 34 additions & 34 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ cluster.addManifest('mypod', {
});
```

> **NOTE: You can only create 1 cluster per stack.** If you have a use-case for multiple clusters per stack, > or would like to understand more about this limitation, see https://github.com/aws/aws-cdk/issues/10073.
In order to interact with your cluster through `kubectl`, you can use the `aws
eks update-kubeconfig` [AWS CLI command](https://docs.aws.amazon.com/cli/latest/reference/eks/update-kubeconfig.html)
to configure your local kubeconfig.
Expand Down Expand Up @@ -98,7 +100,8 @@ const cluster = new eks.Cluster(this, 'hello-eks', {
});
```

The default value is `eks.EndpointAccess.PUBLIC_AND_PRIVATE`. Which means the cluster endpoint is accessible from outside of your VPC, and worker node traffic to the endpoint will stay within your VPC.
The default value is `eks.EndpointAccess.PUBLIC_AND_PRIVATE`. Which means the cluster endpoint is accessible from outside of your VPC, but worker node traffic as well as `kubectl` commands
to the endpoint will stay within your VPC.

### Capacity

Expand Down Expand Up @@ -139,16 +142,12 @@ new eks.Cluster(this, 'cluster-with-no-capacity', {
});
```

The `cluster.defaultCapacity` property will reference the `AutoScalingGroup`
resource for the default capacity. It will be `undefined` if `defaultCapacity`
is set to `0` or `defaultCapacityType` is either `NODEGROUP` or undefined.
When creating a cluster with default capacity (i.e `defaultCapacity !== 0` or is undefined), you can access the allocated capacity using:

And the `cluster.defaultNodegroup` property will reference the `Nodegroup`
resource for the default capacity. It will be `undefined` if `defaultCapacity`
is set to `0` or `defaultCapacityType` is `EC2`.
- `cluster.defaultCapacity` will reference the `AutoScalingGroup` resource in case `defaultCapacityType` is set to `EC2` or is undefined.
- `cluster.defaultNodegroup` will reference the `Nodegroup` resource in case `defaultCapacityType` is set to `NODEGROUP`.

You can add `AutoScalingGroup` resource as customized capacity through `cluster.addCapacity()` or
`cluster.addAutoScalingGroup()`:
You can add customized capacity in the form of an `AutoScalingGroup` resource through `cluster.addCapacity()` or `cluster.addAutoScalingGroup()`:

```ts
cluster.addCapacity('frontend-nodes', {
Expand All @@ -167,7 +166,7 @@ for Amazon EKS Kubernetes clusters. By default, `eks.Nodegroup` create a nodegro
new eks.Nodegroup(stack, 'nodegroup', { cluster });
```

You can add customized node group through `cluster.addNodegroup()`:
You can add customized node groups through `cluster.addNodegroup()`:

```ts
cluster.addNodegroup('nodegroup', {
Expand Down Expand Up @@ -206,14 +205,13 @@ this.cluster.addNodegroup('extra-ng', {

### ARM64 Support

Instance types with `ARM64` architecture are supported in both managed nodegroup and self-managed capacity. Simply specify an ARM64 `instanceType` (such as `m6g.medium`), and the latest
Instance types with `ARM64` architecture are supported in both managed nodegroup and self-managed capacity. Simply specify an ARM64 `instanceType` (such as `m6g.medium`), and the latest
Amazon Linux 2 AMI for ARM64 will be automatically selected.

```ts
// create a cluster with a default managed nodegroup
// create a cluster with a default managed nodegroup
cluster = new eks.Cluster(this, 'Cluster', {
vpc,
mastersRole,
version: eks.KubernetesVersion.V1_17,
});

Expand Down Expand Up @@ -298,12 +296,9 @@ can cause your EC2 instance to become unavailable, such as [EC2 maintenance even
and [EC2 Spot interruptions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html) and helps gracefully stop all pods running on spot nodes that are about to be
terminated.

Current version:

| name | version |
|------------|---------|
| Helm Chart | 0.9.5 |
| App | 1.7.0 |
> Handler Version: [1.7.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.7.0)
>
> Chart Version: [0.9.5](https://github.com/aws/eks-charts/blob/v0.0.28/stable/aws-node-termination-handler/Chart.yaml)
### Bootstrapping

Expand All @@ -327,7 +322,7 @@ cluster.addCapacity('spot', {
To disable bootstrapping altogether (i.e. to fully customize user-data), set `bootstrapEnabled` to `false` when you add
the capacity.

### Kubernetes Resources
### Kubernetes Manifests

The `KubernetesManifest` construct or `cluster.addManifest` method can be used
to apply Kubernetes resource manifests to this cluster.
Expand Down Expand Up @@ -387,7 +382,7 @@ cluster.addManifest('hello-kub', service, deployment);

#### Kubectl Layer and Environment

The resources are created in the cluster by running `kubectl apply` from a python lambda function. You can configure the environment of this function by specifying it at cluster instantiation. For example, this can useful in order to configure an http proxy:
The resources are created in the cluster by running `kubectl apply` from a python lambda function. You can configure the environment of this function by specifying it at cluster instantiation. For example, this can be useful in order to configure an http proxy:

```typescript
const cluster = new eks.Cluster(this, 'hello-eks', {
Expand Down Expand Up @@ -450,10 +445,14 @@ const manifest = yaml.safeLoadAll(request('GET', manifestUrl).getBody());
cluster.addManifest('my-resource', ...manifest);
```

Since Kubernetes resources are implemented as CloudFormation resources in the
CDK. This means that if the resource is deleted from your code (or the stack is
Since Kubernetes manifests are implemented as CloudFormation resources in the
CDK. This means that if the manifest 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.
Kubernetes resources in that manifest will be deleted.

#### Caveat

If you have multiple resources in a single `KubernetesManifest`, and one of those **resources** is removed from the manifest, it will not be deleted and will remain orphan. See [Support Object pruning](https://github.com/aws/aws-cdk/issues/10495) for more details.

#### Dependencies

Expand Down Expand Up @@ -482,9 +481,9 @@ const service = cluster.addManifest('my-service', {
service.node.addDependency(namespace); // will apply `my-namespace` before `my-service`.
```

NOTE: when a `KubernetesManifest` includes multiple resources (either directly
**NOTE:** when a `KubernetesManifest` includes multiple resources (either directly
or through `cluster.addManifest()`) (e.g. `cluster.addManifest('foo', r1, r2,
r3,...))`), these resources will be applied as a single manifest via `kubectl`
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
Expand Down Expand Up @@ -582,7 +581,7 @@ If the cluster is configured with private-only or private and restricted public
Kubernetes [endpoint access](#endpoint-access), you must also specify:

- `kubectlSecurityGroupId` - the ID of an EC2 security group that is allowed
connections to the cluster's control security group.
connections to the cluster's control security group. For example, the EKS managed [cluster security group](#cluster-security-group).
- `kubectlPrivateSubnetIds` - a list of private VPC subnets IDs that will be used
to access the Kubernetes endpoint.

Expand All @@ -598,7 +597,7 @@ users, roles and accounts.
Furthermore, when auto-scaling capacity is added to the cluster (through
`cluster.addCapacity` or `cluster.addAutoScalingGroup`), the IAM instance role
of the auto-scaling group will be automatically mapped to RBAC so nodes can
connect to the cluster. No manual mapping is required any longer.
connect to the cluster. No manual mapping is required.

For example, let's say you want to grant an IAM user administrative privileges
on your cluster:
Expand Down Expand Up @@ -657,11 +656,10 @@ const clusterEncryptionConfigKeyArn = cluster.clusterEncryptionConfigKeyArn;
### Node ssh Access

If you want to be able to SSH into your worker nodes, you must already
have an SSH key in the region you're connecting to and pass it, and you must
be able to connect to the hosts (meaning they must have a public IP and you
have an SSH key in the region you're connecting to and pass it when you add capacity to the cluster. You must also be able to connect to the hosts (meaning they must have a public IP and you
should be allowed to connect to them on port 22):

[ssh into nodes example](test/example.ssh-into-nodes.lit.ts)
See [SSH into nodes](test/example.ssh-into-nodes.lit.ts) for a code example.

If you want to SSH into nodes in a private subnet, you should set up a
bastion host in a public subnet. That setup is recommended, but is
Expand Down Expand Up @@ -699,7 +697,7 @@ cluster.addChart('NginxIngress', {
Helm charts will be installed and updated using `helm upgrade --install`, where a few parameters
are being passed down (such as `repo`, `values`, `version`, `namespace`, `wait`, `timeout`, etc).
This means that if the chart is added to CDK with the same release name, it will try to update
the chart in the cluster. The chart will exists as CloudFormation resource.
the chart in the cluster.

Helm charts are implemented as CloudFormation resources in CDK.
This means that if the chart is deleted from your code (or the stack is
Expand Down Expand Up @@ -775,9 +773,11 @@ const mypod = cluster.addManifest('mypod', {
}
});

// create the resource after the service account
// create the resource after the service account.
// note that using `sa.serviceAccountName` above **does not** translate into a dependency.
// this is why an explicit dependency is needed. See https://github.com/aws/aws-cdk/issues/9910 for more details.
mypod.node.addDependency(sa);

// print the IAM role arn for this service account
new cdk.CfnOutput(this, 'ServiceAccountIamRole', { value: sa.role.roleArn })
```
```
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-s3/lib/bucket-policy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PolicyDocument } from '@aws-cdk/aws-iam';
import { Construct, RemovalPolicy, Resource } from '@aws-cdk/core';
import { RemovalPolicy, Resource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { IBucket } from './bucket';
import { CfnBucketPolicy } from './s3.generated';

Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { EOL } from 'os';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import * as kms from '@aws-cdk/aws-kms';
import { Construct, Fn, IResource, Lazy, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
import { Fn, IResource, Lazy, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { BucketPolicy } from './bucket-policy';
import { IBucketNotificationDestination } from './destination';
import { BucketNotifications } from './notifications-resource';
Expand Down
5 changes: 3 additions & 2 deletions packages/@aws-cdk/aws-s3/lib/util.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as cdk from '@aws-cdk/core';
import { IConstruct } from 'constructs';
import { BucketAttributes } from './bucket';

export function parseBucketArn(construct: cdk.IConstruct, props: BucketAttributes): string {
export function parseBucketArn(construct: IConstruct, props: BucketAttributes): string {

// if we have an explicit bucket ARN, use it.
if (props.bucketArn) {
Expand All @@ -22,7 +23,7 @@ export function parseBucketArn(construct: cdk.IConstruct, props: BucketAttribute
throw new Error('Cannot determine bucket ARN. At least `bucketArn` or `bucketName` is needed');
}

export function parseBucketName(construct: cdk.IConstruct, props: BucketAttributes): string | undefined {
export function parseBucketName(construct: IConstruct, props: BucketAttributes): string | undefined {

// if we have an explicit bucket name, use it.
if (props.bucketName) {
Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
"compat": "cdk-compat"
},
"cdk-build": {
"cloudformation": "AWS::S3"
"cloudformation": "AWS::S3",
"env": {
"AWSLINT_BASE_CONSTRUCT": "true"
}
},
"keywords": [
"aws",
Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-s3/test/test.aspect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// import { expect, haveResource, haveResourceLike, SynthUtils } from '@aws-cdk/assert';
import { SynthUtils } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import { IConstruct } from 'constructs';
import { Test } from 'nodeunit';
import * as s3 from '../lib';

Expand Down Expand Up @@ -40,7 +41,7 @@ export = {
};

class BucketVersioningChecker implements cdk.IAspect {
public visit(node: cdk.IConstruct): void {
public visit(node: IConstruct): void {
if (node instanceof s3.CfnBucket) {
if (!node.versioningConfiguration ||
(!cdk.Tokenization.isResolvable(node.versioningConfiguration) && node.versioningConfiguration.status !== 'Enabled')) {
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/core/lib/construct-compat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class Construct extends constructs.Construct implements IConstruct {
*/
public readonly node: ConstructNode;

constructor(scope: Construct, id: string) {
constructor(scope: constructs.Construct, id: string) {
super(scope, id, {
nodeFactory: {
createNode: (h: constructs.Construct, s: constructs.IConstruct, i: string) =>
Expand Down
7 changes: 4 additions & 3 deletions packages/@aws-cdk/core/lib/private/physical-name-generator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as crypto from 'crypto';
import { Node } from 'constructs';
import { IResolvable, IResolveContext } from '../resolvable';
import { IResource } from '../resource';
import { Stack } from '../stack';
Expand All @@ -8,16 +9,16 @@ import { TokenMap } from './token-map';
export function generatePhysicalName(resource: IResource): string {
const stack = Stack.of(resource);
const stackPart = new PrefixNamePart(stack.stackName, 25);
const idPart = new SuffixNamePart(resource.node.uniqueId, 24);
const idPart = new SuffixNamePart(Node.of(resource).uniqueId, 24);

const region: string = stack.region;
if (Token.isUnresolved(region) || !region) {
throw new Error(`Cannot generate a physical name for ${resource.node.path}, because the region is un-resolved or missing`);
throw new Error(`Cannot generate a physical name for ${Node.of(resource).path}, because the region is un-resolved or missing`);
}

const account: string = stack.account;
if (Token.isUnresolved(account) || !account) {
throw new Error(`Cannot generate a physical name for ${resource.node.path}, because the account is un-resolved or missing`);
throw new Error(`Cannot generate a physical name for ${Node.of(resource).path}, because the account is un-resolved or missing`);
}

const parts = [stackPart, idPart]
Expand Down
5 changes: 3 additions & 2 deletions packages/@aws-cdk/core/lib/resource.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Construct } from 'constructs';
import { ArnComponents } from './arn';
import { Construct, IConstruct } from './construct-compat';
import { IConstruct, Construct as CoreConstruct } from './construct-compat';
import { Lazy } from './lazy';
import { generatePhysicalName, isGeneratedWhenNeededMarker } from './private/physical-name-generator';
import { IResolveContext } from './resolvable';
Expand Down Expand Up @@ -86,7 +87,7 @@ export interface ResourceProps {
/**
* A construct which represents an AWS resource.
*/
export abstract class Resource extends Construct implements IResource {
export abstract class Resource extends CoreConstruct implements IResource {
public readonly stack: Stack;
public readonly env: ResourceEnvironment;

Expand Down
16 changes: 9 additions & 7 deletions packages/@aws-cdk/core/lib/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as fs from 'fs';
import * as path from 'path';
import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import * as cxapi from '@aws-cdk/cx-api';
import { IConstruct, Node } from 'constructs';
import { Annotations } from './annotations';
import { App } from './app';
import { Arn, ArnComponents } from './arn';
Expand All @@ -10,7 +11,7 @@ import { CfnElement } from './cfn-element';
import { Fn } from './cfn-fn';
import { Aws, ScopedAws } from './cfn-pseudo';
import { CfnResource, TagType } from './cfn-resource';
import { Construct, IConstruct, ISynthesisSession } from './construct-compat';
import { Construct, ISynthesisSession } from './construct-compat';
import { ContextProvider } from './context-provider';
import { Environment } from './environment';
import { FeatureFlags } from './feature-flags';
Expand Down Expand Up @@ -169,11 +170,12 @@ export class Stack extends Construct implements ITaggable {
return c;
}

if (Stage.isStage(c) || !c.node.scope) {
throw new Error(`${construct.constructor?.name ?? 'Construct'} at '${construct.node.path}' should be created in the scope of a Stack, but no Stack found`);
const _scope = Node.of(c).scope;
if (Stage.isStage(c) || !_scope) {
throw new Error(`${construct.constructor?.name ?? 'Construct'} at '${Node.of(construct).path}' should be created in the scope of a Stack, but no Stack found`);
}

return _lookup(c.node.scope);
return _lookup(_scope);
}
}

Expand Down Expand Up @@ -934,7 +936,7 @@ export class Stack extends Construct implements ITaggable {
*/
private generateStackId(container: IConstruct | undefined) {
const rootPath = rootPathTo(this, container);
const ids = rootPath.map(c => c.node.id);
const ids = rootPath.map(c => Node.of(c).id);

// In unit tests our Stack (which is the only component) may not have an
// id, so in that case just pretend it's "Stack".
Expand Down Expand Up @@ -1051,7 +1053,7 @@ function cfnElements(node: IConstruct, into: CfnElement[] = []): CfnElement[] {
into.push(node);
}

for (const child of node.node.children) {
for (const child of Node.of(node).children) {
// Don't recurse into a substack
if (Stack.isStack(child)) { continue; }

Expand All @@ -1067,7 +1069,7 @@ function cfnElements(node: IConstruct, into: CfnElement[] = []): CfnElement[] {
* If no ancestor is given or the ancestor is not found, return the entire root path.
*/
export function rootPathTo(construct: IConstruct, ancestor?: IConstruct): IConstruct[] {
const scopes = construct.node.scopes;
const scopes = Node.of(construct).scopes;
for (let i = scopes.length - 2; i >= 0; i--) {
if (scopes[i] === ancestor) {
return scopes.slice(i + 1);
Expand Down
5 changes: 3 additions & 2 deletions packages/@aws-cdk/core/lib/stage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as cxapi from '@aws-cdk/cx-api';
import { Construct, IConstruct } from './construct-compat';
import { IConstruct, Node } from 'constructs';
import { Construct } from './construct-compat';
import { Environment } from './environment';
import { collectRuntimeInformation } from './private/runtime-info';
import { synthesize } from './private/synthesis';
Expand Down Expand Up @@ -73,7 +74,7 @@ export class Stage extends Construct {
* @experimental
*/
public static of(construct: IConstruct): Stage | undefined {
return construct.node.scopes.reverse().slice(1).find(Stage.isStage);
return Node.of(construct).scopes.reverse().slice(1).find(Stage.isStage);
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"exclude": [
"props-physical-name:@aws-cdk/aws-cloudformation.CustomResourceProps",
"construct-ctor:@aws-cdk/core.App.<initializer>",
"construct-ctor:@aws-cdk/core.Construct.<initializer>.params[0]",
"props-no-cfn-types:@aws-cdk/core.CfnOutputProps.condition",
"duration-prop-type:@aws-cdk/core.ResourceSignal.timeout",
"props-no-any:@aws-cdk/core.CfnParameterProps.default",
Expand Down
Loading

0 comments on commit 4ec1c28

Please sign in to comment.