Skip to content

Commit

Permalink
Merge branch 'master' into rmuller/remove-useless-cfn2ts-script-entries
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Jun 9, 2020
2 parents 9cbc4e4 + 888b412 commit dcd45e5
Show file tree
Hide file tree
Showing 26 changed files with 1,135 additions and 21 deletions.
2 changes: 2 additions & 0 deletions packages/@aws-cdk/assets/lib/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/**
* Common interface for all assets.
*
* @deprecated use `core.IAsset`
*/
export interface IAsset {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/assets/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './api';
export * from './fs/follow-mode';
export * from './fs/options';
export * from './staging';
export * from './staging';
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as ec2 from '@aws-cdk/aws-ec2';
import { PolicyStatement, ServicePrincipal } from '@aws-cdk/aws-iam';
import { IBucket } from '@aws-cdk/aws-s3';
import { Construct, Resource } from '@aws-cdk/core';
import { BaseLoadBalancer, BaseLoadBalancerProps, ILoadBalancerV2 } from '../shared/base-load-balancer';
import { BaseNetworkListenerProps, NetworkListener } from './network-listener';
Expand Down Expand Up @@ -101,6 +103,41 @@ export class NetworkLoadBalancer extends BaseLoadBalancer implements INetworkLoa
});
}

/**
* Enable access logging for this load balancer.
*
* A region must be specified on the stack containing the load balancer; you cannot enable logging on
* environment-agnostic stacks. See https://docs.aws.amazon.com/cdk/latest/guide/environments.html
*
* This is extending the BaseLoadBalancer.logAccessLogs method to match the bucket permissions described
* at https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-access-logs.html#access-logging-bucket-requirements
*/
public logAccessLogs(bucket: IBucket, prefix?: string) {
super.logAccessLogs(bucket, prefix);

const logsDeliveryServicePrincipal = new ServicePrincipal('delivery.logs.amazonaws.com');

bucket.addToResourcePolicy(
new PolicyStatement({
actions: ['s3:PutObject'],
principals: [logsDeliveryServicePrincipal],
resources: [
bucket.arnForObjects(`${prefix ? prefix + '/' : ''}AWSLogs/${this.stack.account}/*`),
],
conditions: {
StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' },
},
}),
);
bucket.addToResourcePolicy(
new PolicyStatement({
actions: ['s3:GetBucketAcl'],
principals: [logsDeliveryServicePrincipal],
resources: [bucket.bucketArn],
}),
);
}

/**
* Return the given named metric for this Network Load Balancer
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,24 @@ export = {
{ Ref: 'AWS::AccountId' }, '/*']],
},
},
{
Action: 's3:PutObject',
Condition: { StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' }},
Effect: 'Allow',
Principal: { Service: 'delivery.logs.amazonaws.com' },
Resource: {
'Fn::Join': ['', [{ 'Fn::GetAtt': ['AccessLoggingBucketA6D88F29', 'Arn'] }, '/AWSLogs/',
{ Ref: 'AWS::AccountId' }, '/*']],
},
},
{
Action: 's3:GetBucketAcl',
Effect: 'Allow',
Principal: { Service: 'delivery.logs.amazonaws.com' },
Resource: {
'Fn::GetAtt': ['AccessLoggingBucketA6D88F29', 'Arn'],
},
},
],
},
}));
Expand Down Expand Up @@ -170,6 +188,24 @@ export = {
{ Ref: 'AWS::AccountId' }, '/*']],
},
},
{
Action: 's3:PutObject',
Condition: { StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' }},
Effect: 'Allow',
Principal: { Service: 'delivery.logs.amazonaws.com' },
Resource: {
'Fn::Join': ['', [{ 'Fn::GetAtt': ['AccessLoggingBucketA6D88F29', 'Arn'] }, '/prefix-of-access-logs/AWSLogs/',
{ Ref: 'AWS::AccountId' }, '/*']],
},
},
{
Action: 's3:GetBucketAcl',
Effect: 'Allow',
Principal: { Service: 'delivery.logs.amazonaws.com' },
Resource: {
'Fn::GetAtt': ['AccessLoggingBucketA6D88F29', 'Arn'],
},
},
],
},
}));
Expand Down
52 changes: 50 additions & 2 deletions packages/@aws-cdk/aws-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ runtime code.
* `lambda.Code.fromInline(code)` - inline the handle code as a string. This is
limited to supported runtimes and the code cannot exceed 4KiB.
* `lambda.Code.fromAsset(path)` - specify a directory or a .zip file in the local
filesystem which will be zipped and uploaded to S3 before deployment.
filesystem which will be zipped and uploaded to S3 before deployment. See also
[bundling asset code](#Bundling-Asset-Code).

The following example shows how to define a Python function and deploy the code
from the local directory `my-lambda-handler` to it:
Expand Down Expand Up @@ -62,7 +63,7 @@ const fn = new lambda.Function(this, 'MyFunction', {
runtime: lambda.Runtime.NODEJS_10_X,
handler: 'index.handler',
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),

fn.role // the Role
```
Expand Down Expand Up @@ -287,6 +288,53 @@ number of times and with different properties. Using `SingletonFunction` here wi
For example, the `LogRetention` construct requires only one single lambda function for all different log groups whose
retention it seeks to manage.

### Bundling Asset Code
When using `lambda.Code.fromAsset(path)` it is possible to bundle the code by running a
command in a Docker container. The asset path will be mounted at `/asset-input`. The
Docker container is responsible for putting content at `/asset-output`. The content at
`/asset-output` will be zipped and used as Lambda code.

Example with Python:
```ts
new lambda.Function(this, 'Function', {
code: lambda.Code.fromAsset(path.join(__dirname, 'my-python-handler'), {
bundling: {
image: lambda.Runtime.PYTHON_3_6.bundlingDockerImage,
command: [
'bash', '-c', `
pip install -r requirements.txt -t /asset-output &&
rsync -r . /asset-output
`,
],
},
}),
runtime: lambda.Runtime.PYTHON_3_6,
handler: 'index.handler',
});
```
Runtimes expose a `bundlingDockerImage` property that points to the [lambci/lambda](https://hub.docker.com/r/lambci/lambda/) build image.

Use `cdk.BundlingDockerImage.fromRegistry(image)` to use an existing image or
`cdk.BundlingDockerImage.fromAsset(path)` to build a specific image:

```ts
import * as cdk from '@aws-cdk/core';

new lambda.Function(this, 'Function', {
code: lambda.Code.fromAsset('/path/to/handler', {
bundling: {
image: cdk.BundlingDockerImage.fromAsset('/path/to/dir/with/DockerFile', {
buildArgs: {
ARG1: 'value1',
},
}),
command: ['my', 'cool', 'command'],
},
}),
// ...
});
```

### Language-specific APIs
Language-specific higher level constructs are provided in separate modules:

Expand Down
11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-lambda/lib/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { BundlingDockerImage } from '@aws-cdk/core';

export interface LambdaRuntimeProps {
/**
* Whether the ``ZipFile`` (aka inline code) property can be used with this runtime.
Expand Down Expand Up @@ -154,10 +156,19 @@ export class Runtime {
*/
public readonly family?: RuntimeFamily;

