Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(autoscaling): enable group metrics collections #7432

Merged
merged 16 commits into from
Jul 20, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion packages/@aws-cdk/aws-autoscaling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,58 @@ about allowing connections between resources backed by instances.

To enable the max instance lifetime support, specify `maxInstanceLifetime` property
for the `AutoscalingGroup` resource. The value must be between 7 and 365 days(inclusive).
To clear a previously set value, just leave this property undefinied.
To clear a previously set value, leave this property undefined.

### Instance Monitoring

To disable detailed instance monitoring, specify `instanceMonitoring` property
for the `AutoscalingGroup` resource as `Monitoring.BASIC`. Otherwise detailed monitoring
will be enabled.

### Monitoring Group Metrics

Group metrics are used to monitor group level properties; they describe the group rather than any of its instances (e.g GroupMaxSize, the group maximum size). To enable group metrics monitoring, use the `groupMetricsCollections` property, or the `emitAllGroupMetrics` and `emitGroupMetrics` methods.
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
All Group metrics are reported in a granularity of 1 minute at no additional charge.

See [EC2 docs](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-monitoring.html#as-group-metrics) for a list of all available group metrics.

To enable group metrics monitoring using the `groupMetricsCollections` property:
NetaNir marked this conversation as resolved.
Show resolved Hide resolved

```ts
// Enable monitoring of all group metrics
new autoscaling.AutoScalingGroup(stack, 'ASG', {
groupMetricsCollections: [
{
metrics: GroupMetric.ALL,
}
]
// ...
});

// Enable monitoring for a subset of group metrics
new autoscaling.AutoScalingGroup(stack, 'ASG', {
groupMetricsCollections: [
{
metrics: [
autoscaling.GroupMetric.MIN_SIZE,
autoscaling.GroupMetric.MAX_SIZE,
]
}
],
```

Or using the emitXxx methods:

```ts
// Enable monitoring for all group metrics
asg.emitAllGroupMetrics();

// Enable monitoring for a subset of metrics
asg.emitGroupMetrics(
autoscaling.GroupMetric.MIN_SIZE,
autoscaling.GroupMetric.MAX_SIZE,
);
```

### Future work

Expand Down
129 changes: 125 additions & 4 deletions packages/@aws-cdk/aws-autoscaling/lib/auto-scaling-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export interface CommonAutoScalingGroupProps {
* it is terminated and replaced, and cannot be used again.
*
* You must specify a value of at least 604,800 seconds (7 days). To clear a previously set value,
* simply leave this property undefinied.
* leave this property undefined.
*
* @see https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-max-instance-lifetime.html
*
Expand All @@ -234,6 +234,19 @@ export interface CommonAutoScalingGroupProps {
* @default - Monitoring.DETAILED
*/
readonly instanceMonitoring?: Monitoring;

/**
* Enable monitoring for group metrics.
*
* Group metrics describe the group rather than any of its instances (e.g GroupMaxSize, the group maximum size).
* You can enable monitoring for all group metrics using `GroupMetrics.ALL` or you can specify a subset of group metrics.
*
* Group metrics are reported in a granularity of 1 minute at no additional charge.
*
* You can also use the `emitAllGroupMetrics` and `emitGroupMetrics` methods
* @default - disabled
*/
readonly groupMetricsCollections?: MetricsCollection[];
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down Expand Up @@ -288,6 +301,82 @@ export interface AutoScalingGroupProps extends CommonAutoScalingGroupProps {
readonly role?: iam.IRole;
}

/**
* Group metrics that an Auto Scaling group sends to Amazon CloudWatch.
*/
export class GroupMetric {

/**
* All available GroupMetrics.
*/
public static readonly ALL = new Array<GroupMetric>();
NetaNir marked this conversation as resolved.
Show resolved Hide resolved

NetaNir marked this conversation as resolved.
Show resolved Hide resolved
/**
* The minimum size of the Auto Scaling group
*/
public static readonly MIN_SIZE = new GroupMetric('GroupMinSize');

/**
* The maximum size of the Auto Scaling group
*/
public static readonly MAX_SIZE = new GroupMetric('GroupMaxSize');

/**
* The number of instances that the Auto Scaling group attempts to maintain
*/
public static readonly DESIRED_CAPACITY = new GroupMetric('GroupDesiredCapacity');

/**
* The number of instances that are running as part of the Auto Scaling group
* This metric does not include instances that are pending or terminating
*/
public static readonly IN_SERVICE_INSTANCES = new GroupMetric('GroupInServiceInstances');

/**
* The number of instances that are pending
* A pending instance is not yet in service, this metric does not include instances that are in service or terminating
*/
public static readonly PENDING_INSTANCES = new GroupMetric('GroupPendingInstances');

/**
* The number of instances that are in a Standby state
* Instances in this state are still running but are not actively in service
*/
public static readonly STANDBY_INSTANCES = new GroupMetric('GroupStandbyInstances');

/**
* The number of instances that are in the process of terminating
* This metric does not include instances that are in service or pending
*/
public static readonly TERMINATING_INSTANCES = new GroupMetric('GroupTerminatingInstances');

/**
* The total number of instances in the Auto Scaling group
* This metric identifies the number of instances that are in service, pending, and terminating
*/
public static readonly TOTAL_INSTANCES = new GroupMetric('GroupTotalInstances');

/**
* The name of the group metric
*/
public readonly name: string;

constructor(name: string) {
this.name = name;
}
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* A collection of group metrics
*/
export interface MetricsCollection {

/**
* The list of group metrics to monitor
*/
readonly metrics: GroupMetric[];
}
NetaNir marked this conversation as resolved.
Show resolved Hide resolved

abstract class AutoScalingGroupBase extends Resource implements IAutoScalingGroup {

public abstract autoScalingGroupName: string;
Expand Down Expand Up @@ -462,7 +551,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
public readonly userData: ec2.UserData;

/**
* The maximum spot price configured for thie autoscaling group. `undefined`
* The maximum spot price configured for the autoscaling group. `undefined`
* indicates that this group uses on-demand capacity.
*/
public readonly spotPrice?: string;
Expand All @@ -477,6 +566,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
private readonly securityGroups: ec2.ISecurityGroup[] = [];
private readonly loadBalancerNames: string[] = [];
private readonly targetGroupArns: string[] = [];
private readonly metricsCollections: MetricsCollection[] = [];
private readonly notifications: NotificationConfiguration[] = [];

constructor(scope: Construct, id: string, props: AutoScalingGroupProps) {
Expand All @@ -497,6 +587,10 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements

this.grantPrincipal = this.role;

if (props.groupMetricsCollections) {
this.metricsCollections.push(...props.groupMetricsCollections);
}

const iamProfile = new iam.CfnInstanceProfile(this, 'InstanceProfile', {
roles: [ this.role.roleName ],
});
Expand Down Expand Up @@ -584,6 +678,10 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
loadBalancerNames: Lazy.listValue({ produce: () => this.loadBalancerNames }, { omitEmpty: true }),
targetGroupArns: Lazy.listValue({ produce: () => this.targetGroupArns }, { omitEmpty: true }),
notificationConfigurations: this.renderNotificationConfiguration(),
metricsCollection: Lazy.anyValue({ produce: () => this.metricsCollections.length === 0 ? undefined : this.metricsCollections.map(mc => ({
granularity: '1Minute',
metrics: mc.metrics?.length !== 0 ? mc.metrics.map(m => m.name) : undefined,
}))}),
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
vpcZoneIdentifier: subnetIds,
healthCheckType: props.healthCheck && props.healthCheck.type,
healthCheckGracePeriod: props.healthCheck && props.healthCheck.gracePeriod && props.healthCheck.gracePeriod.toSeconds(),
Expand Down Expand Up @@ -619,6 +717,29 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements
this.securityGroups.push(securityGroup);
}

/**
* Emit all group metrics, these metrics describe the group rather than any of its instances
* see all available types https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-monitoring.html#as-group-metrics
* if granularity is not provided, 1Minute will be set
* @default - disabled
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-metricscollection.html
*/
public emitAllGroupMetrics() {
this.emitGroupMetrics(...GroupMetric.ALL);
}

/**
* Emit a specific subset of group metrics, these metrics describe the group rather than a single instance
* to emit all group metrics use \`emitAllGroupMetrics\`
* @param metrics which groups metrics to collect
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-metricscollection.html
*/
public emitGroupMetrics(...metrics: GroupMetric[]) {
NetaNir marked this conversation as resolved.
Show resolved Hide resolved
this.metricsCollections.push({
metrics,
});
}

/**
* Attach to a classic load balancer
*/
Expand Down Expand Up @@ -775,7 +896,7 @@ export interface NotificationConfiguration {
*/
export enum ScalingEvent {
/**
* Notify when an instance was launced
* Notify when an instance was launched
*/
INSTANCE_LAUNCH = 'autoscaling:EC2_INSTANCE_LAUNCH',

Expand Down Expand Up @@ -877,7 +998,7 @@ export interface RollingUpdateConfiguration {

/**
* A list of ScalingEvents, you can use one of the predefined lists, such as ScalingEvents.ERRORS
* or create a custome group by instantiating a `NotificationTypes` object, e.g: `new NotificationTypes(`NotificationType.INSTANCE_LAUNCH`)`.
* or create a custom group by instantiating a `NotificationTypes` object, e.g: `new NotificationTypes(`NotificationType.INSTANCE_LAUNCH`)`.
*/
export class ScalingEvents {
/**
Expand Down
Loading