-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
EC2: Properly handle disableApiStop in instance lifecycle #8610
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
EC2: Properly handle disableApiStop in instance lifecycle #8610
Conversation
@@ -143,7 +144,7 @@ def __init__( | |||
self.virtualization_type = ami.virtualization_type if ami else "paravirtual" | |||
self.architecture = ami.architecture if ami else "x86_64" | |||
self.root_device_name = ami.root_device_name if ami else None | |||
self.disable_api_stop = False | |||
self.disable_api_stop = kwargs.get("disable_api_stop", False) |
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 make sure this is coerced to an actual boolean value? It's confusing that the default value is False
but when you check if it's enabled you compare with == "true"
instead of is True
.
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 actually followed the same approach as for disable_api_termination
:
- https://github.com/anisaoshafi/moto/blob/9e8bc74f3610ed390e7fad4bb90af574b68dd1f1/moto/ec2/models/instances.py#L126
- https://github.com/anisaoshafi/moto/blob/9e8bc74f3610ed390e7fad4bb90af574b68dd1f1/moto/ec2/models/instances.py#L778 with
if instance.disable_api_termination == "true":
for some reason when I coerce disable_api_stop
to bool with _convert_to_bool()
, the test starts failing even though it should be straightforward 🤔
unless I'm doing sth wrong in the test or elsewhere. Could you please help me figure out if I'm missing sth?
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 attribute is always coerced to a string, if supplied. If we want Moto to always handle this as a boolean, we need to make changes in quite a few places:
- run_instances() - that's the easiest one, as it can use
_get_bool_param
- modify_instance_attribute(Attribute="disableApiStop", Value="false") - more difficult, as we currently treat all attributes (strings and booleans) the same
- modify_instance_attribute(DisableApiStop={"Value": True}) - same logic, different code path
describe_instance_attribute
- the response needs custom logic to convert True to 'true' and False to 'false' iff we're describing a boolean attribute
The last point was why you we're getting an error @anisaoshafi. boto3 expects a lower-case true
in the responses, so if Moto returns <value>True</value>
, boto3 interprets that as a False-value.
Now, ideally, if we're going to handle this attribute as a boolean, we should handle all boolean attributes as such. The other ones are: SourceDestCheck
, DisableApiTermination
, EbsOptimized
, EnaSupport
.
Which leads to another change:
5. Change describe_instances(filters=[{"Name": "source-dest-check", "Values": ["false"]}])
(and other boolean filters like it) to convert the incoming values
So in short - should it be a boolean? Yes absolutely. Do we want to do it as part of this PR? Probably not, because the list of changes is quite large, and I'm not sure if we have the test coverage for all corner cases. So I vote to merge this as-is for now, and classify this as techdebt.
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've pushed a commit with a few more assertions, just to verify all possible scenarios currently pass. This should come in handy if/when we tackle this techdebt.
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.
Thanks a lot for the very thorough clarification, @bblommers. This seems like an interesting problem, and agree that it's out of the scope of this PR.
I really appreciate that you added the extra assertions 🙏🏼 hope all the checks pass, otherwise I can handle the needed adjustments 🤞🏼
277badc
to
68c71be
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #8610 +/- ##
=======================================
Coverage 92.71% 92.71%
=======================================
Files 1242 1242
Lines 107614 107624 +10
=======================================
+ Hits 99773 99783 +10
Misses 7841 7841
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
e962afd
to
b374b12
Compare
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.
All the checks pass, so this LGTM. Thanks for the PR @anisaoshafi, and welcome to Moto! 😄
Thanks a lot, Bert and Brian for the quick reviews and support in merging this! 😄 |
Hi moto team 👋🏼
I'm opening this PR to tacke these two issues:
The EC2 parameter
DisableApiStop
is not propagated when running an instance, instead uses default (DisableApiStop=False
).This leads to inconsistencies when trying to create ec2 instances with localstack with terraform & pulumi, due to these changes not being stored in the instance so these IAC detect changes and modify the instance when running corresponding iac scripts.
On the other side, took advantage to throw the corresponding exception when trying to stop an ec2 instance that was created with
DisableApiStop=True
as that was not handled.