/**
* The bundling Docker image for this runtime.
* Points to the lambci/lambda build image for this runtime.
*
* @see https://hub.docker.com/r/lambci/lambda/
*/
public readonly bundlingDockerImage: BundlingDockerImage;

constructor(name: string, family?: RuntimeFamily, props: LambdaRuntimeProps = { }) {
this.name = name;
this.supportsInlineCode = !!props.supportsInlineCode;
this.family = family;
this.bundlingDockerImage = BundlingDockerImage.fromRegistry(`lambci/lambda:build-${name}`);

Runtime.ALL.push(this);
}
Expand Down
113 changes: 113 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/integ.bundling.expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"Resources": {
"FunctionServiceRole675BB04A": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
]
]
}
]
}
},
"Function76856677": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdS3Bucket6365D8AA"
},
"S3Key": {
"Fn::Join": [
"",
[
{
"Fn::Select": [
0,
{
"Fn::Split": [
"||",
{
"Ref": "AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdS3VersionKey14A1DBA7"
}
]
}
]
},
{
"Fn::Select": [
1,
{
"Fn::Split": [
"||",
{
"Ref": "AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdS3VersionKey14A1DBA7"
}
]
}
]
}
]
]
}
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"FunctionServiceRole675BB04A",
"Arn"
]
},
"Runtime": "python3.6"
},
"DependsOn": [
"FunctionServiceRole675BB04A"
]
}
},
"Parameters": {
"AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdS3Bucket6365D8AA": {
"Type": "String",
"Description": "S3 bucket for asset \"0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cd\""
},
"AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdS3VersionKey14A1DBA7": {
"Type": "String",
"Description": "S3 key for asset version \"0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cd\""
},
"AssetParameters0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cdArtifactHashEEC2ED67": {
"Type": "String",
"Description": "Artifact hash for asset \"0ccf37fa0b92d4598d010192eb994040c2e22cc6b12270736d323437817112cd\""
}
},
"Outputs": {
"FunctionArn": {
"Value": {
"Fn::GetAtt": [
"Function76856677",
"Arn"
]
}
}
}
}
42 changes: 42 additions & 0 deletions packages/@aws-cdk/aws-lambda/test/integ.bundling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { App, CfnOutput, Construct, Stack, StackProps } from '@aws-cdk/core';
import * as path from 'path';
import * as lambda from '../lib';

/**
* Stack verification steps:
* * aws cloudformation describe-stacks --stack-name cdk-integ-lambda-bundling --query Stacks[0].Outputs[0].OutputValue
* * aws lambda invoke --function-name <output from above> response.json
* * cat response.json
* The last command should show '200'
*/
class TestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);

const assetPath = path.join(__dirname, 'python-lambda-handler');
const fn = new lambda.Function(this, 'Function', {
code: lambda.Code.fromAsset(assetPath, {
bundling: {
image: lambda.Runtime.PYTHON_3_6.bundlingDockerImage,
command: [
'bash', '-c', [
'rsync -r . /asset-output',
'cd /asset-output',
'pip install -r requirements.txt -t .',
].join(' && '),
],
},
}),
runtime: lambda.Runtime.PYTHON_3_6,
handler: 'index.handler',
});

new CfnOutput(this, 'FunctionArn', {
value: fn.functionArn,
});
}
}

const app = new App();
new TestStack(app, 'cdk-integ-lambda-bundling');
app.synth();
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import requests

def handler(event, context):
r = requests.get('https://aws.amazon.com')

print(r.status_code)

return r.status_code
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests==2.23.0
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-s3-assets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ The following examples grants an IAM group read permissions on an asset:

[Example of granting read access to an asset](./test/integ.assets.permissions.lit.ts)

The following example uses custom asset bundling to convert a markdown file to html:
[Example of using asset bundling](./test/integ.assets.bundling.lit.ts)

## How does it work?

When an asset is defined in a construct, a construct metadata entry
Expand Down
Loading

0 comments on commit dcd45e5

Please sign in to comment.