Skip to content

Commit 415e4a1

Browse files
authored
Merge branch 'master' into epolon/add-auto-approve-label-to-dependabot
2 parents c5ecc0d + d658525 commit 415e4a1

18 files changed

Lines changed: 514 additions & 56 deletions

File tree

packages/@aws-cdk/aws-certificatemanager/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,21 @@ new acm.DnsValidatedCertificate(this, 'CrossRegionCertificate', {
113113
});
114114
```
115115

116+
## Requesting private certificates
117+
118+
AWS Certificate Manager can create [private certificates](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html) issued by [Private Certificate Authority (PCA)](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaWelcome.html). Validation of private certificates is not necessary.
119+
120+
```ts
121+
import * as acmpca from '@aws-cdk/aws-acmpca';
122+
123+
new acm.PrivateCertificate(stack, 'PrivateCertificate', {
124+
domainName: 'test.example.com',
125+
subjectAlternativeNames: ['cool.example.com', 'test.example.net'], // optional
126+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
127+
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
128+
});
129+
```
130+
116131
## Importing
117132

118133
If you want to import an existing certificate, you can do so from its ARN:

packages/@aws-cdk/aws-certificatemanager/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './certificate';
22
export * from './dns-validated-certificate';
3+
export * from './private-certificate';
34
export * from './util';
45

56
// AWS::CertificateManager CloudFormation Resources:
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import * as acmpca from '@aws-cdk/aws-acmpca';
2+
import { Construct } from 'constructs';
3+
import { ICertificate } from './certificate';
4+
import { CertificateBase } from './certificate-base';
5+
import { CfnCertificate } from './certificatemanager.generated';
6+
7+
/**
8+
* Properties for your private certificate
9+
*/
10+
export interface PrivateCertificateProps {
11+
/**
12+
* Fully-qualified domain name to request a private certificate for.
13+
*
14+
* May contain wildcards, such as ``*.domain.com``.
15+
*/
16+
readonly domainName: string;
17+
18+
/**
19+
* Alternative domain names on your private certificate.
20+
*
21+
* Use this to register alternative domain names that represent the same site.
22+
*
23+
* @default - No additional FQDNs will be included as alternative domain names.
24+
*/
25+
readonly subjectAlternativeNames?: string[];
26+
27+
/**
28+
* Private certificate authority (CA) that will be used to issue the certificate.
29+
*/
30+
readonly certificateAuthority: acmpca.ICertificateAuthority;
31+
}
32+
33+
/**
34+
* A private certificate managed by AWS Certificate Manager
35+
*
36+
* @resource AWS::CertificateManager::Certificate
37+
*/
38+
export class PrivateCertificate extends CertificateBase implements ICertificate {
39+
/**
40+
* Import a certificate
41+
*/
42+
public static fromCertificateArn(scope: Construct, id: string, certificateArn: string): ICertificate {
43+
class Import extends CertificateBase {
44+
public readonly certificateArn = certificateArn;
45+
}
46+
47+
return new Import(scope, id);
48+
}
49+
50+
/**
51+
* The certificate's ARN
52+
*/
53+
public readonly certificateArn: string;
54+
55+
constructor(scope: Construct, id: string, props: PrivateCertificateProps) {
56+
super(scope, id);
57+
58+
const cert = new CfnCertificate(this, 'Resource', {
59+
domainName: props.domainName,
60+
subjectAlternativeNames: props.subjectAlternativeNames,
61+
certificateAuthorityArn: props.certificateAuthority.certificateAuthorityArn,
62+
});
63+
64+
this.certificateArn = cert.ref;
65+
}
66+
}

packages/@aws-cdk/aws-certificatemanager/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
"@types/jest": "^26.0.24"
8080
},
8181
"dependencies": {
82+
"@aws-cdk/aws-acmpca": "0.0.0",
8283
"@aws-cdk/aws-cloudwatch": "0.0.0",
8384
"@aws-cdk/aws-iam": "0.0.0",
8485
"@aws-cdk/aws-lambda": "0.0.0",
@@ -88,6 +89,7 @@
8889
},
8990
"homepage": "https://github.com/aws/aws-cdk",
9091
"peerDependencies": {
92+
"@aws-cdk/aws-acmpca": "0.0.0",
9193
"@aws-cdk/aws-cloudwatch": "0.0.0",
9294
"@aws-cdk/aws-iam": "0.0.0",
9395
"@aws-cdk/aws-lambda": "0.0.0",
@@ -101,7 +103,8 @@
101103
"awslint": {
102104
"exclude": [
103105
"props-physical-name:@aws-cdk/aws-certificatemanager.CertificateProps",
104-
"props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps"
106+
"props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps",
107+
"props-physical-name:@aws-cdk/aws-certificatemanager.PrivateCertificateProps"
105108
]
106109
},
107110
"stability": "stable",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import '@aws-cdk/assert-internal/jest';
2+
import * as acmpca from '@aws-cdk/aws-acmpca';
3+
import { Duration, Lazy, Stack } from '@aws-cdk/core';
4+
import { PrivateCertificate } from '../lib';
5+
6+
test('private certificate authority', () => {
7+
const stack = new Stack();
8+
9+
new PrivateCertificate(stack, 'Certificate', {
10+
domainName: 'test.example.com',
11+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
12+
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
13+
});
14+
15+
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
16+
DomainName: 'test.example.com',
17+
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
18+
});
19+
});
20+
21+
test('private certificate authority with subjectAlternativeNames', () => {
22+
const stack = new Stack();
23+
24+
new PrivateCertificate(stack, 'Certificate', {
25+
domainName: 'test.example.com',
26+
subjectAlternativeNames: ['extra.example.com'],
27+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
28+
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
29+
});
30+
31+
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
32+
DomainName: 'test.example.com',
33+
SubjectAlternativeNames: ['extra.example.com'],
34+
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
35+
});
36+
});
37+
38+
test('private certificate authority with multiple subjectAlternativeNames', () => {
39+
const stack = new Stack();
40+
41+
new PrivateCertificate(stack, 'Certificate', {
42+
domainName: 'test.example.com',
43+
subjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'],
44+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
45+
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
46+
});
47+
48+
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
49+
DomainName: 'test.example.com',
50+
SubjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'],
51+
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
52+
});
53+
});
54+
55+
test('private certificate authority with tokens', () => {
56+
const stack = new Stack();
57+
58+
const certificateAuthority = Lazy.string({
59+
produce: () => 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
60+
});
61+
62+
const domainName = Lazy.string({
63+
produce: () => 'test.example.com',
64+
});
65+
66+
const domainNameAlternative = Lazy.string({
67+
produce: () => 'extra.example.com',
68+
});
69+
70+
new PrivateCertificate(stack, 'Certificate', {
71+
domainName,
72+
subjectAlternativeNames: [domainNameAlternative],
73+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', certificateAuthority),
74+
});
75+
76+
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', {
77+
DomainName: 'test.example.com',
78+
SubjectAlternativeNames: ['extra.example.com'],
79+
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77',
80+
});
81+
});
82+
83+
test('metricDaysToExpiry', () => {
84+
const stack = new Stack();
85+
86+
const certificate = new PrivateCertificate(stack, 'Certificate', {
87+
domainName: 'test.example.com',
88+
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA',
89+
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'),
90+
});
91+
92+
expect(stack.resolve(certificate.metricDaysToExpiry().toMetricConfig())).toEqual({
93+
metricStat: {
94+
dimensions: [{ name: 'CertificateArn', value: stack.resolve(certificate.certificateArn) }],
95+
metricName: 'DaysToExpiry',
96+
namespace: 'AWS/CertificateManager',
97+
period: Duration.days(1),
98+
statistic: 'Minimum',
99+
},
100+
renderingProperties: expect.anything(),
101+
});
102+
});

packages/@aws-cdk/aws-ec2/lib/instance-types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ export enum InstanceClass {
208208
*/
209209
C5 = 'c5',
210210

211+
/**
212+
* Compute optimized instances, 6th generation
213+
*/
214+
COMPUTE6_INTEL = 'c6i',
215+
216+
/**
217+
* Compute optimized instances, 6th generation
218+
*/
219+
C6I = 'c6i',
220+
211221
/**
212222
* Compute optimized instances with local NVME drive, 5th generation
213223
*/

packages/@aws-cdk/aws-iot/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const func = new lambda.Function(this, 'MyFunction', {
5959
});
6060

6161
new iot.TopicRule(this, 'TopicRule', {
62+
topicRuleName: 'MyTopicRule', // optional
63+
description: 'invokes the lambda finction', // optional
6264
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
6365
actions: [new actions.LambdaFunctionAction(func)],
6466
});
@@ -72,3 +74,12 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
7274
});
7375
topicRule.addAction(new actions.LambdaFunctionAction(func))
7476
```
77+
78+
If you wanna make the topic rule disable, add property `enabled: false` as following:
79+
80+
```ts
81+
new iot.TopicRule(this, 'TopicRule', {
82+
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"),
83+
enabled: false,
84+
});
85+
```

