Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into benisrae/nested-sta…
Browse files Browse the repository at this point in the history
…cks-dependencies
  • Loading branch information
Elad Ben-Israel committed Nov 27, 2019
2 parents 2eaff5b + 91c4502 commit 94a4fe2
Show file tree
Hide file tree
Showing 35 changed files with 542 additions and 617 deletions.
57 changes: 0 additions & 57 deletions packages/@aws-cdk/assert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,60 +79,3 @@ expect(stack).to(haveResource('AWS::CertificateManager::Certificate', {
// Note: some properties omitted here
}));
```


## Integration tests

Integration tests are modeled as CDK apps that are deployed by the developers.
If deployment succeeds, the synthesized template is saved in a local file and
"locked". During build, the test app is only synthesized and compared against
the checked-in file to protect against regressions.

### Setup

Create any number of files called `integ.*.ts` in your `test` directory. These
should be CDK apps containing a single stack.

Add the following to your `package.json`':

```json
{
scripts: {
"test": ".... && cdk-integ-assert",
"integ": "cdk-integ"
},
...
devDependencies: {
"@aws-cdk/assert": "*",
"aws-cdk": "*"
}
}
```

This installs two tools into your scripts:

* When `npm test` is executed (during build), the `cdk-integ-assert` tool is
invoked. This tool will only synthesize the integration test stacks and
compare them to the .expected files. If the files differ (or do not exist),
the test will fail.
* When `npm run integ` is executed (manually by the developer), the `cdk-integ`
tool is invoked. This tool will actually attempt to deploy the integration
test stacks into the default environment. If it succeeds, the .expected file
will be updated to include the latest synthesized stack.

The usage of `cdk-integ` is:

```bash
cdk-integ [--no-clean] [filters...]

# or

