Skip to content

Commit

Permalink
Merge branch 'master' into profiler_group_compute
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Aug 14, 2020
2 parents 00300cc + 1c4eae8 commit 37a9640
Show file tree
Hide file tree
Showing 62 changed files with 3,731 additions and 449 deletions.
156 changes: 86 additions & 70 deletions DESIGN_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ If all props are optional, the `props` argument must also be optional
_[awslint:construct-ctor-props-optional]_.

```ts
constructor(scope: cdk.Construct, id: string, props: FooProps = { })
constructor(scope: cdk.Construct, id: string, props: FooProps = {})
```

> Using `={}` as a default value is preferable to using an optional qualifier
> Using `= {}` as a default value is preferable to using an optional qualifier
(`?`) since it will ensure that props will never be `undefined` and therefore
easier to parse in the method body.

Expand Down Expand Up @@ -203,13 +203,13 @@ expanding it's surface area. It also allows the **Key** class to change it's
behavior (i.e. add an IAM action to enable encryption of certain types of keys)
without affecting the API of the consumer.

#### owned vs. unowned constructs
#### Owned vs. Unowned Constructs

Using object references instead of attribute references provides a richer API,
but also introduces an inherent challenge: how do we reference constructs that
are not defined inside the same app (“**owned**” by the app). These could be
resources that were created by some other AWS CDK app, via the AWS console,
etc. We call these **unowned****constructs.**
etc. We call these **unownedconstructs.**