packages/@aws-cdk/aws-iot/lib/topic-rule.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@ export interface TopicRuleProps {
4141
*/
4242
readonly actions?: IAction[];
4343

44+
/**
45+
* A textual description of the topic rule.
46+
*
47+
* @default None
48+
*/
49+
readonly description?: string;
50+
51+
/**
52+
* Specifies whether the rule is enabled.
53+
*
54+
* @default true
55+
*/
56+
readonly enabled?: boolean
57+
4458
/**
4559
* A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere.
4660
*
@@ -102,6 +116,8 @@ export class TopicRule extends Resource implements ITopicRule {
102116
topicRulePayload: {
103117
actions: Lazy.any({ produce: () => this.actions }),
104118
awsIotSqlVersion: sqlConfig.awsIotSqlVersion,
119+
description: props.description,
120+
ruleDisabled: props.enabled === undefined ? undefined : !props.enabled,
105121
sql: sqlConfig.sql,
106122
},
107123
});

packages/@aws-cdk/aws-iot/test/topic-rule.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,36 @@ test('can set physical name', () => {
7171
});
7272
});
7373

74+
test('can set description', () => {
75+
const stack = new cdk.Stack();
76+
77+
new iot.TopicRule(stack, 'MyTopicRule', {
78+
description: 'test-description',
79+
sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
80+
});
81+
82+
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
83+
TopicRulePayload: {
84+
Description: 'test-description',
85+
},
86+
});
87+
});
88+
89+
test('can set ruleDisabled', () => {
90+
const stack = new cdk.Stack();
91+
92+
new iot.TopicRule(stack, 'MyTopicRule', {
93+
enabled: false,
94+
sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"),
95+
});
96+
97+
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
98+
TopicRulePayload: {
99+
RuleDisabled: true,
100+
},
101+
});
102+
});
103+
74104
test.each([
75105
['fromStringAsVer20151008', iot.IotSql.fromStringAsVer20151008, '2015-10-08'],
76106
['fromStringAsVer20160323', iot.IotSql.fromStringAsVer20160323, '2016-03-23'],

packages/@aws-cdk/aws-logs/README.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,44 @@ By default, the log group will be created in the same region as the stack. The `
4848
log groups in other regions. This is typically useful when controlling retention for log groups auto-created by global services that
4949
publish their log group to a specific region, such as AWS Chatbot creating a log group in `us-east-1`.
5050

51+
## Resource Policy
52+
53+
CloudWatch Resource Policies allow other AWS services or IAM Principals to put log events into the log groups.
54+
A resource policy is automatically created when `addToResourcePolicy` is called on the LogGroup for the first time.
55+
56+
`ResourcePolicy` can also be created manually.
57+
58+
```ts
59+
const logGroup = new LogGroup(this, 'LogGroup');
60+
const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy');
61+
resourcePolicy.document.addStatements(new iam.PolicyStatement({
62+
actions: ['logs:CreateLogStream', 'logs:PutLogEvents'],
63+
principals: [new iam.ServicePrincipal('es.amazonaws.com')],
64+
resources: [logGroup.logGroupArn],
65+
}));
66+
```
67+
68+
Or more conveniently, write permissions to the log group can be granted as follows which gives same result as in the above example.
69+
70+
```ts
71+
const logGroup = new LogGroup(this, 'LogGroup');
72+
logGroup.grantWrite(iam.ServicePrincipal('es.amazonaws.com'));
73+
```
74+
75+
Optionally name and policy statements can also be passed on `ResourcePolicy` construction.
76+
77+
```ts
78+
const policyStatement = new new iam.PolicyStatement({
79+
resources: ["*"],
80+
actions: ['logs:PutLogEvents'],
81+
principals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user-name')],
82+
});
83+
const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy', {
84+
policyName: 'myResourcePolicy',
85+
policyStatements: [policyStatement],
86+
});
87+
```
88+
5189
## Encrypting Log Groups
5290

5391
By default, log group data is always encrypted in CloudWatch Logs. You have the
@@ -182,7 +220,6 @@ line.
182220
all of the terms in any of the groups (specified as arrays) matches. This is
183221
an OR match.
184222

185-
186223
Examples:
187224

188225
```ts
@@ -231,7 +268,6 @@ and then descending into it, such as `$.field` or `$.list[0].field`.
231268
given JSON patterns match. This makes an OR combination of the given
232269
patterns.
233270

234-
235271
Example:
236272

237273
```ts

0 commit comments

Comments
 (0)