-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
fix(ec2): instance resourceSignalTimeout overwrites initOptions.timeout #31446
base: main
Are you sure you want to change the base?
Conversation
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 pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.
A comment requesting an exemption should contain the text Exemption Request
. Additionally, if clarification is needed add Clarification Request
to a comment.
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
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.
Nice Michelle! Left some comments.
I see your fix would now be summing the two values up. This would mean that users (who haven't changed their template) would have the values updated in their next deployment if they upgrade their CDK version. This is generally a sign of breaking change, however, in this case it's extending the timeout value. I think this can be argued to be a non-breaking change. Can you include @moelasmar in the review and get his though?
timeout: props.resourceSignalTimeout && props.resourceSignalTimeout.toIsoString(), | ||
...this.instance.cfnOptions.creationPolicy?.resourceSignal, | ||
timeout: props.initOptions?.timeout ? | ||
props.resourceSignalTimeout.plus(props.initOptions?.timeout).toIsoString() : |
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.
can you double check this for me: i don't think you need the ?
on this line because typescript should be smart enough to know props.initOptions
must exist to be on this side of the ternary operator.
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.
Yes, you are right! I have updated this.
props.resourceSignalTimeout.plus(props.initOptions.timeout).toIsoString() : | ||
props.resourceSignalTimeout.toIsoString(), |
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.
although it looks safe to add the 2 numbers, but this may cause a breaking change for customers if the sum of the 2 numbers is more than 12 hours .. this should be a very rare case, but may be some customers set one of these numbers to the maximum value, and since we ignore the other one, it was working for them, but now it will stop working.
Also, I can see that the original intent was to sum these 2 numbers together based on this code
aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/instance.ts
Lines 686 to 694 in 4fa7716
private waitForResourceSignal(timeout: Duration) { | |
const oldResourceSignal = this.instance.cfnOptions.creationPolicy?.resourceSignal; | |
this.instance.cfnOptions.creationPolicy = { | |
...this.instance.cfnOptions.creationPolicy, | |
resourceSignal: { | |
count: (oldResourceSignal?.count ?? 0) + 1, | |
timeout: (oldResourceSignal?.timeout ? Duration.parse(oldResourceSignal?.timeout).plus(timeout) : timeout).toIsoString(), | |
}, | |
}; |
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 more thing it is not needed to do this change here, it is enough to change this snippet
aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/instance.ts
Lines 592 to 596 in 4fa7716
if (props.init) { | |
this.applyCloudFormationInit(props.init, props.initOptions); | |
} | |
this.applyUpdatePolicies(props); |
this.applyUpdatePolicies(props);
before the if condition
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 think you're right that it may cause breaking changes when the sum is over the max threshold. Thanks for pointing that out.
For the second point, I disagree that we put it inside if statement because users could choose not to specify props.init
and still setup the timeout value. Now if we move it inside, it won't happen anymore.
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 did not mean to put it inside the if condition, what I recommend is something like this
this.applyUpdatePolicies(props);
if (props.init) {
this.applyCloudFormationInit(props.init, props.initOptions);
}
and to remove the addition changes that @michelle-wangg added to the applyUpdatePolicies
method and depend that the addition logic is already exist in applyCloudFormationInit
method some how:
aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/instance.ts
Lines 661 to 695 in 4fa7716
public applyCloudFormationInit(init: CloudFormationInit, options: ApplyCloudFormationInitOptions = {}) { | |
init.attach(this.instance, { | |
platform: this.osType, | |
instanceRole: this.role, | |
userData: this.userData, | |
configSets: options.configSets, | |
embedFingerprint: options.embedFingerprint, | |
printLog: options.printLog, | |
ignoreFailures: options.ignoreFailures, | |
includeRole: options.includeRole, | |
includeUrl: options.includeUrl, | |
}); | |
this.waitForResourceSignal(options.timeout ?? Duration.minutes(5)); | |
} | |
/** | |
* Wait for a single additional resource signal | |
* | |
* Add 1 to the current ResourceSignal Count and add the given timeout to the current timeout. | |
* | |
* Use this to pause the CloudFormation deployment to wait for the instances | |
* in the AutoScalingGroup to report successful startup during | |
* creation and updates. The UserData script needs to invoke `cfn-signal` | |
* with a success or failure code after it is done setting up the instance. | |
*/ | |
private waitForResourceSignal(timeout: Duration) { | |
const oldResourceSignal = this.instance.cfnOptions.creationPolicy?.resourceSignal; | |
this.instance.cfnOptions.creationPolicy = { | |
...this.instance.cfnOptions.creationPolicy, | |
resourceSignal: { | |
count: (oldResourceSignal?.count ?? 0) + 1, | |
timeout: (oldResourceSignal?.timeout ? Duration.parse(oldResourceSignal?.timeout).plus(timeout) : timeout).toIsoString(), | |
}, | |
}; | |
} |
See the login in
waitForResourceSignal
, by this change we do not need to duplicate the addition logic in 2 places.
For the warning message, I also prefer to move it to the constructor after the validations.
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.
Sounds good! I have updated the implementation to use a feature flag. Since I have not changed the logic waitForResourceSignal
, even if initOptions.Timeout
is not specified and resourceSignalTimeout
is specified, the timeout will add the default 5 min to the resourceSignalTimeout.
289663d
to
1cda59c
Compare
563f7fe
to
40dbdd2
Compare
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
@@ -589,11 +590,23 @@ export class Instance extends Resource implements IInstance { | |||
this.instancePublicDnsName = this.instance.attrPublicDnsName; | |||
this.instancePublicIp = this.instance.attrPublicIp; | |||
|
|||
if (props.init) { | |||
this.applyCloudFormationInit(props.init, props.initOptions); | |||
if (props.initOptions?.timeout && props.resourceSignalTimeout) { |
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 believe if the feature flag is enabled, so no need for this warning, as this is our recommended behaviour.
@@ -581,8 +581,7 @@ | |||
], | |||
"CreationPolicy": { | |||
"ResourceSignal": { | |||
"Count": 1, |
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 believe Count
should stay in the template
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.
left minor comments, and you need to rerun the integration test cases with --update-on-failed
flag
Issue # (if applicable)
Closes #30052
Reason for this change
When specifiying both
resourceSignalTimeout
andinitOptions.timeout
in the options for creating an EC2 Instance, only the value fromresourceSignalTimeout
is used.Description of changes
initOptions.timeout
andresourceSignalTimeout
are set, timeout consisting of the sum of the values and a warning suggesting that only one field should be specifiedDescription of how you validated changes
instance-init.js
with both fields and verify that warning is loggedinitOptions.timeout
andresourceSignalTimeout
are both not set, timeout is set to default of 5 mininitOptions.timeout
set andresourceSignalTimeout
not set, timeout is set to initOptions.timeoutinitOptions.timeout
not set andresourceSignalTimeout
is set, timeout is set toresourceSignalTimeout
initOptions.timeout
andresourceSignalTimeout
are both set, timeout is set to sum of timeouts and warning is loggedChecklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license