Skip to content

Commit

Permalink
Merge branch 'master' into hassanazharkhan/expose_esbuild_option
Browse files Browse the repository at this point in the history
  • Loading branch information
hassanazharkhan authored Dec 17, 2020
2 parents bad3c1d + d10ea63 commit e2d3f97
Show file tree
Hide file tree
Showing 7 changed files with 318 additions and 38 deletions.
74 changes: 37 additions & 37 deletions .github/workflows/issue-label-assign.yml

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions packages/@aws-cdk/aws-elasticsearch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,29 @@ const domain = new es.Domain(this, 'Domain', {

const masterUserPassword = domain.masterUserPassword;
```



## Audit logs

Audit logs can be enabled for a domain, but only when fine grained access control is enabled.

```ts
const domain = new es.Domain(this, 'Domain', {
version: es.ElasticsearchVersion.V7_1,
enforceHttps: true,
nodeToNodeEncryption: true,
encryptionAtRest: {
enabled: true,
},
fineGrainedAccessControl: {
masterUserName: 'master-user',
},
logging: {
auditLogEnabled: true,
slowSearchLogEnabled: true,
appLogEnabled: true,
slowIndexLogEnabled: true,
},
});
```
41 changes: 41 additions & 0 deletions packages/@aws-cdk/aws-elasticsearch/lib/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,21 @@ export interface LoggingOptions {
* @default - a new log group is created if app logging is enabled
*/
readonly appLogGroup?: logs.ILogGroup;

/**
* Specify if Elasticsearch audit logging should be set up.
* Requires Elasticsearch version 6.7 or later and fine grained access control to be enabled.
*
* @default - false
*/
readonly auditLogEnabled?: boolean;

/**
* Log Elasticsearch audit logs to this log group.
*
* @default - a new log group is created if audit logging is enabled
*/
readonly auditLogGroup?: logs.ILogGroup;
}

/**
Expand Down Expand Up @@ -1162,6 +1177,13 @@ export class Domain extends DomainBase implements IDomain {
*/
public readonly appLogGroup?: logs.ILogGroup;

/**
* Log group that audit logs are logged to.
*
* @attribute
*/
public readonly auditLogGroup?: logs.ILogGroup;

/**
* Master user password if fine grained access control is configured.
*/
Expand Down Expand Up @@ -1365,6 +1387,12 @@ export class Domain extends DomainBase implements IDomain {
}
}

// Validate fine grained access control enabled for audit logs, per
// https://aws.amazon.com/about-aws/whats-new/2020/09/elasticsearch-audit-logs-now-available-on-amazon-elasticsearch-service/
if (props.logging?.auditLogEnabled && !advancedSecurityEnabled) {
throw new Error('Fine-grained access control is required when audit logs publishing is enabled.');
}

let cfnVpcOptions: CfnDomain.VPCOptionsProperty | undefined;
if (props.vpcOptions) {
cfnVpcOptions = {
Expand Down Expand Up @@ -1403,6 +1431,15 @@ export class Domain extends DomainBase implements IDomain {
logGroups.push(this.appLogGroup);
};

if (props.logging?.auditLogEnabled) {
this.auditLogGroup = props.logging.auditLogGroup ??
new logs.LogGroup(this, 'AuditLogs', {
retention: logs.RetentionDays.ONE_MONTH,
});

logGroups.push(this.auditLogGroup);
};

let logGroupResourcePolicy: LogGroupResourcePolicy | null = null;
if (logGroups.length > 0) {
const logPolicyStatement = new iam.PolicyStatement({
Expand Down Expand Up @@ -1454,6 +1491,10 @@ export class Domain extends DomainBase implements IDomain {
},
nodeToNodeEncryptionOptions: { enabled: nodeToNodeEncryptionEnabled },
logPublishingOptions: {
AUDIT_LOGS: {
enabled: this.auditLogGroup != null,
cloudWatchLogsLogGroupArn: this.auditLogGroup?.logGroupArn,
},
ES_APPLICATION_LOGS: {
enabled: this.appLogGroup != null,
cloudWatchLogsLogGroupArn: this.appLogGroup?.logGroupArn,
Expand Down
201 changes: 201 additions & 0 deletions packages/@aws-cdk/aws-elasticsearch/test/domain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import '@aws-cdk/assert/jest';
import { Metric, Statistic } from '@aws-cdk/aws-cloudwatch';
import { Subnet, Vpc, EbsDeviceVolumeType } from '@aws-cdk/aws-ec2';
import * as iam from '@aws-cdk/aws-iam';
import * as logs from '@aws-cdk/aws-logs';
import { App, Stack, Duration, SecretValue } from '@aws-cdk/core';
import { Domain, ElasticsearchVersion } from '../lib';

Expand Down Expand Up @@ -47,6 +48,9 @@ test('minimal example renders correctly', () => {
Enabled: false,
},
LogPublishingOptions: {
AUDIT_LOGS: {
Enabled: false,
},
ES_APPLICATION_LOGS: {
Enabled: false,
},
Expand Down Expand Up @@ -152,6 +156,46 @@ describe('log groups', () => {
});
});

test('auditLogEnabled should create a custom log group', () => {
new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V7_4,
logging: {
auditLogEnabled: true,
},
fineGrainedAccessControl: {
masterUserName: 'username',
},
nodeToNodeEncryption: true,
encryptionAtRest: {
enabled: true,
},
enforceHttps: true,
});

expect(stack).toHaveResourceLike('AWS::Elasticsearch::Domain', {
LogPublishingOptions: {
AUDIT_LOGS: {
CloudWatchLogsLogGroupArn: {
'Fn::GetAtt': [
'DomainAuditLogs608E0FA6',
'Arn',
],
},
Enabled: true,
},
ES_APPLICATION_LOGS: {
Enabled: false,
},
SEARCH_SLOW_LOGS: {
Enabled: false,
},
INDEX_SLOW_LOGS: {
Enabled: false,
},
},
});
});

test('two domains with logging enabled can be created in same stack', () => {
new Domain(stack, 'Domain1', {
version: ElasticsearchVersion.V7_7,
Expand Down Expand Up @@ -265,6 +309,163 @@ describe('log groups', () => {
});
});

test('enabling audit logs throws without fine grained access control enabled', () => {
expect(() => new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V6_7,
logging: {
auditLogEnabled: true,
},
})).toThrow(/Fine-grained access control is required when audit logs publishing is enabled\./);
});

test('slowSearchLogGroup should use a custom log group', () => {
new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V7_4,
logging: {
slowSearchLogEnabled: true,
slowSearchLogGroup: new logs.LogGroup(stack, 'SlowSearchLogs', {
retention: logs.RetentionDays.THREE_MONTHS,
}),
},
});

expect(stack).toHaveResourceLike('AWS::Elasticsearch::Domain', {
LogPublishingOptions: {
AUDIT_LOGS: {
Enabled: false,
},
ES_APPLICATION_LOGS: {
Enabled: false,
},
SEARCH_SLOW_LOGS: {
CloudWatchLogsLogGroupArn: {
'Fn::GetAtt': [
'SlowSearchLogsE00DC2E7',
'Arn',
],
},
Enabled: true,
},
INDEX_SLOW_LOGS: {
Enabled: false,
},
},
});
});

test('slowIndexLogEnabled should use a custom log group', () => {
new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V7_4,
logging: {
slowIndexLogEnabled: true,
slowIndexLogGroup: new logs.LogGroup(stack, 'SlowIndexLogs', {
retention: logs.RetentionDays.THREE_MONTHS,
}),
},
});

expect(stack).toHaveResourceLike('AWS::Elasticsearch::Domain', {
LogPublishingOptions: {
AUDIT_LOGS: {
Enabled: false,
},
ES_APPLICATION_LOGS: {
Enabled: false,
},
SEARCH_SLOW_LOGS: {
Enabled: false,
},
INDEX_SLOW_LOGS: {
CloudWatchLogsLogGroupArn: {
'Fn::GetAtt': [
'SlowIndexLogsAD49DED0',
'Arn',
],
},
Enabled: true,
},
},
});
});

test('appLogGroup should use a custom log group', () => {
new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V7_4,
logging: {
appLogEnabled: true,
appLogGroup: new logs.LogGroup(stack, 'AppLogs', {
retention: logs.RetentionDays.THREE_MONTHS,
}),
},
});

expect(stack).toHaveResourceLike('AWS::Elasticsearch::Domain', {
LogPublishingOptions: {
AUDIT_LOGS: {
Enabled: false,
},
ES_APPLICATION_LOGS: {
CloudWatchLogsLogGroupArn: {
'Fn::GetAtt': [
'AppLogsC5DF83A6',
'Arn',
],
},
Enabled: true,
},
SEARCH_SLOW_LOGS: {
Enabled: false,
},
INDEX_SLOW_LOGS: {
Enabled: false,
},
},
});
});

test('auditLOgGroup should use a custom log group', () => {
new Domain(stack, 'Domain', {
version: ElasticsearchVersion.V7_4,
fineGrainedAccessControl: {
masterUserName: 'username',
},
nodeToNodeEncryption: true,
encryptionAtRest: {
enabled: true,
},
enforceHttps: true,
logging: {
auditLogEnabled: true,
auditLogGroup: new logs.LogGroup(stack, 'AuditLogs', {
retention: logs.RetentionDays.THREE_MONTHS,
}),
},
});

expect(stack).toHaveResourceLike('AWS::Elasticsearch::Domain', {
LogPublishingOptions: {
AUDIT_LOGS: {
CloudWatchLogsLogGroupArn: {
'Fn::GetAtt': [
'AuditLogsB945E340',
'Arn',
],
},
Enabled: true,
},
ES_APPLICATION_LOGS: {
Enabled: false,
},
SEARCH_SLOW_LOGS: {
Enabled: false,
},
INDEX_SLOW_LOGS: {
Enabled: false,
},
},
});
});

});

describe('grants', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
"Enabled": true
},
"LogPublishingOptions": {
"AUDIT_LOGS": {
"Enabled": false
},
"ES_APPLICATION_LOGS": {
"Enabled": false
},
Expand All @@ -57,4 +60,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@
"Enabled": true
},
"LogPublishingOptions": {
"AUDIT_LOGS": {
"Enabled": false
},
"ES_APPLICATION_LOGS": {
"CloudWatchLogsLogGroupArn": {
"Fn::GetAtt": [
Expand Down Expand Up @@ -431,6 +434,9 @@
"Enabled": true
},
"LogPublishingOptions": {
"AUDIT_LOGS": {
"Enabled": false
},
"ES_APPLICATION_LOGS": {
"CloudWatchLogsLogGroupArn": {
"Fn::GetAtt": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
"Enabled": true
},
"LogPublishingOptions": {
"AUDIT_LOGS": {
"Enabled": false
},
"ES_APPLICATION_LOGS": {
"Enabled": false
},
Expand Down

0 comments on commit e2d3f97

Please sign in to comment.