In order to model this concept of owned and unowned constructs, all constructs
in the AWS Construct Library should always have a corresponding **construct
Expand All @@ -233,7 +233,7 @@ AWS Construct Library) should extend **IResource** (which, transitively, extends
#### Abstract Base

It is recommended to implement an abstract base class **FooBase** for each
resource **Foo****. **The base class would normally implement the entire
resource **Foo**. The base class would normally implement the entire
construct interface and leave attributes as abstract properties.

```ts
Expand Down Expand Up @@ -289,7 +289,7 @@ through a declarative interface [_awslint:props-coverage_].

This section describes guidelines for construct props.

#### types
#### Types

Use **strong types** (and specifically, construct interfaces) instead of
physical attributes when referencing other resources. For example, instead of
Expand All @@ -306,14 +306,18 @@ be avoided wherever possible [_awslint:props-no-tokens_].
**deCDK** allows users to synthesize CDK stacks through a CloudFormation-like
template, similar to SAM. CDK constructs are represented in deCDK templates
like CloudFormation resources. Technically, this means that when a construct
is defined, users supply an ID, type and a set of properties.****In order to
is defined, users supply an ID, type and a set of properties. In order to
allow users to instantiate all AWS Construct Library constructs through the
deCDK syntax, we pose restrictions on prop types _[awslint:props-decdk]_:

* Primitives (string, number, boolean, date) Collections (list, map) Structs
* Enums Enum-like classes Union-like classes References to other constructs
* (through their construct interface) Integration interfaces (interfaces that
* have a “**bind**” method)
* Primitives (string, number, boolean, date)
* Collections (list, map)
* Structs
* Enums
* Enum-like classes
* Union-like classes
* References to other constructs (through their construct interface)
* Integration interfaces (interfaces that have a “**bind**” method)

#### Defaults

Expand All @@ -331,7 +335,7 @@ from harnessing the full power of the resource, and customizing its behavior.
The **@default** documentation tag must be included on all optional properties
of interfaces. Since there are cases where the default behavior is not a
specific value but rather depends on circumstances/context, the default
documentation tag must always begin with a ****-"**** and then include a
documentation tag must always begin with a “**-**" and then include a
description of the default behavior _[awslint:props-default-doc]_.

For example:
Expand Down Expand Up @@ -649,10 +653,11 @@ export interface IFoo {
Notice that:
* The method has an “add” prefix. It implies that users are adding something to
* their stack. The method is implemented on the construct interface (to allow
* adding secondary resources to unowned constructs). The method returns a “Bar”
* instance (owned).
* The method has an “add” prefix.
It implies that users are adding something to their stack.
* The method is implemented on the construct interface
(to allow adding secondary resources to unowned constructs).
* The method returns a “Bar” instance (owned).
In order to reuse the set of props used to configure the secondary resource,
define a base interface for **FooProps** called **FooOptions** to allow
Expand Down Expand Up @@ -682,12 +687,12 @@ their app.
The signature of all “from” methods should adhere to the following rules
_[awslint:from-signature]_:
* First argument must be **scope** of type **Construct** Second argument is a
* **string**. This string will be used to determine the ID of the new
* construct. If the import method uses some value that is promised to be unique
* within the stack scope (such as ARN, export name), this value can be reused as
* the construct ID. Returns an object that implements the construct interface
* (**IFoo**).
* First argument must be **scope** of type **Construct**
* Second argument is a **string**. This string will be used to determine the
ID of the new construct. If the import method uses some value that is
promised to be unique within the stack scope (such as ARN, export name),
this value can be reused as the construct ID.
* Returns an object that implements the construct interface (**IFoo**).
#### “from” Methods
Expand Down Expand Up @@ -792,8 +797,6 @@ If the construct is unowned this method should no-op and issue a **permissions
notice** (TODO) to the user indicating that they should ensure that the role of
this resource should have the specified permission.
TODO: add a few sentences on grantable
Implementing **IGrantable** brings an implementation burden of **grantPrincipal:
IPrincipal**. This property must be set to the **role** if available, or to a
new **iam.ImportedResourcePrincipal** if the resource is imported and the role
Expand Down Expand Up @@ -897,8 +900,9 @@ cases. For example, **dynamodb.Table.grantPutItem**,
**s3.Bucket.grantReadWrite**, etc. In such cases, the signature of the grant
method should adhere to the following rules _[awslint:grant-signature]_:
1. Name should have a “grant” prefix 2. Returns an **iam.Grant** object 3. First
argument must be **grantee: iam.IGrantable**
1. Name should have a “grant” prefix
2. Returns an **iam.Grant** object
3. First argument must be **grantee: iam.IGrantable**
```ts
grantXxx(grantee: iam.IGrantable): iam.Grant;
Expand Down Expand Up @@ -941,9 +945,9 @@ metric(metricName: string, options?: cloudwatch.MetricOptions): cloudwatch.Metri
Additional metric methods should be exposed with the official metric name as a
suffix and adhere to the following rules _[awslint:metrics-method-signature]:_
* Name should be “metricXxx” where “Xxx” is the official metric name Accepts a
* single “options” argument of type **MetricOptions** Returns a **Metric**
* object.
* Name should be “metricXxx” where “Xxx” is the official metric name
* Accepts a single “options” argument of type **MetricOptions**
* Returns a **Metric** object.
```ts
interface IFunction {
Expand Down Expand Up @@ -1034,9 +1038,9 @@ interface IEventSource {
A method “addXxx” should be defined on the construct interface and adhere to the
following rules _[awslint:integrations-add-method]:_
* Should accept any object that implements the integrations interface Should not
* return anything (void) Implementation should call “bind” on the integration
* object
* Should accept any object that implements the integrations interface
* Should not return anything (void)
* Implementation should call “bind” on the integration object
```ts
interface IFunction extends IResource {
Expand Down Expand Up @@ -1123,11 +1127,11 @@ property **stateful** which returns **true** or **false** to allow runtime
checks query whether a resource is persistent
_[awslint:state-stateful-property]_.
### Physical Names (NEW) - TODO
### Physical Names - TODO
See <https://github.com/awslabs/aws-cdk/issues/2283>
### Tags (NEW)
### Tags
The AWS platform has a powerful tagging system that can be used to tag resources
with key/values. The AWS CDK exposes this capability through the **Tag**
Expand All @@ -1141,7 +1145,7 @@ myConstruct.node.apply(new cdk.Tag("myKey", "myValue"));
Constructs for AWS resources that can be tagged must have an optional **tags**
hash in their props [_awslint:tags-prop_].
### Secrets (NEW)
### Secrets
If you expect a secret in your API (such as passwords, tokens), use the
**cdk.SecretValue** class to signal to users that they should not include
Expand All @@ -1155,10 +1159,11 @@ use the SecretValue type [_awslint:secret-token_].
### Code Organization
* Code should be under `lib/` Entry point should be `lib/index.ts` and should
* only contain “imports” for other files. No need to put every class in a
* separate file. Try to think of a reader-friendly organization of your source
* files.
* Code should be under `lib/`
* Entry point should be `lib/index.ts` and should only contain “imports”
for other files.
* No need to put every class in a separate file. Try to think of a
reader-friendly organization of your source files.
## Implementation
Expand All @@ -1167,11 +1172,14 @@ implementation of AWS constructs.
### General Principles
* Do not future proof No fluent APIs Good APIs “speak” in the language of the
* user. The terminology your API uses should be intuitive and represent the
* mental model your user brings over, not one that you made up and you force
* them to learn. Multiple ways of achieving the same thing is legitimate
* Constantly maintain the invariants Fewer “if statements” the better
* Do not future proof.
* No fluent APIs.
* Good APIs “speak” in the language of the user. The terminology your API uses
should be intuitive and represent the mental model your user brings over,
not one that you made up and you force them to learn.
* Multiple ways of achieving the same thing is legitimate.
* Constantly maintain the invariants.
* Fewer “if statements” the better.
### Construct IDs
Expand Down Expand Up @@ -1208,26 +1216,28 @@ for (const az of availabilityZones) {
### Errors
#### input validation
#### Input Validation
Prefer to validate input as early as it is passed into your code (ctor, methods,
etc) and bail out by throwing an **Error** (no need to create subclasses of
Error since all errors in the CDK are unrecoverable):
* All lowercase sentences (usually they are printed after “Error: \<message\>”)
* Include a descriptive message Include the value provided Include the
* expected/allowed values No need to include information that can be obtained
* from the stack trace. No need to add a period at the end of error messages.
* Include a descriptive message
* Include the value provided
* Include the expected/allowed values
* No need to include information that can be obtained from the stack trace.
* No need to add a period at the end of error messages.
#### avoid errors if possible
#### Avoid Errors if Possible
Always prefer to do the right thing for the user instead of raising an
error. Only fail if the user has explicitly specified bad configuration. For
example, VPC has **enableDnsHostnames** and **enableDnsSupport**. DNS hostnames
*require* DNS support, so only fail if the user enabled DNS hostnames but
explicitly disabled DNS support. Otherwise, auto-enable DNS support for them.
#### Never catch exceptions
#### Never Catch Exceptions
All CDK errors are unrecoverable. If a method wishes to signal a recoverable
error, this should be modeled in a return value and not through exceptions.
Expand All @@ -1238,12 +1248,12 @@ In the rare case where the integrity of your construct can only be checked right
before synthesis, override the **Construct.validate()** method and return
meaningful errors. Always prefer early input validation over post-validation.
#### attached Errors/warnings
#### Attached Errors/Warnings
You can also “attach” an error or a warning to a construct via
**node.addWarning(s)** or **node.addError(s)**. These methods will attach CDK
metadata to your construct, which will be displayed to the user by the toolchain
when the stack is deployed.
the **Annotations** class. These methods (e.g., `Annotations.of(construct).addWarning`)
will attach CDK metadata to your construct, which will be displayed to the user
by the toolchain when the stack is deployed.
Errors will not allow deployment and warnings will only be displayed in
highlight (unless **--strict** mode is used).
Expand Down Expand Up @@ -1274,20 +1284,22 @@ Use the following JSDoc tags: **@param**, **@returns**, **@default**, **@see**,
### Readme
* Header should include maturity level Example for the simple use case should be
* almost the first thing If there are multiple common use cases, provide an
* example for each one and describe what happens under the hood at a high level
* (e.g. which resources are created). Reference docs are not needed Use
* literate (`.lit.ts`) integration tests into README file (see example in
* Header should include maturity level.
* Example for the simple use case should be almost the first thing.
* If there are multiple common use cases, provide an example for each one and
describe what happens under the hood at a high level
(e.g. which resources are created).
* Reference docs are not needed.
* Use literate (`.lit.ts`) integration tests into README file.
## Testing
### Unit tests
* Unit test utility functions and object models separately from constructs. If
* you want them to be “package-private”, just put them in a separate file and
* import `../lib/my-util` from your unit test code. Failing tests should be
* prefixed with “fails”
you want them to be “package-private”, just put them in a separate file and
import `../lib/my-util` from your unit test code.
* Failing tests should be prefixed with “fails”
### Integration tests
Expand All @@ -1302,14 +1314,18 @@ Use the following JSDoc tags: **@param**, **@returns**, **@default**, **@see**,
### Naming Conventions
* **Class names**: PascalCase Properties**: camelCase Methods (static and
* **non-static)**: camelCase Interfaces** (“behavioral interface”) :
* **IMyInterface Structs** (“data interfaces”): MyDataStruct Enums**:
* **PascalCase,**Members**: SNAKE_UPPER
* **Class names**: PascalCase
* **Properties**: camelCase
* **Methods (static and non-static)**: camelCase
* **Interfaces** (“behavioral interface”): IMyInterface
* **Structs** (“data interfaces”): MyDataStruct
* **Enums**: PascalCase, **Members**: SNAKE_UPPER
### Coding Style
* **Indentation**: 2 spaces Line length**: 150 String literals**: use
* **single-quotes (`'`) or backticks (```) Semicolons**: at the end of each code
* **statement and declaration (incl. properties and imports). Comments**: start
* **with lower-case, end with a period.
* **Indentation**: 2 spaces
* **Line length**: 150
* **String literals**: use single-quotes (`'`) or backticks (```)
* **Semicolons**: at the end of each code statement and declaration
(incl. properties and imports).
* **Comments**: start with lower-case, end with a period.
6 changes: 6 additions & 0 deletions allowed-breaking-changes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ removed:@aws-cdk/cdk-assets-schema.FileAssetPackaging

changed-type:@aws-cdk/aws-codedeploy.IServerDeploymentGroup.autoScalingGroups
changed-type:@aws-cdk/aws-codedeploy.ServerDeploymentGroup.autoScalingGroups

# We were leaking L1 types in L2 APIs, which now have changed required -> optional
# when ECS moved to the CloudFormation Registry spec.
change-return-type:@aws-cdk/aws-ecs.ContainerDefinition.renderContainerDefinition
change-return-type:@aws-cdk/aws-ecs.FirelensLogRouter.renderContainerDefinition
change-return-type:@aws-cdk/aws-ecs.LinuxParameters.renderLinuxParameters
Binary file modified logo/default-128-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified logo/default-256-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified logo/default-64-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,19 @@
"ForwardedValues": {
"QueryString": false
},
"TargetOriginId": "cloudfrontorigingroupDistributionOrigin137659A54",
"TargetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1",
"ViewerProtocolPolicy": "allow-all"
},
"CacheBehaviors": [
{
"ForwardedValues": {
"QueryString": false
},
"PathPattern": "/api",
"TargetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1",
"ViewerProtocolPolicy": "allow-all"
}
],
"Enabled": true,
"HttpVersion": "http2",
"IPV6Enabled": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ const originGroup = new origins.OriginGroup({

new cloudfront.Distribution(stack, 'Distribution', {
defaultBehavior: { origin: originGroup },
additionalBehaviors: {
'/api': {
origin: originGroup,
},
},
});

app.synth();
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ describe('Origin Groups', () => {

const primaryOriginId = 'DistributionOrigin13547B94F';
const failoverOriginId = 'DistributionOrigin2C85CC43B';
const originGroupId = 'DistributionOriginGroup1A1A31B49';
expect(stack).toHaveResourceLike('AWS::CloudFront::Distribution', {
DistributionConfig: {
DefaultCacheBehavior: {
TargetOriginId: originGroupId,
},
Origins: [
{
Id: primaryOriginId,
Expand Down
Loading

0 comments on commit 37a9640

Please sign in to comment.