-
Notifications
You must be signed in to change notification settings - Fork 4k
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): CloudFormation init for ASGs #9674
Conversation
Introduces CloudFormation init (cfn-init) support for autoscaling groups. This builds on the previous work (#9065) and (#9664) that introduced init support for instances. This change also reworks the existing signaling functionality, as this becomes even more important with cfn-init. A final change was to adjust the (internal) interface of the `_attach` method to accept an `ec2.OperatingSystemType` instead of the internal-only `ec2.InitPlatform` type which wasn't exported and unavailable within the asg module. This change is also in the #9664 diff, as both are pending. Credit for 90% of this goes to @rix0rrr; all cfn-init support was pair- programmed, but the ASG stuff was much more heavily done by him.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initial comments
* | ||
* @default true if you configured `signals` on the AutoScalingGroup, false otherwise | ||
*/ | ||
readonly waitOnResourceSignals?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this property necessary? wouldn't providing signal
(or not providing it) be sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well yes but the point is you can disable it for updates. I don't know why you'd want to, but CFN allows you to do so.
You'll notice the default "does the right thing", so this property is here for completeness and someone's edge case.
/** | ||
* Options for rendering UpdatePolicy | ||
*/ | ||
interface RenderUpdateOptions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this used only in an internal method, does it needs to be an interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not isn't this a nice pattern to just use everywhere?
} | ||
|
||
/** | ||
* How existing instances should be updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually control how the auto scaling group and the instance in it will be updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "how the auto scaling group will be updated" even mean? I mean, technically I guess so, but the thing you're interested in will be the instances in the ASG.
* | ||
* @default - The `timeout` configured for `signals` on the AutoScalingGroup | ||
*/ | ||
readonly pauseTime?: Duration; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this property also be deprecated in favor of the value in signals
?
Add that the max allowed value is 1hr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, the default does the right thing but CFN allows you to customize and we'll get yelled at if we don't offer the customization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to expose all L1 properties? This one feels very confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Erring on the side of caution. Again, it will just use the right default if you don't specify anything.
*/ | ||
protected doRender(options: SignalsOptions, count?: number): CfnCreationPolicy { | ||
const minSuccessfulInstancesPercent = validatePercentage(options.minSuccessPercentage); | ||
return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the validatePercentage
was already called in all calling methods?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be safe I guess?
|
||
* you *must* also specify `signals` to configure how long CloudFormation | ||
should wait for the instances to successfully configure themselves. | ||
* you *should* also specify an `updatePolicy` to configure how instances |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since updatePolicy can be used without configuring cfn init it will be helpful to add a section on it
/** | ||
* ConfigSet to activate | ||
* | ||
* @default ['default'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does default
mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The configset with the literal name "default"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading this... what is the default UpdatePolicy when you specify a CfnInit configuration?
Feels silly to have it be UpdatePolicy.none()
. I think a rollingUpdate()
with default settings makes for a good default. If we do that, we might need to add UpdatePolicy.none()
to have people be able to disable it.
Made 2 final tweaks:
Added explanations of updatepolicy/signals as requested. |
@NetaNir unless you have strong objections we should be merging this. It's been out for too long. |
Hi, In our one of our cloudformation templates we use an ASG and all two launchtemplates. If its production it defaults to launchtemplate high. And for other environments it defaults to launchtemplate low. We offer a possibility to switch to out templates when necessary using a custom portal. Does this construct support this? |
@@ -1094,7 +1096,7 @@ export class AutoScalingGroup extends AutoScalingGroupBase implements | |||
* - Update the instance's CreationPolicy to wait for `cfn-init` to finish | |||
* before reporting success. | |||
*/ | |||
private applyCloudFormationInit(init: ec2.CloudFormationInit, options: ApplyCloudFormationInitOptions = {}) { | |||
public applyCloudFormationInit(init: ec2.CloudFormationInit, options: ApplyCloudFormationInitOptions = {}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question now that this is public -- what's the behavior if I supply one init in the constructor and then call this separately? (Or call this twice, with either different or the same init
)? Should we error in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanna say they just shouldn't do that, but I guess we can add a check on it, sure.
Co-authored-by: Nick Lynch <[email protected]>
@hansterwal we don't support LaunchTemplate-based ASGs yet, so no. What you need is Unfortunately we made the lower-level API private. That's a different change though. EDIT: See #9674. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New changes look good to me!
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Introduces CloudFormation init (cfn-init) support for autoscaling groups.
This builds on the previous work (#9065) and (#9664) that introduced init
support for instances.
This change also reworks the existing signaling functionality, as this becomes
even more important with cfn-init.
A final change is to export the
CloudFormationInit._attach
method and relatedoptions.
Credit for 90% of this goes to @rix0rrr; all cfn-init support was pair-
programmed, but the ASG stuff was mostly him.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license