From d1131ab47d685fc942ff7de4731d0aa003d1e96a Mon Sep 17 00:00:00 2001 From: Lukasz Rubaszewski Date: Fri, 6 May 2022 23:36:27 +0200 Subject: [PATCH] s3_lifecycle: check that configuration is complete before returning. (#1085) s3_lifecycle: reassure that configuration is complete before returning. Get bucket lifecycle configuration a few times to make sure it is stable. It was observed that shortly (~30s) after setting the rules a method get-bucket-lifecycle-configuration returns alternatively new and old rules in a random manner. Similar issue reported for boto3 library: boto/boto3#2491 SUMMARY Fixes #1084 ISSUE TYPE Bugfix Pull Request COMPONENT NAME s3_lifecycle Reviewed-by: Mark Chappell Reviewed-by: Lukasz Rubaszewski Reviewed-by: Mark Woolley Reviewed-by: Alina Buzachis Reviewed-by: Joseph Torcasso (cherry picked from commit d802749febd7dbf30e92a6eac174aebf0ba73308) --- ...iguration-is-complete-before-returning.yml | 2 ++ plugins/modules/s3_lifecycle.py | 24 ++++++++++--- .../targets/s3_lifecycle/tasks/main.yml | 36 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/1085-s3_lifecycle-check-that-configuration-is-complete-before-returning.yml diff --git a/changelogs/fragments/1085-s3_lifecycle-check-that-configuration-is-complete-before-returning.yml b/changelogs/fragments/1085-s3_lifecycle-check-that-configuration-is-complete-before-returning.yml new file mode 100644 index 00000000000..b8d464cae78 --- /dev/null +++ b/changelogs/fragments/1085-s3_lifecycle-check-that-configuration-is-complete-before-returning.yml @@ -0,0 +1,2 @@ +bugfixes: + - s3_lifecycle - check that configuration is complete before returning (https://github.com/ansible-collections/community.aws/pull/1085). diff --git a/plugins/modules/s3_lifecycle.py b/plugins/modules/s3_lifecycle.py index 3f0bd784cef..a9aed2b29fd 100644 --- a/plugins/modules/s3_lifecycle.py +++ b/plugins/modules/s3_lifecycle.py @@ -485,15 +485,23 @@ def create_lifecycle_rule(client, module): _changed = changed _retries = 10 - while wait and _changed and _retries: + _not_changed_cnt = 6 + while wait and _changed and _retries and _not_changed_cnt: # We've seen examples where get_bucket_lifecycle_configuration returns - # the updated rules, then the old rules, then the updated rules again, + # the updated rules, then the old rules, then the updated rules again and + # again couple of times. + # Thus try to read the rule few times in a row to check if it has changed. time.sleep(5) _retries -= 1 new_rules = fetch_rules(client, module, name) (_changed, lifecycle_configuration) = compare_and_update_configuration(client, module, new_rules, new_rule) + if not _changed: + _not_changed_cnt -= 1 + _changed = True + else: + _not_changed_cnt = 6 new_rules = fetch_rules(client, module, name) @@ -531,13 +539,21 @@ def destroy_lifecycle_rule(client, module): _changed = changed _retries = 10 - while wait and _changed and _retries: + _not_changed_cnt = 6 + while wait and _changed and _retries and _not_changed_cnt: # We've seen examples where get_bucket_lifecycle_configuration returns - # the updated rules, then the old rules, then the updated rules again, + # the updated rules, then the old rules, then the updated rules again and + # again couple of times. + # Thus try to read the rule few times in a row to check if it has changed. time.sleep(5) _retries -= 1 new_rules = fetch_rules(client, module, name) (_changed, lifecycle_configuration) = compare_and_remove_rule(new_rules, rule_id, prefix) + if not _changed: + _not_changed_cnt -= 1 + _changed = True + else: + _not_changed_cnt = 6 new_rules = fetch_rules(client, module, name) diff --git a/tests/integration/targets/s3_lifecycle/tasks/main.yml b/tests/integration/targets/s3_lifecycle/tasks/main.yml index 67871545bda..4acc5c941f7 100644 --- a/tests/integration/targets/s3_lifecycle/tasks/main.yml +++ b/tests/integration/targets/s3_lifecycle/tasks/main.yml @@ -24,6 +24,42 @@ - output.changed - output.name == bucket_name - not output.requester_pays + # ============================================================ + - name: Create a number of policies and check if all of them are created + community.aws.s3_lifecycle: + name: "{{ bucket_name }}" + rule_id: "{{ item }}" + expiration_days: 10 + prefix: "{{ item }}" + status: enabled + state: present + wait: yes + register: output + loop: + - rule_1 + - rule_2 + - rule_3 + - assert: + that: + - (output.results | last).rules | length == 3 + # ============================================================ + - name: Remove previously created policies and check if all of them are removed + community.aws.s3_lifecycle: + name: "{{ bucket_name }}" + rule_id: "{{ item }}" + expiration_days: 10 + prefix: "{{ item }}" + status: enabled + state: absent + wait: yes + register: output + loop: + - rule_1 + - rule_2 + - rule_3 + - assert: + that: + - (output.results | last).rules | length == 0 # ============================================================ - name: Create a lifecycle policy s3_lifecycle: