Skip to content

Commit

Permalink
Merge branch 'master' into resolvable-fields
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Aug 24, 2020
2 parents abd1057 + ef98b9f commit dbdd649
Show file tree
Hide file tree
Showing 17 changed files with 228 additions and 90 deletions.
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-elasticloadbalancingv2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ and adding Targets to the Listener:
```ts
import * as ec2 from '@aws-cdk/aws-ec2';
import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2';
import * as autoscaling from '@aws-cdk/aws-autoscaling';
import { AutoScalingGroup } from '@aws-cdk/aws-autoscaling';

// ...

Expand All @@ -51,7 +51,7 @@ const listener = lb.addListener('Listener', {

// Create an AutoScaling group and add it as a load balancing
// target to the listener.
const asg = new autoscaling.AutoScalingGroup(...);
const asg = new AutoScalingGroup(...);
listener.addTargets('ApplicationFleet', {
port: 8080,
targets: [asg]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ class ImportedApplicationListener extends Resource implements IApplicationListen
// New rule
new ApplicationListenerRule(this, id, {
listener: this,
conditions: props.conditions,
hostHeader: props.hostHeader,
pathPattern: props.pathPattern,
pathPatterns: props.pathPatterns,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,38 @@ export = {
test.done();
},

'Can call addTargetGroups on imported listener with conditions prop'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'VPC');
const listener = elbv2.ApplicationListener.fromApplicationListenerAttributes(stack, 'Listener', {
listenerArn: 'ieks',
securityGroupId: 'sg-12345',
});
const group = new elbv2.ApplicationTargetGroup(stack, 'TargetGroup', { vpc, port: 80 });

// WHEN
listener.addTargetGroups('Gruuup', {
priority: 30,
conditions: [elbv2.ListenerCondition.hostHeaders(['example.com'])],
targetGroups: [group],
});

// THEN
expect(stack).to(haveResource('AWS::ElasticLoadBalancingV2::ListenerRule', {
ListenerArn: 'ieks',
Priority: 30,
Actions: [
{
TargetGroupArn: { Ref: 'TargetGroup3D7CD9B8' },
Type: 'forward',
},
],
}));

test.done();
},

'Can depend on eventual listener via TargetGroup'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/aws-rds/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,28 @@ The rotation will start as soon as this user exists.

See also [@aws-cdk/aws-secretsmanager](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-secretsmanager/README.md) for credentials rotation of existing clusters/instances.

### IAM Authentication

You can also authenticate to a database instance using AWS Identity and Access Management (IAM) database authentication;
See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html for more information
and a list of supported versions and limitations.

The following example shows enabling IAM authentication for a database instance and granting connection access to an IAM role.

```ts
const instance = new rds.DatabaseInstance(stack, 'Instance', {
engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }),
masterUsername: 'admin',
vpc,
iamAuthentication: true, // Optional - will be automatically set if you call grantConnect().
});
const role = new Role(stack, 'DBRole', { assumedBy: new AccountPrincipal(stack.account) });
instance.grantConnect(role); // Grant the role connection access to the DB.
```

**Note**: In addition to the setup above, a database user will need to be created to support IAM auth.
See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html for setup instructions.

### Metrics

Database instances expose metrics (`cloudwatch.Metric`):
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-rds/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ export interface DatabaseClusterProps {
*/
readonly defaultDatabaseName?: string;

/**
* Indicates whether the DB cluster should have deletion protection enabled.
*
* @default false
*/
readonly deletionProtection?: boolean;

/**
* Whether to enable storage encryption.
*
Expand Down Expand Up @@ -425,6 +432,7 @@ export class DatabaseCluster extends DatabaseClusterBase {
port: props.port ?? clusterEngineBindConfig.port,
dbClusterParameterGroupName: clusterParameterGroupConfig?.parameterGroupName,
associatedRoles: clusterAssociatedRoles.length > 0 ? clusterAssociatedRoles : undefined,
deletionProtection: props.deletionProtection,
// Admin
masterUsername: secret ? secret.secretValueFromJson('username').toString() : props.masterUser.username,
masterUserPassword: secret
Expand Down
25 changes: 24 additions & 1 deletion packages/@aws-cdk/aws-rds/lib/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ export interface IDatabaseInstance extends IResource, ec2.IConnectable, secretsm
*/
addProxy(id: string, options: DatabaseProxyOptions): DatabaseProxy;

/**
* Grant the given identity connection access to the database.
*/
grantConnect(grantee: iam.IGrantable): iam.Grant;

/**
* Defines a CloudWatch event rule which triggers for instance events. Use
* `rule.addEventPattern(pattern)` to specify a filter.
Expand Down Expand Up @@ -103,6 +108,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
public readonly dbInstanceEndpointAddress = attrs.instanceEndpointAddress;
public readonly dbInstanceEndpointPort = attrs.port.toString();
public readonly instanceEndpoint = new Endpoint(attrs.instanceEndpointAddress, attrs.port);
protected enableIamAuthentication = true;
}

return new Import(scope, id);
Expand All @@ -112,6 +118,7 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
public abstract readonly dbInstanceEndpointAddress: string;
public abstract readonly dbInstanceEndpointPort: string;
public abstract readonly instanceEndpoint: Endpoint;
protected abstract enableIamAuthentication?: boolean;

/**
* Access to network connections.
Expand All @@ -128,6 +135,19 @@ export abstract class DatabaseInstanceBase extends Resource implements IDatabase
});
}

public grantConnect(grantee: iam.IGrantable): iam.Grant {
if (this.enableIamAuthentication === false) {
throw new Error('Cannot grant connect when IAM authentication is disabled');
}

this.enableIamAuthentication = true;
return iam.Grant.addToPrincipal({
grantee,
actions: ['rds-db:connect'],
resourceArns: [this.instanceArn],
});
}

/**
* Defines a CloudWatch event rule which triggers for instance events. Use
* `rule.addEventPattern(pattern)` to specify a filter.
Expand Down Expand Up @@ -494,6 +514,8 @@ abstract class DatabaseInstanceNew extends DatabaseInstanceBase implements IData
private readonly cloudwatchLogsRetention?: logs.RetentionDays;
private readonly cloudwatchLogsRetentionRole?: iam.IRole;

protected enableIamAuthentication?: boolean;

constructor(scope: Construct, id: string, props: DatabaseInstanceNewProps) {
super(scope, id);

Expand Down Expand Up @@ -532,6 +554,7 @@ abstract class DatabaseInstanceNew extends DatabaseInstanceBase implements IData
this.cloudwatchLogsExports = props.cloudwatchLogsExports;
this.cloudwatchLogsRetention = props.cloudwatchLogsRetention;
this.cloudwatchLogsRetentionRole = props.cloudwatchLogsRetentionRole;
this.enableIamAuthentication = props.iamAuthentication;

this.newCfnProps = {
autoMinorVersionUpgrade: props.autoMinorVersionUpgrade,
Expand All @@ -544,7 +567,7 @@ abstract class DatabaseInstanceNew extends DatabaseInstanceBase implements IData
deleteAutomatedBackups: props.deleteAutomatedBackups,
deletionProtection,
enableCloudwatchLogsExports: this.cloudwatchLogsExports,
enableIamDatabaseAuthentication: props.iamAuthentication,
enableIamDatabaseAuthentication: Lazy.anyValue({ produce: () => this.enableIamAuthentication }),
enablePerformanceInsights: props.enablePerformanceInsights,
iops,
monitoringInterval: props.monitoringInterval && props.monitoringInterval.toSeconds(),
Expand Down
27 changes: 27 additions & 0 deletions packages/@aws-cdk/aws-rds/test/test.cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,33 @@ export = {
test.done();
},

'can set deletion protection'(test: Test) {
// GIVEN
const stack = testStack();
const vpc = new ec2.Vpc(stack, 'VPC');

// WHEN
new DatabaseCluster(stack, 'Database', {
engine: DatabaseClusterEngine.AURORA,
masterUser: {
username: 'admin',
password: cdk.SecretValue.plainText('tooshort'),
},
instanceProps: {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL),
vpc,
},
deletionProtection: true,
});

// THEN
expect(stack).to(haveResourceLike('AWS::RDS::DBCluster', {
DeletionProtection: true,
}));

test.done();
},

'does not throw (but adds a node error) if a (dummy) VPC does not have sufficient subnets'(test: Test) {
// GIVEN
const stack = testStack();
Expand Down
Loading

0 comments on commit dbdd649

Please sign in to comment.