npm run integ -- [--no-clean] [filters...]
```

* If `--no-clean` is specified, the integration test stacks will not be cleaned
up. This can be used to perform manual validation on the stacks.
* If filters are specified, each test name is evaluated against each filter. If
the name matches any of the filters, the test is included. Otherwise it is
skipped.

11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import certificatemanager = require('@aws-cdk/aws-certificatemanager');
import iam = require('@aws-cdk/aws-iam');
import lambda = require('@aws-cdk/aws-lambda');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/core');
Expand Down Expand Up @@ -827,6 +828,16 @@ export class CloudFrontWebDistribution extends cdk.Construct implements IDistrib
lambdaFunctionArn: fna.lambdaFunction && fna.lambdaFunction.functionArn,
}))
});

// allow edgelambda.amazonaws.com to assume the functions' execution role.
for (const a of input.lambdaFunctionAssociations) {
if (a.lambdaFunction.role && a.lambdaFunction.role instanceof iam.Role && a.lambdaFunction.role.assumeRolePolicy) {
a.lambdaFunction.role.assumeRolePolicy.addStatements(new iam.PolicyStatement({
actions: [ 'sts:AssumeRole' ],
principals: [ new iam.ServicePrincipal('edgelambda.amazonaws.com') ]
}));
}
}
}
return toReturn;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-cloudfront/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"license": "Apache-2.0",
"devDependencies": {
"@aws-cdk/assert": "1.18.0",
"aws-sdk": "^2.575.0",
"aws-sdk": "^2.579.0",
"cdk-build-tools": "1.18.0",
"cdk-integ-tools": "1.18.0",
"cfn2ts": "1.18.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"Resources": {
"Bucket83908E77": {
"Type": "AWS::S3::Bucket",
"Properties": {
"WebsiteConfiguration": {
"ErrorDocument": "404.html",
"IndexDocument": "index.html"
}
},
"UpdateReplacePolicy": "Retain",
"DeletionPolicy": "Retain"
},
"BucketPolicyE9A3008A": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "Bucket83908E77"
},
"PolicyDocument": {
"Statement": [
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Principal": "*",
"Resource": {
"Fn::Join": [
"",
[
{
"Fn::GetAtt": [
"Bucket83908E77",
"Arn"
]
},
"/*"
]
]
}
}
],
"Version": "2012-10-17"
}
}
},
"DistributionCFDistribution882A7313": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"DefaultCacheBehavior": {
"AllowedMethods": [
"GET",
"HEAD"
],
"CachedMethods": [
"GET",
"HEAD"
],
"Compress": true,
"ForwardedValues": {
"Cookies": {
"Forward": "none"
},
"QueryString": false
},
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https"
},
"DefaultRootObject": "index.html",
"Enabled": true,
"HttpVersion": "http2",
"IPV6Enabled": true,
"Origins": [
{
"CustomOriginConfig": {
"HTTPPort": 80,
"HTTPSPort": 443,
"OriginKeepaliveTimeout": 5,
"OriginProtocolPolicy": "http-only",
"OriginReadTimeout": 30,
"OriginSSLProtocols": [
"TLSv1.2"
]
},
"DomainName": {
"Fn::Select": [
2,
{
"Fn::Split": [
"/",
{
"Fn::GetAtt": [
"Bucket83908E77",
"WebsiteURL"
]
}
]
}
]
},
"Id": "origin1"
}
],
"PriceClass": "PriceClass_200",
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import s3 = require('@aws-cdk/aws-s3');
import { App, Construct, Stack } from "@aws-cdk/core";
import cloudfront = require('../lib');

class TestStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);

const bucket = new s3.Bucket(this, `Bucket`, {
publicReadAccess: true,
websiteIndexDocument: "index.html",
websiteErrorDocument: "404.html",
});

new cloudfront.CloudFrontWebDistribution(this, `Distribution`, {
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
priceClass: cloudfront.PriceClass.PRICE_CLASS_200,
originConfigs: [
{
behaviors: [ { isDefaultBehavior: true } ],
customOriginSource: {
originProtocolPolicy: cloudfront.OriginProtocolPolicy.HTTP_ONLY,
domainName: bucket.bucketWebsiteDomainName
},
}
]
}
);
}
}

const app = new App();
new TestStack(app, 'cloudfront-custom-s3-integ');
app.synth();
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Resources": {
"Bucket83908E77": {
"DeletionPolicy": "Delete",
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Delete",
"Type": "AWS::S3::Bucket"
"DeletionPolicy": "Delete"
},
"LambdaServiceRoleA8ED4D3B": {
"Type": "AWS::IAM::Role",
Expand All @@ -16,6 +16,13 @@
"Principal": {
"Service": "lambda.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "edgelambda.amazonaws.com"
}
}
],
"Version": "2012-10-17"
Expand Down Expand Up @@ -76,14 +83,13 @@
"GET",
"HEAD"
],
"Compress": true,
"ForwardedValues": {
"Cookies": {
"Forward": "none"
},
"QueryString": false
},
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https",
"LambdaFunctionAssociations": [
{
"EventType": "origin-request",
Expand All @@ -92,7 +98,8 @@
}
}
],
"Compress": true
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https"
},
"DefaultRootObject": "index.html",
"Enabled": true,
Expand All @@ -118,4 +125,4 @@
}
}
}
}
}
85 changes: 84 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/test/test.basic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect, haveResourceLike } from '@aws-cdk/assert';
import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert';
import certificatemanager = require('@aws-cdk/aws-certificatemanager');
import * as lambda from '@aws-cdk/aws-lambda';
import s3 = require('@aws-cdk/aws-s3');
Expand Down Expand Up @@ -787,4 +787,87 @@ export = {
}
},

'edgelambda.amazonaws.com is added to the trust policy of lambda'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const sourceBucket = new s3.Bucket(stack, 'Bucket');
const fn = new lambda.Function(stack, 'Lambda', {
code: lambda.Code.fromInline('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_10_X
});
const lambdaVersion = new lambda.Version(stack, 'LambdaVersion', { lambda: fn });

// WHEN
new CloudFrontWebDistribution(stack, 'MyDistribution', {
originConfigs: [
{
s3OriginSource: { s3BucketSource: sourceBucket },
behaviors : [
{
isDefaultBehavior: true, lambdaFunctionAssociations: [
{
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
lambdaFunction: lambdaVersion
}
]
}
]
}
]
});

// THEN
expect(stack).to(haveResource('AWS::IAM::Role', {
AssumeRolePolicyDocument: {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "edgelambda.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}));
test.done();
},

'edgelambda.amazonaws.com is not added to lambda role for imported functions'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const sourceBucket = new s3.Bucket(stack, 'Bucket');
const lambdaVersion = lambda.Version.fromVersionArn(stack, 'Version', 'arn:my-version');

// WHEN
new CloudFrontWebDistribution(stack, 'MyDistribution', {
originConfigs: [
{
s3OriginSource: { s3BucketSource: sourceBucket },
behaviors : [
{
isDefaultBehavior: true, lambdaFunctionAssociations: [
{
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
lambdaFunction: lambdaVersion
}
]
}
]
}
]
});

expect(stack).notTo(haveResourceLike('AWS::IAM::Role'));
test.done();
}
};
Loading

0 comments on commit 94a4fe2

Please sign in to comment.