Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into fix-ecr-repo-regex
Browse files Browse the repository at this point in the history
mergify[bot] authored Sep 13, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents f57aad4 + 84701d6 commit 7336880
Showing 13 changed files with 171 additions and 11 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -4,7 +4,8 @@
"Type": "AWS::ApiGatewayV2::Api",
"Properties": {
"Name": "HttpApi",
"ProtocolType": "HTTP"
"ProtocolType": "HTTP",
"RouteSelectionExpression": "${request.method} ${request.path}"
}
},
"HttpApiDefaultStage3EEB07D6": {

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@ import * as apigw from 'aws-cdk-lib/aws-apigatewayv2';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-cdk-aws-apigatewayv2');

new apigw.HttpApi(stack, 'HttpApi');
new apigw.HttpApi(stack, 'HttpApi', {
routeSelectionExpression: true,
});

new IntegTest(app, 'http-api', {
testCases: [stack],
8 changes: 8 additions & 0 deletions packages/aws-cdk-lib/aws-apigatewayv2/README.md
Original file line number Diff line number Diff line change
@@ -93,6 +93,14 @@ new apigwv2.HttpApi(this, 'HttpProxyApi', {
});
```

The `routeSelectionExpression` option allows configuring the HTTP API to accept only `${request.method} ${request.path}`. Setting it to `true` automatically applies this value.

```ts
new apigwv2.HttpApi(this, 'HttpProxyApi', {
routeSelectionExpression: true,
});
```

### Cross Origin Resource Sharing (CORS)

[Cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a browser security
10 changes: 10 additions & 0 deletions packages/aws-cdk-lib/aws-apigatewayv2/lib/http/api.ts
Original file line number Diff line number Diff line change
@@ -160,6 +160,15 @@ export interface HttpApiProps {
* @default - no default authorization scopes
*/
readonly defaultAuthorizationScopes?: string[];

/**
* Whether to set the default route selection expression for the API.
*
* When enabled, "${request.method} ${request.path}" is set as the default route selection expression.
*
* @default false
*/
readonly routeSelectionExpression?: boolean;
}

/**
@@ -434,6 +443,7 @@ export class HttpApi extends HttpApiBase {
corsConfiguration,
description: props?.description,
disableExecuteApiEndpoint: this.disableExecuteApiEndpoint,
routeSelectionExpression: props?.routeSelectionExpression ? '${request.method} ${request.path}' : undefined,
};

const resource = new CfnApi(this, 'Resource', apiProps);
26 changes: 26 additions & 0 deletions packages/aws-cdk-lib/aws-apigatewayv2/test/http/api.test.ts
Original file line number Diff line number Diff line change
@@ -234,6 +234,32 @@ describe('HttpApi', () => {
});
});

test('routeSelectionExpression is enabled', () => {
const stack = new Stack();
new HttpApi(stack, 'api', {
routeSelectionExpression: true,
});

Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', {
Name: 'api',
ProtocolType: 'HTTP',
RouteSelectionExpression: '${request.method} ${request.path}',
});
});

test.each([false, undefined])('routeSelectionExpression is not enabled', (routeSelectionExpression) => {
const stack = new Stack();
new HttpApi(stack, 'api', {
routeSelectionExpression,
});

Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', {
Name: 'api',
ProtocolType: 'HTTP',
RouteSelectionExpression: Match.absent(),
});
});

test('can add a vpc links', () => {
// GIVEN
const stack = new Stack();
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/aws-ec2/lib/vpc-endpoint.ts
Original file line number Diff line number Diff line change
@@ -538,6 +538,7 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ
public static readonly REKOGNITION_STREAMING = new InterfaceVpcEndpointAwsService('streaming-rekognition');
public static readonly REKOGNITION_STREAMING_FIPS = new InterfaceVpcEndpointAwsService('streaming-rekognition-fips');
public static readonly REPOST_SPACE = new InterfaceVpcEndpointAwsService('repostspace');
public static readonly RESOURCE_ACCESS_MANAGER = new InterfaceVpcEndpointAwsService('ram');
public static readonly ROBOMAKER = new InterfaceVpcEndpointAwsService('robomaker');
public static readonly RECYCLE_BIN = new InterfaceVpcEndpointAwsService('rbin');
public static readonly S3 = new InterfaceVpcEndpointAwsService('s3');
111 changes: 111 additions & 0 deletions packages/aws-cdk-lib/aws-s3/README.md
Original file line number Diff line number Diff line change
@@ -492,6 +492,117 @@ const bucket = new s3.Bucket(this, 'MyBucket', {
});
```

The above code will create a new bucket policy if none exists or update the
existing bucket policy to allow access log delivery.

However, there could be an edge case if the `accessLogsBucket` also defines a bucket
policy resource using the L1 Construct. Although the mixing of L1 and L2 Constructs is not
recommended, there are no mechanisms in place to prevent users from doing this at the moment.

```ts
const bucketName = "my-favorite-bucket-name";
const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket', {
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED,
bucketName,
});

// Creating a bucket policy using L1
const bucketPolicy = new s3.CfnBucketPolicy(this, "BucketPolicy", {
bucket: bucketName,
policyDocument: {
Statement: [
{
Action: 's3:*',
Effect: 'Deny',
Principal: {
AWS: '*',
},
Resource: [
accessLogsBucket.bucketArn,
`${accessLogsBucket.bucketArn}/*`
],
},
],
Version: '2012-10-17',
},
});

// 'serverAccessLogsBucket' will create a new L2 bucket policy
// to allow log delivery and overwrite the L1 bucket policy.
const bucket = new s3.Bucket(this, 'MyBucket', {
serverAccessLogsBucket: accessLogsBucket,
serverAccessLogsPrefix: 'logs',
});
```

The above example uses the L2 Bucket Construct with the L1 CfnBucketPolicy Construct. However,
when `serverAccessLogsBucket` is set, a new L2 Bucket Policy resource will be created
which overwrites the permissions defined in the L1 Bucket Policy causing unintended
behaviours.

As noted above, we highly discourage the mixed usage of L1 and L2 Constructs. The recommended
approach would to define the bucket policy using `addToResourcePolicy` method.

```ts
const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket', {
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED,
});

accessLogsBucket.addToResourcePolicy(
new iam.PolicyStatement({
actions: ['s3:*'],
resources: [accessLogsBucket.bucketArn, accessLogsBucket.arnForObjects('*')],
principals: [new iam.AnyPrincipal()],
})
)

const bucket = new s3.Bucket(this, 'MyBucket', {
serverAccessLogsBucket: accessLogsBucket,
serverAccessLogsPrefix: 'logs',
});
```

Alternatively, users can use the L2 Bucket Policy Construct
`BucketPolicy.fromCfnBucketPolicy` to wrap around `CfnBucketPolicy` Construct. This will allow the subsequent bucket policy generated by `serverAccessLogsBucket` usage to append to the existing bucket policy instead of overwriting.

```ts
const bucketName = "my-favorite-bucket-name";
const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket', {
objectOwnership: s3.ObjectOwnership.BUCKET_OWNER_ENFORCED,
bucketName,
});

const bucketPolicy = new s3.CfnBucketPolicy(this, "BucketPolicy", {
bucket: bucketName,
policyDocument: {
Statement: [
{
Action: 's3:*',
Effect: 'Deny',
Principal: {
AWS: '*',
},
Resource: [
accessLogsBucket.bucketArn,
`${accessLogsBucket.bucketArn}/*`
],
},
],
Version: '2012-10-17',
},
});

// Wrap L1 Construct with L2 Bucket Policy Construct. Subsequent
// generated bucket policy to allow access log delivery would append
// to the current policy.
s3.BucketPolicy.fromCfnBucketPolicy(bucketPolicy);

const bucket = new s3.Bucket(this, 'MyBucket', {
serverAccessLogsBucket: accessLogsBucket,
serverAccessLogsPrefix: 'logs',
});
```

## S3 Inventory

An [inventory](https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-inventory.html) contains a list of the objects in the source bucket and metadata for each object. The inventory lists are stored in the destination bucket as a CSV file compressed with GZIP, as an Apache optimized row columnar (ORC) file compressed with ZLIB, or as an Apache Parquet (Parquet) file compressed with Snappy.

0 comments on commit 7336880

Please sign in to comment.