From 8b6fdd9445b362bae36bd3bae9c3fdfd754dad7e Mon Sep 17 00:00:00 2001 From: Markus Bergholz Date: Wed, 14 Dec 2022 14:02:17 +0100 Subject: [PATCH] rds_instance: support for gp3 (#1266) rds_instance: support for gp3 SUMMARY Fixes: #1254 ISSUE TYPE Feature Pull Request COMPONENT NAME rds_instance ADDITIONAL INFORMATION Required boto3 >= 1.26.0 Reviewed-by: Alina Buzachis Reviewed-by: Mandar Kulkarni (cherry picked from commit e56003e341f9ba37ff5e7aa77ca44f228155ec6d) --- .../1266-rds_instance_gp3_support.yaml | 3 + plugins/modules/rds_instance.py | 45 ++++++++++++++- .../roles/rds_instance/tasks/test_modify.yml | 56 +++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/1266-rds_instance_gp3_support.yaml diff --git a/changelogs/fragments/1266-rds_instance_gp3_support.yaml b/changelogs/fragments/1266-rds_instance_gp3_support.yaml new file mode 100644 index 00000000000..dd67d532dc3 --- /dev/null +++ b/changelogs/fragments/1266-rds_instance_gp3_support.yaml @@ -0,0 +1,3 @@ +--- +minor_changes: +- "rds_instance - add support for gp3 storage type (https://github.com/ansible-collections/amazon.aws/pull/1266)." diff --git a/plugins/modules/rds_instance.py b/plugins/modules/rds_instance.py index 12fabc93aac..facb02ad712 100644 --- a/plugins/modules/rds_instance.py +++ b/plugins/modules/rds_instance.py @@ -406,8 +406,17 @@ choices: - standard - gp2 + - gp3 - io1 type: str + storage_throughput: + description: + - The storage throughput when the I(storage_type) is C(gp3). + - When the allocated storage is below 400 GB, the storage throughput will always be 125 mb/s. + - When the allocated storage is large than or equal 400 GB, the througput starts at 500 mb/s. + - Requires boto3 >= 1.26.0. + type: int + version_added: 5.2.0 tde_credential_arn: description: - The ARN from the key store with which to associate the instance for Transparent Data Encryption. This is @@ -1004,6 +1013,39 @@ def get_options_with_changing_values(client, module, parameters): parameters['AllocatedStorage'] = new_allocated_storage parameters['Iops'] = new_iops + if instance.get('StorageType') == 'gp3': + if module.boto3_at_least('1.26.0'): + GP3_THROUGHPUT = True + current_storage_throughput = instance.get('PendingModifiedValues', {}).get('StorageThroughput', instance['StorageThroughput']) + new_storage_throughput = module.params.get('storage_throughput') or current_storage_throughput + if new_storage_throughput != current_storage_throughput: + parameters['StorageThroughput'] = new_storage_throughput + else: + GP3_THROUGHPUT = False + module.warn('gp3 volumes require boto3 >= 1.26.0. storage_throughput will be ignored.') + + current_iops = instance.get('PendingModifiedValues', {}).get('Iops', instance['Iops']) + # when you just change from gp2 to gp3, you may not add the iops parameter + new_iops = module.params.get('iops') or current_iops + + new_allocated_storage = module.params.get('allocated_storage') + current_allocated_storage = instance.get('PendingModifiedValues', {}).get('AllocatedStorage', instance['AllocatedStorage']) + + if current_allocated_storage != new_allocated_storage: + parameters['AllocatedStorage'] = new_allocated_storage + + if new_allocated_storage >= 400: + if new_iops < 12000: + module.fail_json(msg='IOPS must be at least 12000 when the allocated storage is larger than or equal to 400 GB.') + + if new_storage_throughput < 500 and GP3_THROUGHPUT: + module.fail_json(msg='Storage Throughput must be at least 500 when the allocated storage is larger than or equal to 400 GB.') + + if current_iops != new_iops: + parameters['Iops'] = new_iops + # must be always specified when changing iops + parameters['AllocatedStorage'] = new_allocated_storage + if parameters.get('NewDBInstanceIdentifier') and instance.get('PendingModifiedValues', {}).get('DBInstanceIdentifier'): if parameters['NewDBInstanceIdentifier'] == instance['PendingModifiedValues']['DBInstanceIdentifier'] and not apply_immediately: parameters.pop('NewDBInstanceIdentifier') @@ -1319,7 +1361,8 @@ def main(): source_engine_version=dict(), source_region=dict(), storage_encrypted=dict(type='bool'), - storage_type=dict(choices=['standard', 'gp2', 'io1']), + storage_type=dict(choices=['standard', 'gp2', 'gp3', 'io1']), + storage_throughput=dict(type='int'), tags=dict(type='dict', aliases=['resource_tags']), tde_credential_arn=dict(aliases=['transparent_data_encryption_arn']), tde_credential_password=dict(no_log=True, aliases=['transparent_data_encryption_password']), diff --git a/tests/integration/targets/rds_instance/roles/rds_instance/tasks/test_modify.yml b/tests/integration/targets/rds_instance/roles/rds_instance/tasks/test_modify.yml index 8e620333786..a5e2e13d6dd 100644 --- a/tests/integration/targets/rds_instance/roles/rds_instance/tasks/test_modify.yml +++ b/tests/integration/targets/rds_instance/roles/rds_instance/tasks/test_modify.yml @@ -76,6 +76,62 @@ # monitoring_role_arn, monitoring_interval, domain, domain_iam_role_name, cloudwatch_logs_export_configuration # ------------------------------------------------------------------------------------------ + - name: Modify the storage type without immediate application - check_mode + rds_instance: + id: '{{ instance_id }}' + state: present + storage_type: gp3 + apply_immediately: false + register: result + check_mode: yes + + - assert: + that: + - result.changed + - 'result.storage_type == "gp2"' + + - name: Modify the storage type without immediate application + rds_instance: + id: '{{ instance_id }}' + state: present + storage_type: gp3 + apply_immediately: false + register: result + + - assert: + that: + - result.changed + - 'result.pending_modified_values.storage_type == "gp3"' + - 'result.storage_type == "gp2"' + + - name: Modify the storage type without immediate application - idempotent + rds_instance: + id: '{{ instance_id }}' + state: present + storage_type: gp3 + apply_immediately: false + register: result + check_mode: yes + + - assert: + that: + - not result.changed + - 'result.pending_modified_values.storage_type == "gp3"' + - 'result.storage_type == "gp2"' + + - name: Modify the storage type back to gp2 without immediate application + rds_instance: + id: '{{ instance_id }}' + state: present + storage_type: gp2 + apply_immediately: false + register: result + + - assert: + that: + - result.changed + - 'result.pending_modified_values == {}' + - 'result.storage_type == "gp2"' - name: Modify the instance name without immediate application - check_mode rds_instance: