Repository: ansible-collections/amazon.aws

Issue:
ec2_instance - deprecate purge_tags=False
Depends-On: https://github.com/ansible-collections/amazon.aws/pull/844

##### SUMMARY

Deprecate purge_tags=False for ec2_instance

##### ISSUE TYPE

- Feature Pull Request

##### COMPONENT NAME

plugins/modules/ec2_instance.py

##### ADDITIONAL INFORMATION

Add assume role functionality to aws_rds
I've basically copied the relevant functions from `aws_ec2.py`, there's nothing really new in here. 
Probably this shared functionality would be better to put in a shared module, as I've mostly just duplicated code. But still I think this is a useful first step.

##### SUMMARY
Carry over the asume role functionality from aws_ec2.py

##### ISSUE TYPE
- Feature Pull Request

##### COMPONENT NAME
aws_rds

##### ADDITIONAL INFORMATION
As I said above, I think there's some shared functionality between the EC2 and RDS inventory plugins that could be extracted into a shared module. I didn't want to make too many changes in the code, and as there was already some duplication between the two plugins, so I basically followed what was already there. i'd be happy to refactor this a bit, please let me know if that would be appreciated. 


Discussion:

I forgot to mention that this would resolve issue #30 

Resolving patch:
diff --git a/plugins/modules/rds_cluster.py b/plugins/modules/rds_cluster.py
new file mode 100644
--- /dev/null
+++ b/plugins/modules/rds_cluster.py
@@ -0,0 +1,1022 @@
+#!/usr/bin/python
+# Copyright (c) 2022 Ansible Project
+# Copyright (c) 2022 Alina Buzachis (@alinabuzachis)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+---
+module: rds_cluster
+version_added: "3.2.0"
+short_description: rds_cluster module
+description:
+    - Create, modify, and delete RDS clusters.
+extends_documentation_fragment:
+    - amazon.aws.aws
+    - amazon.aws.ec2
+    - amazon.aws.tags
+author:
+    - Sloane Hertel (@s-hertel)
+    - Alina Buzachis (@alinabuzachis)
+options:
+  # General module options
+    state:
+        description: Whether the snapshot should exist or not.
+        choices: ['present', 'absent']
+        default: 'present'
+        type: str
+    creation_source:
+        description: Which source to use if creating from a template (an existing cluster, S3 bucket, or snapshot).
+        choices: ['snapshot', 's3', 'cluster']
+        type: str
+    force_update_password:
+        description:
+          - Set to C(true) to update your cluster password with I(master_user_password).
+          - Since comparing passwords to determine if it needs to be updated is not possible this is set to C(false) by default to allow idempotence.
+        type: bool
+        default: false
+    promote:
+        description: Set to C(true) to promote a read replica cluster.
+        type: bool
+        default: false
+    purge_cloudwatch_logs_exports:
+        description:
+          - Whether or not to disable Cloudwatch logs enabled for the DB cluster that are not provided in I(enable_cloudwatch_logs_exports).
+            Set I(enable_cloudwatch_logs_exports) to an empty list to disable all.
+        type: bool
+        default: true
+    purge_security_groups:
+        description:
+          - Set to C(false) to retain any enabled security groups that aren't specified in the task and are associated with the cluster.
+          - Can be applied to I(vpc_security_group_ids)
+        type: bool
+        default: true
+    wait:
+        description: Whether to wait for the cluster to be available or deleted.
+        type: bool
+        default: true
+    # Options that have a corresponding boto3 parameter
+    apply_immediately:
+        description:
+          - A value that specifies whether modifying a cluster with I(new_db_cluster_identifier) and I(master_user_password)
+            should be applied as soon as possible, regardless of the I(preferred_maintenance_window) setting. If C(false), changes
+            are applied during the next maintenance window.
+        type: bool
+        default: false
+    availability_zones:
+        description:
+          - A list of EC2 Availability Zones that instances in the DB cluster can be created in.
+            May be used when creating a cluster or when restoring from S3 or a snapshot.
+        aliases:
+          - zones
+          - az
+        type: list
+        elements: str
+    backtrack_to:
+        description:
+          - The timestamp of the time to backtrack the DB cluster to in ISO 8601 format, such as "2017-07-08T18:00Z".
+        type: str
+    backtrack_window:
+        description:
+          - The target backtrack window, in seconds. To disable backtracking, set this value to C(0).
+          - If specified, this value must be set to a number from C(0) to C(259,200) (72 hours).
+        default: 0
+        type: int
+    backup_retention_period:
+        description:
+          - The number of days for which automated backups are retained (must be within C(1) to C(35)).
+            May be used when creating a new cluster, when restoring from S3, or when modifying a cluster.
+        type: int
+        default: 1
+    character_set_name:
+        description:
+          - The character set to associate with the DB cluster.
+        type: str
+    database_name:
+        description:
+          - The name for your database. If a name is not provided Amazon RDS will not create a database.
+        aliases:
+          - db_name
+        type: str
+    db_cluster_identifier:
+        description:
+          - The DB cluster (lowercase) identifier. The identifier must contain from 1 to 63 letters, numbers, or
+            hyphens and the first character must be a letter and may not end in a hyphen or contain consecutive hyphens.
+        aliases:
+          - cluster_id
+          - id
+          - cluster_name
+        type: str
+        required: true
+    db_cluster_parameter_group_name:
+        description:
+          - The name of the DB cluster parameter group to associate with this DB cluster.
+            If this argument is omitted when creating a cluster, the default DB cluster parameter group for the specified DB engine and version is used.
+        type: str
+    db_subnet_group_name:
+        description:
+          - A DB subnet group to associate with this DB cluster if not using the default.
+        type: str
+    enable_cloudwatch_logs_exports:
+        description:
+          - A list of log types that need to be enabled for exporting to CloudWatch Logs.
+          - Engine aurora-mysql supports C(audit), C(error), C(general) and C(slowquery).
+          - Engine aurora-postgresql supports C(postgresql).
+        type: list
+        elements: str
+    deletion_protection:
+        description:
+          -  A value that indicates whether the DB cluster has deletion protection enabled.
+             The database can't be deleted when deletion protection is enabled.
+             By default, deletion protection is disabled.
+        type: bool
+    global_cluster_identifier:
+        description:
+          -  The global cluster ID of an Aurora cluster that becomes the primary cluster in the new global database cluster.
+        type: str
+    enable_http_endpoint:
+        description:
+          -  A value that indicates whether to enable the HTTP endpoint for an Aurora Serverless DB cluster.
+             By default, the HTTP endpoint is disabled.
+        type: bool
+    copy_tags_to_snapshot:
+        description:
+          - Indicates whether to copy all tags from the DB cluster to snapshots of the DB cluster.
+            The default is not to copy them.
+        type: bool
+    domain:
+        description:
+          - The Active Directory directory ID to create the DB cluster in.
+        type: str
+    domain_iam_role_name:
+        description:
+          - Specify the name of the IAM role to be used when making API calls to the Directory Service.
+        type: str
+    enable_global_write_forwarding:
+        description:
+          - A value that indicates whether to enable this DB cluster to forward write operations to the primary cluster of an Aurora global database.
+            By default, write operations are not allowed on Aurora DB clusters that are secondary clusters in an Aurora global database.
+          - This value can be only set on Aurora DB clusters that are members of an Aurora global database.
+        type: bool
+    enable_iam_database_authentication:
+        description:
+          - Enable mapping of AWS Identity and Access Management (IAM) accounts to database accounts.
+            If this option is omitted when creating the cluster, Amazon RDS sets this to C(false).
+        type: bool
+    engine:
+        description:
+          - The name of the database engine to be used for this DB cluster. This is required to create a cluster.
+        choices:
+          - aurora
+          - aurora-mysql
+          - aurora-postgresql
+        type: str
+    engine_version:
+        description:
+          - The version number of the database engine to use.
+          - For Aurora MySQL that could be C(5.6.10a), C(5.7.12).
+          - Aurora PostgreSQL example, C(9.6.3).
+        type: str
+    final_snapshot_identifier:
+        description:
+          - The DB cluster snapshot identifier of the new DB cluster snapshot created when I(skip_final_snapshot=false).
+        type: str
+    force_backtrack:
+        description:
+          - A boolean to indicate if the DB cluster should be forced to backtrack when binary logging is enabled.
+            Otherwise, an error occurs when binary logging is enabled.
+        type: bool
+    kms_key_id:
+        description:
+          - The AWS KMS key identifier (the ARN, unless you are creating a cluster in the same account that owns the
+            KMS key, in which case the KMS key alias may be used).
+          - If I(replication_source_identifier) specifies an encrypted source Amazon RDS will use the key used toe encrypt the source.
+          - If I(storage_encrypted=true) and and I(replication_source_identifier) is not provided, the default encryption key is used.
+        type: str
+    master_user_password:
+        description:
+          - An 8-41 character password for the master database user.
+          - The password can contain any printable ASCII character except "/", """, or "@".
+          - To modify the password use I(force_password_update). Use I(apply immediately) to change
+            the password immediately, otherwise it is updated during the next maintenance window.
+        aliases:
+          - password
+        type: str
+    master_username:
+        description:
+          - The name of the master user for the DB cluster. Must be 1-16 letters or numbers and begin with a letter.
+        aliases:
+          - username
+        type: str
+    new_db_cluster_identifier:
+        description:
+          - The new DB cluster (lowercase) identifier for the DB cluster when renaming a DB cluster.
+          - The identifier must contain from 1 to 63 letters, numbers, or hyphens and the first character must be a
+            letter and may not end in a hyphen or contain consecutive hyphens.
+          - Use I(apply_immediately) to rename immediately, otherwise it is updated during the next maintenance window.
+        aliases:
+          - new_cluster_id
+          - new_id
+          - new_cluster_name
+        type: str
+    option_group_name:
+        description:
+          - The option group to associate with the DB cluster.
+        type: str
+    port:
+        description:
+          - The port number on which the instances in the DB cluster accept connections. If not specified, Amazon RDS
+            defaults this to C(3306) if the I(engine) is C(aurora) and c(5432) if the I(engine) is C(aurora-postgresql).
+        type: int
+    preferred_backup_window:
+        description:
+          - The daily time range (in UTC) of at least 30 minutes, during which automated backups are created if automated backups are
+            enabled using I(backup_retention_period). The option must be in the format of "hh24:mi-hh24:mi" and not conflict with
+            I(preferred_maintenance_window).
+        aliases:
+          - backup_window
+        type: str
+    preferred_maintenance_window:
+        description:
+          - The weekly time range (in UTC) of at least 30 minutes, during which system maintenance can occur. The option must
+            be in the format "ddd:hh24:mi-ddd:hh24:mi" where ddd is one of Mon, Tue, Wed, Thu, Fri, Sat, Sun.
+        aliases:
+          - maintenance_window
+        type: str
+    replication_source_identifier:
+        description:
+          - The Amazon Resource Name (ARN) of the source DB instance or DB cluster if this DB cluster is created as a Read Replica.
+        aliases:
+          - replication_src_id
+        type: str
+    restore_to_time:
+        description:
+          - The UTC date and time to restore the DB cluster to. Must be in the format "2015-03-07T23:45:00Z".
+          - If this is not provided while restoring a cluster, I(use_latest_restorable_time) must be.
+            May not be specified if I(restore_type) is copy-on-write.
+        type: str
+    restore_type:
+        description:
+          - The type of restore to be performed. If not provided, Amazon RDS uses full-copy.
+        choices:
+          - full-copy
+          - copy-on-write
+        type: str
+    role_arn:
+        description:
+          - The Amazon Resource Name (ARN) of the IAM role to associate with the Aurora DB cluster, for example
+            "arn:aws:iam::123456789012:role/AuroraAccessRole"
+        type: str
+    s3_bucket_name:
+        description:
+          - The name of the Amazon S3 bucket that contains the data used to create the Amazon Aurora DB cluster.
+        type: str
+    s3_ingestion_role_arn:
+        description:
+          - The Amazon Resource Name (ARN) of the AWS Identity and Access Management (IAM) role that authorizes Amazon RDS to access
+            the Amazon S3 bucket on your behalf.
+        type: str
+    s3_prefix:
+        description:
+          - The prefix for all of the file names that contain the data used to create the Amazon Aurora DB cluster.
+          - If you do not specify a SourceS3Prefix value, then the Amazon Aurora DB cluster is created by using all of the files in the Amazon S3 bucket.
+        type: str
+    skip_final_snapshot:
+        description:
+          - Whether a final DB cluster snapshot is created before the DB cluster is deleted.
+          - If this is C(false), I(final_snapshot_identifier) must be provided.
+        type: bool
+        default: false
+    snapshot_identifier:
+        description:
+          - The identifier for the DB snapshot or DB cluster snapshot to restore from.
+          - You can use either the name or the ARN to specify a DB cluster snapshot. However, you can use only the ARN to specify a DB snapshot.
+        type: str
+    source_db_cluster_identifier:
+        description:
+          - The identifier of the source DB cluster from which to restore.
+        type: str
+    source_engine:
+        description:
+          - The identifier for the database engine that was backed up to create the files stored in the Amazon S3 bucket.
+        choices:
+          - mysql
+        type: str
+    source_engine_version:
+        description:
+          - The version of the database that the backup files were created from.
+        type: str
+    source_region:
+        description:
+          - The ID of the region that contains the source for the DB cluster.
+        type: str
+    storage_encrypted:
+        description:
+          - Whether the DB cluster is encrypted.
+        type: bool
+    use_earliest_time_on_point_in_time_unavailable:
+        description:
+          - If I(backtrack_to) is set to a timestamp earlier than the earliest backtrack time, this value backtracks the DB cluster to
+            the earliest possible backtrack time. Otherwise, an error occurs.
+        type: bool
+    use_latest_restorable_time:
+        description:
+          - Whether to restore the DB cluster to the latest restorable backup time. Only one of I(use_latest_restorable_time)
+            and I(restore_to_time) may be provided.
+        type: bool
+    vpc_security_group_ids:
+        description:
+          - A list of EC2 VPC security groups to associate with the DB cluster.
+        type: list
+        elements: str
+'''
+
+EXAMPLES = r'''
+# Note: These examples do not set authentication details, see the AWS Guide for details.
+- name: Create minimal aurora cluster in default VPC and default subnet group
+  amazon.aws.rds_cluster:
+    cluster_id: "{{ cluster_id }}"
+    engine: "aurora"
+    password: "{{ password }}"
+    username: "{{ username }}"
+
+- name: Add a new security group without purge
+  amazon.aws.rds_cluster:
+    id: "{{ cluster_id }}"
+    state: present
+    vpc_security_group_ids:
+      - sg-0be17ba10c9286b0b
+    purge_security_groups: false
+
+- name: Modify password
+  amazon.aws.rds_cluster:
+    id: "{{ cluster_id }}"
+    state: present
+    password: "{{ new_password }}"
+    force_update_password: true
+    apply_immediately: true
+
+- name: Rename the cluster
+  amazon.aws.rds_cluster:
+    engine: aurora
+    password: "{{ password }}"
+    username: "{{ username }}"
+    cluster_id: "cluster-{{ resource_prefix }}"
+    new_cluster_id: "cluster-{{ resource_prefix }}-renamed"
+    apply_immediately: true
+
+- name: Delete aurora cluster without creating a final snapshot
+  amazon.aws.rds_cluster:
+    engine: aurora
+    password: "{{ password }}"
+    username: "{{ username }}"
+    cluster_id: "{{ cluster_id }}"
+    skip_final_snapshot: True
+    tags:
+      Name: "cluster-{{ resource_prefix }}"
+      Created_By: "Ansible_rds_cluster_integration_test"
+    state: absent
+
+- name: Restore cluster from source snapshot
+  amazon.aws.rds_cluster:
+    engine: aurora
+    password: "{{ password }}"
+    username: "{{ username }}"
+    cluster_id: "cluster-{{ resource_prefix }}-restored"
+    snapshot_identifier: "cluster-{{ resource_prefix }}-snapshot"
+'''
+
+RETURN = r'''
+activity_stream_status:
+  description: The status of the database activity stream.
+  returned: always
+  type: str
+  sample: stopped
+allocated_storage:
+  description:
+    - The allocated storage size in gigabytes. Since aurora storage size is not fixed this is
+      always 1 for aurora database engines.
+  returned: always
+  type: int
+  sample: 1
+associated_roles:
+  description:
+    - A list of dictionaries of the AWS Identity and Access Management (IAM) roles that are associated
+      with the DB cluster. Each dictionary contains the role_arn and the status of the role.
+  returned: always
+  type: list
+  sample: []
+availability_zones:
+  description: The list of availability zones that instances in the DB cluster can be created in.
+  returned: always
+  type: list
+  sample:
+  - us-east-1c
+  - us-east-1a
+  - us-east-1e
+backup_retention_period:
+  description: The number of days for which automatic DB snapshots are retained.
+  returned: always
+  type: int
+  sample: 1
+changed:
+  description: If the RDS cluster has changed.
+  returned: always
+  type: bool
+  sample: true
+cluster_create_time:
+  description: The time in UTC when the DB cluster was created.
+  returned: always
+  type: str
+  sample: '2018-06-29T14:08:58.491000+00:00'
+copy_tags_to_snapshot:
+  description:
+    - Specifies whether tags are copied from the DB cluster to snapshots of the DB cluster.
+  returned: always
+  type: bool
+  sample: false
+cross_account_clone:
+  description:
+    - Specifies whether the DB cluster is a clone of a DB cluster owned by a different Amazon Web Services account.
+  returned: always
+  type: bool
+  sample: false
+db_cluster_arn:
+  description: The Amazon Resource Name (ARN) for the DB cluster.
+  returned: always
+  type: str
+  sample: arn:aws:rds:us-east-1:123456789012:cluster:rds-cluster-demo
+db_cluster_identifier:
+  description: The lowercase user-supplied DB cluster identifier.
+  returned: always
+  type: str
+  sample: rds-cluster-demo
+db_cluster_members:
+  description:
+    - A list of dictionaries containing information about the instances in the cluster.
+      Each dictionary contains the db_instance_identifier, is_cluster_writer (bool),
+      db_cluster_parameter_group_status, and promotion_tier (int).
+  returned: always
+  type: list
+  sample: []
+db_cluster_parameter_group:
+  description: The parameter group associated with the DB cluster.
+  returned: always
+  type: str
+  sample: default.aurora5.6
+db_cluster_resource_id:
+  description: The AWS Region-unique, immutable identifier for the DB cluster.
+  returned: always
+  type: str
+  sample: cluster-D2MEQDN3BQNXDF74K6DQJTHASU
+db_subnet_group:
+  description: The name of the subnet group associated with the DB Cluster.
+  returned: always
+  type: str
+  sample: default
+deletion_protection:
+  description:
+    - Indicates if the DB cluster has deletion protection enabled.
+      The database can't be deleted when deletion protection is enabled.
+  returned: always
+  type: bool
+  sample: false
+domain_memberships:
+  description:
+    - The Active Directory Domain membership records associated with the DB cluster.
+  returned: always
+  type: list
+  sample: []
+earliest_restorable_time:
+  description: The earliest time to which a database can be restored with point-in-time restore.
+  returned: always
+  type: str
+  sample: '2018-06-29T14:09:34.797000+00:00'
+endpoint:
+  description: The connection endpoint for the primary instance of the DB cluster.
+  returned: always
+  type: str
+  sample: rds-cluster-demo.cluster-cvlrtwiennww.us-east-1.rds.amazonaws.com
+engine:
+  description: The database engine of the DB cluster.
+  returned: always
+  type: str
+  sample: aurora
+engine_mode:
+  description: The DB engine mode of the DB cluster.
+  returned: always
+  type: str
+  sample: provisioned
+engine_version:
+  description: The database engine version.
+  returned: always
+  type: str
+  sample: 5.6.10a
+hosted_zone_id:
+  description: The ID that Amazon Route 53 assigns when you create a hosted zone.
+  returned: always
+  type: str
+  sample: Z2R2ITUGPM61AM
+http_endpoint_enabled:
+  description:
+    - A value that indicates whether the HTTP endpoint for an Aurora Serverless DB cluster is enabled.
+  returned: always
+  type: bool
+  sample: false
+iam_database_authentication_enabled:
+  description: Whether IAM accounts may be mapped to database accounts.
+  returned: always
+  type: bool
+  sample: false
+latest_restorable_time:
+  description: The latest time to which a database can be restored with point-in-time restore.
+  returned: always
+  type: str
+  sample: '2018-06-29T14:09:34.797000+00:00'
+master_username:
+  description: The master username for the DB cluster.
+  returned: always
+  type: str
+  sample: username
+multi_az:
+  description: Whether the DB cluster has instances in multiple availability zones.
+  returned: always
+  type: bool
+  sample: false
+port:
+  description: The port that the database engine is listening on.
+  returned: always
+  type: int
+  sample: 3306
+preferred_backup_window:
+  description: The UTC weekly time range during which system maintenance can occur.
+  returned: always
+  type: str
+  sample: 10:18-10:48
+preferred_maintenance_window:
+  description: The UTC weekly time range during which system maintenance can occur.
+  returned: always
+  type: str
+  sample: tue:03:23-tue:03:53
+read_replica_identifiers:
+  description: A list of read replica ID strings associated with the DB cluster.
+  returned: always
+  type: list
+  sample: []
+reader_endpoint:
+  description: The reader endpoint for the DB cluster.
+  returned: always
+  type: str
+  sample: rds-cluster-demo.cluster-ro-cvlrtwiennww.us-east-1.rds.amazonaws.com
+status:
+  description: The status of the DB cluster.
+  returned: always
+  type: str
+  sample: available
+storage_encrypted:
+  description: Whether the DB cluster is storage encrypted.
+  returned: always
+  type: bool
+  sample: false
+tag_list:
+  description: A list of tags consisting of key-value pairs.
+  returned: always
+  type: list
+  elements: dict
+  sample: [
+    {
+      "key": "Created_By",
+      "value": "Ansible_rds_cluster_integration_test"
+    }
+  ]
+tags:
+  description: A dictionary of key value pairs.
+  returned: always
+  type: dict
+  sample: {
+    "Name": "rds-cluster-demo"
+  }
+vpc_security_groups:
+  description: A list of the DB cluster's security groups and their status.
+  returned: always
+  type: complex
+  contains:
+    status:
+      description: Status of the security group.
+      returned: always
+      type: str
+      sample: active
+    vpc_security_group_id:
+      description: Security group of the cluster.
+      returned: always
+      type: str
+      sample: sg-12345678
+'''
+
+
+try:
+    import botocore
+except ImportError:
+    pass  # caught by AnsibleAWSModule
+
+from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict
+
+from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
+from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list
+from ansible_collections.amazon.aws.plugins.module_utils.rds import wait_for_cluster_status
+from ansible_collections.amazon.aws.plugins.module_utils.rds import arg_spec_to_rds_params
+from ansible_collections.amazon.aws.plugins.module_utils.rds import get_tags
+from ansible_collections.amazon.aws.plugins.module_utils.rds import ensure_tags
+from ansible_collections.amazon.aws.plugins.module_utils.rds import call_method
+
+
+@AWSRetry.jittered_backoff(retries=10)
+def _describe_db_clusters(**params):
+    try:
+        paginator = client.get_paginator('describe_db_clusters')
+        return paginator.paginate(**params).build_full_result()['DBClusters'][0]
+    except is_boto3_error_code('DBClusterNotFoundFault'):
+        return {}
+
+
+def get_add_role_options(params_dict, cluster):
+    current_role_arns = [role['RoleArn'] for role in cluster.get('AssociatedRoles', [])]
+    role = params_dict['RoleArn']
+    if role is not None and role not in current_role_arns:
+        return {'RoleArn': role, 'DBClusterIdentifier': params_dict['DBClusterIdentifier']}
+    return {}
+
+
+def get_backtrack_options(params_dict):
+    options = ['BacktrackTo', 'DBClusterIdentifier', 'UseEarliestTimeOnPointInTimeUnavailable']
+    if params_dict['BacktrackTo'] is not None:
+        options = dict((k, params_dict[k]) for k in options if params_dict[k] is not None)
+        if 'ForceBacktrack' in params_dict:
+            options['Force'] = params_dict['ForceBacktrack']
+        return options
+    return {}
+
+
+def get_create_options(params_dict):
+    options = [
+        'AvailabilityZones', 'BacktrackWindow', 'BackupRetentionPeriod', 'PreferredBackupWindow',
+        'CharacterSetName', 'DBClusterIdentifier', 'DBClusterParameterGroupName', 'DBSubnetGroupName',
+        'DatabaseName', 'EnableCloudwatchLogsExports', 'EnableIAMDatabaseAuthentication', 'KmsKeyId',
+        'Engine', 'EngineVersion', 'PreferredMaintenanceWindow', 'MasterUserPassword', 'MasterUsername',
+        'OptionGroupName', 'Port', 'ReplicationSourceIdentifier', 'SourceRegion', 'StorageEncrypted',
+        'Tags', 'VpcSecurityGroupIds', 'EngineMode', 'ScalingConfiguration', 'DeletionProtection',
+        'EnableHttpEndpoint', 'CopyTagsToSnapshot', 'Domain', 'DomainIAMRoleName',
+        'EnableGlobalWriteForwarding',
+    ]
+
+    return dict((k, v) for k, v in params_dict.items() if k in options and v is not None)
+
+
+def get_modify_options(params_dict, force_update_password):
+    options = [
+        'ApplyImmediately', 'BacktrackWindow', 'BackupRetentionPeriod', 'PreferredBackupWindow',
+        'DBClusterIdentifier', 'DBClusterParameterGroupName', 'EnableIAMDatabaseAuthentication',
+        'EngineVersion', 'PreferredMaintenanceWindow', 'MasterUserPassword', 'NewDBClusterIdentifier',
+        'OptionGroupName', 'Port', 'VpcSecurityGroupIds', 'EnableIAMDatabaseAuthentication',
+        'CloudwatchLogsExportConfiguration', 'DeletionProtection', 'EnableHttpEndpoint',
+        'CopyTagsToSnapshot', 'EnableGlobalWriteForwarding', 'Domain', 'DomainIAMRoleName',
+    ]
+    modify_options = dict((k, v) for k, v in params_dict.items() if k in options and v is not None)
+    if not force_update_password:
+        modify_options.pop('MasterUserPassword', None)
+    return modify_options
+
+
+def get_delete_options(params_dict):
+    options = ['DBClusterIdentifier', 'FinalSnapshotIdentifier', 'SkipFinalSnapshot']
+    return dict((k, params_dict[k]) for k in options if params_dict[k] is not None)
+
+
+def get_restore_s3_options(params_dict):
+    options = [
+        'AvailabilityZones', 'BacktrackWindow', 'BackupRetentionPeriod', 'CharacterSetName',
+        'DBClusterIdentifier', 'DBClusterParameterGroupName', 'DBSubnetGroupName', 'DatabaseName',
+        'EnableCloudwatchLogsExports', 'EnableIAMDatabaseAuthentication', 'Engine', 'EngineVersion',
+        'KmsKeyId', 'MasterUserPassword', 'MasterUsername', 'OptionGroupName', 'Port',
+        'PreferredBackupWindow', 'PreferredMaintenanceWindow', 'S3BucketName', 'S3IngestionRoleArn',
+        'S3Prefix', 'SourceEngine', 'SourceEngineVersion', 'StorageEncrypted', 'Tags',
+        'VpcSecurityGroupIds', 'DeletionProtection', 'EnableHttpEndpoint', 'CopyTagsToSnapshot',
+        'Domain', 'DomainIAMRoleName',
+    ]
+
+    return dict((k, v) for k, v in params_dict.items() if k in options and v is not None)
+
+
+def get_restore_snapshot_options(params_dict):
+    options = [
+        'AvailabilityZones', 'BacktrackWindow', 'DBClusterIdentifier', 'DBSubnetGroupName',
+        'DatabaseName', 'EnableCloudwatchLogsExports', 'EnableIAMDatabaseAuthentication',
+        'Engine', 'EngineVersion', 'KmsKeyId', 'OptionGroupName', 'Port', 'SnapshotIdentifier',
+        'Tags', 'VpcSecurityGroupIds', 'DBClusterParameterGroupName', 'DeletionProtection',
+        'CopyTagsToSnapshot', 'Domain', 'DomainIAMRoleName',
+    ]
+    return dict((k, v) for k, v in params_dict.items() if k in options and v is not None)
+
+
+def get_restore_cluster_options(params_dict):
+    options = [
+        'BacktrackWindow', 'DBClusterIdentifier', 'DBSubnetGroupName', 'EnableCloudwatchLogsExports',
+        'EnableIAMDatabaseAuthentication', 'KmsKeyId', 'OptionGroupName', 'Port', 'RestoreToTime',
+        'RestoreType', 'SourceDBClusterIdentifier', 'Tags', 'UseLatestRestorableTime',
+        'VpcSecurityGroupIds', 'DeletionProtection', 'CopyTagsToSnapshot', 'Domain',
+        'DomainIAMRoleName',
+    ]
+    return dict((k, v) for k, v in params_dict.items() if k in options and v is not None)
+
+
+def get_rds_method_attribute_name(cluster):
+    state = module.params['state']
+    creation_source = module.params['creation_source']
+    method_name = None
+    method_options_name = None
+
+    if state == 'absent':
+        if cluster and cluster['Status'] not in ['deleting', 'deleted']:
+            method_name = 'delete_db_cluster'
+            method_options_name = 'get_delete_options'
+    else:
+        if cluster:
+            method_name = 'modify_db_cluster'
+            method_options_name = 'get_modify_options'
+        elif creation_source == 'snapshot':
+            method_name = 'restore_db_cluster_from_snapshot'
+            method_options_name = 'get_restore_snapshot_options'
+        elif creation_source == 's3':
+            method_name = 'restore_db_cluster_from_s3'
+            method_options_name = 'get_restore_s3_options'
+        elif creation_source == 'cluster':
+            method_name = 'restore_db_cluster_to_point_in_time'
+            method_options_name = 'get_restore_cluster_options'
+        else:
+            method_name = 'create_db_cluster'
+            method_options_name = 'get_create_options'
+
+    return method_name, method_options_name
+
+
+def add_role(params):
+    if not module.check_mode:
+        try:
+            client.add_role_to_db_cluster(**params)
+        except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
+            module.fail_json_aws(e, msg=f"Unable to add role {params['RoleArn']} to cluster {params['DBClusterIdentifier']}")
+        wait_for_cluster_status(client, module, params['DBClusterIdentifier'], 'cluster_available')
+
+
+def backtrack_cluster(params):
+    if not module.check_mode:
+        try:
+            client.backtrack_db_cluster(**params)
+        except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
+            module.fail_json_aws(e, msg=F"Unable to backtrack cluster {params['DBClusterIdentifier']}")
+        wait_for_cluster_status(client, module, params['DBClusterIdentifier'], 'cluster_available')
+
+
+def get_cluster(db_cluster_id):
+    try:
+        return _describe_db_clusters(DBClusterIdentifier=db_cluster_id)
+    except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
+        module.fail_json_aws(e, msg="Failed to describe DB clusters")
+
+
+def changing_cluster_options(modify_params, current_cluster):
+    changing_params = {}
+    apply_immediately = modify_params.pop('ApplyImmediately')
+    db_cluster_id = modify_params.pop('DBClusterIdentifier')
+
+    enable_cloudwatch_logs_export = modify_params.pop('EnableCloudwatchLogsExports', None)
+    if enable_cloudwatch_logs_export is not None:
+        desired_cloudwatch_logs_configuration = {'EnableLogTypes': [], 'DisableLogTypes': []}
+        provided_cloudwatch_logs = set(enable_cloudwatch_logs_export)
+        current_cloudwatch_logs_export = set(current_cluster['EnabledCloudwatchLogsExports'])
+
+        desired_cloudwatch_logs_configuration['EnableLogTypes'] = list(provided_cloudwatch_logs.difference(current_cloudwatch_logs_export))
+        if module.params['purge_cloudwatch_logs_exports']:
+            desired_cloudwatch_logs_configuration['DisableLogTypes'] = list(current_cloudwatch_logs_export.difference(provided_cloudwatch_logs))
+        changing_params['CloudwatchLogsExportConfiguration'] = desired_cloudwatch_logs_configuration
+
+    password = modify_params.pop('MasterUserPassword', None)
+    if password:
+        changing_params['MasterUserPassword'] = password
+
+    new_cluster_id = modify_params.pop('NewDBClusterIdentifier', None)
+    if new_cluster_id and new_cluster_id != current_cluster['DBClusterIdentifier']:
+        changing_params['NewDBClusterIdentifier'] = new_cluster_id
+
+    option_group = modify_params.pop('OptionGroupName', None)
+    if (
+        option_group and option_group not in [g['DBClusterOptionGroupName'] for g in current_cluster['DBClusterOptionGroupMemberships']]
+    ):
+        changing_params['OptionGroupName'] = option_group
+
+    vpc_sgs = modify_params.pop('VpcSecurityGroupIds', None)
+    if vpc_sgs:
+        desired_vpc_sgs = []
+        provided_vpc_sgs = set(vpc_sgs)
+        current_vpc_sgs = set([sg['VpcSecurityGroupId'] for sg in current_cluster['VpcSecurityGroups']])
+        if module.params['purge_security_groups']:
+            desired_vpc_sgs = vpc_sgs
+        else:
+            if provided_vpc_sgs - current_vpc_sgs:
+                desired_vpc_sgs = list(provided_vpc_sgs | current_vpc_sgs)
+
+        if desired_vpc_sgs:
+            changing_params['VpcSecurityGroupIds'] = desired_vpc_sgs
+
+    desired_db_cluster_parameter_group = modify_params.pop("DBClusterParameterGroupName", None)
+    if desired_db_cluster_parameter_group:
+        if desired_db_cluster_parameter_group != current_cluster["DBClusterParameterGroup"]:
+            changing_params["DBClusterParameterGroupName"] = desired_db_cluster_parameter_group
+
+    for param in modify_params:
+        if modify_params[param] != current_cluster[param]:
+            changing_params[param] = modify_params[param]
+
+    if changing_params:
+        changing_params['DBClusterIdentifier'] = db_cluster_id
+        if apply_immediately is not None:
+            changing_params['ApplyImmediately'] = apply_immediately
+
+    return changing_params
+
+
+def ensure_present(cluster, parameters, method_name, method_options_name):
+    changed = False
+
+    if not cluster:
+        if parameters.get('Tags') is not None:
+            parameters['Tags'] = ansible_dict_to_boto3_tag_list(parameters['Tags'])
+        call_method(client, module, method_name, eval(method_options_name)(parameters))
+        changed = True
+    else:
+        if get_backtrack_options(parameters):
+            backtrack_cluster(client, module, get_backtrack_options(parameters))
+            changed = True
+        else:
+            modifiable_options = eval(method_options_name)(parameters,
+                                                           force_update_password=module.params['force_update_password'])
+            modify_options = changing_cluster_options(modifiable_options, cluster)
+            if modify_options:
+                call_method(client, module, method_name, modify_options)
+                changed = True
+            if module.params['tags'] is not None:
+                existing_tags = get_tags(client, module, cluster['DBClusterArn'])
+                changed |= ensure_tags(client, module, cluster['DBClusterArn'], existing_tags, module.params['tags'],
+                                       module.params['purge_tags'])
+
+    add_role_params = get_add_role_options(parameters, cluster)
+    if add_role_params:
+        add_role(client, module, add_role_params)
+        changed = True
+
+    if module.params['promote'] and cluster.get('ReplicationSourceIdentifier'):
+        call_method(client, module, 'promote_read_replica_db_cluster', parameters={'DBClusterIdentifier': module.params['db_cluster_identifier']})
+        changed = True
+
+    return changed
+
+
+def main():
+    global module
+    global client
+
+    arg_spec = dict(
+        state=dict(choices=['present', 'absent'], default='present'),
+        creation_source=dict(type='str', choices=['snapshot', 's3', 'cluster']),
+        force_update_password=dict(type='bool', default=False),
+        promote=dict(type='bool', default=False),
+        purge_cloudwatch_logs_exports=dict(type='bool', default=True),
+        purge_tags=dict(type='bool', default=True),
+        wait=dict(type='bool', default=True),
+        purge_security_groups=dict(type='bool', default=True),
+    )
+
+    parameter_options = dict(
+        apply_immediately=dict(type='bool', default=False),
+        availability_zones=dict(type='list', elements='str', aliases=['zones', 'az']),
+        backtrack_to=dict(),
+        backtrack_window=dict(type='int'),
+        backup_retention_period=dict(type='int', default=1),
+        character_set_name=dict(),
+        database_name=dict(aliases=['db_name']),
+        db_cluster_identifier=dict(required=True, aliases=['cluster_id', 'id', 'cluster_name']),
+        db_cluster_parameter_group_name=dict(),
+        db_subnet_group_name=dict(),
+        enable_cloudwatch_logs_exports=dict(type='list', elements='str'),
+        deletion_protection=dict(type='bool'),
+        global_cluster_identifier=dict(),
+        enable_http_endpoint=dict(type='bool'),
+        copy_tags_to_snapshot=dict(type='bool'),
+        domain=dict(),
+        domain_iam_role_name=dict(),
+        enable_global_write_forwarding=dict(type='bool'),
+        enable_iam_database_authentication=dict(type='bool'),
+        engine=dict(choices=["aurora", "aurora-mysql", "aurora-postgresql"]),
+        engine_version=dict(),
+        final_snapshot_identifier=dict(),
+        force_backtrack=dict(type='bool'),
+        kms_key_id=dict(),
+        master_user_password=dict(aliases=['password'], no_log=True),
+        master_username=dict(aliases=['username']),
+        new_db_cluster_identifier=dict(aliases=['new_cluster_id', 'new_id', 'new_cluster_name']),
+        option_group_name=dict(),
+        port=dict(type='int'),
+        preferred_backup_window=dict(aliases=['backup_window']),
+        preferred_maintenance_window=dict(aliases=['maintenance_window']),
+        replication_source_identifier=dict(aliases=['replication_src_id']),
+        restore_to_time=dict(),
+        restore_type=dict(choices=['full-copy', 'copy-on-write']),
+        role_arn=dict(),
+        s3_bucket_name=dict(),
+        s3_ingestion_role_arn=dict(),
+        s3_prefix=dict(),
+        skip_final_snapshot=dict(type='bool', default=False),
+        snapshot_identifier=dict(),
+        source_db_cluster_identifier=dict(),
+        source_engine=dict(choices=['mysql']),
+        source_engine_version=dict(),
+        source_region=dict(),
+        storage_encrypted=dict(type='bool'),
+        tags=dict(type='dict', aliases=['resource_tags']),
+        use_earliest_time_on_point_in_time_unavailable=dict(type='bool'),
+        use_latest_restorable_time=dict(type='bool'),
+        vpc_security_group_ids=dict(type='list', elements='str'),
+    )
+    arg_spec.update(parameter_options)
+
+    module = AnsibleAWSModule(
+        argument_spec=arg_spec,
+        required_if=[
+            ('creation_source', 'snapshot', ('snapshot_identifier', 'engine')),
+            ('creation_source', 's3', (
+                's3_bucket_name', 'engine', 'master_username', 'master_user_password',
+                'source_engine', 'source_engine_version', 's3_ingestion_role_arn')),
+        ],
+        mutually_exclusive=[
+            ('s3_bucket_name', 'source_db_cluster_identifier', 'snapshot_identifier'),
+            ('use_latest_restorable_time', 'restore_to_time'),
+        ],
+        supports_check_mode=True
+    )
+
+    retry_decorator = AWSRetry.jittered_backoff(retries=10)
+
+    try:
+        client = module.client('rds', retry_decorator=retry_decorator)
+    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
+        module.fail_json_aws(e, msg='Failed to connect to AWS.')
+
+    module.params['db_cluster_identifier'] = module.params['db_cluster_identifier'].lower()
+    cluster = get_cluster(module.params['db_cluster_identifier'])
+
+    if module.params['new_db_cluster_identifier']:
+        module.params['new_db_cluster_identifier'] = module.params['new_db_cluster_identifier'].lower()
+
+        if get_cluster(module.params['new_db_cluster_identifier']):
+            module.fail_json(f"A new cluster ID {module.params['new_db_cluster_identifier']} was provided but it already exists")
+        if not cluster:
+            module.fail_json(f"A new cluster ID {module.params['new_db_cluster_identifier']} was provided but the cluster to be renamed does not exist")
+
+    if (
+        module.params['state'] == 'absent' and module.params['skip_final_snapshot'] is False and
+        module.params['final_snapshot_identifier'] is None
+    ):
+        module.fail_json(msg='skip_final_snapshot is False but all of the following are missing: final_snapshot_identifier')
+
+    parameters = arg_spec_to_rds_params(dict((k, module.params[k]) for k in module.params if k in parameter_options))
+
+    changed = False
+    method_name, method_options_name = get_rds_method_attribute_name(cluster)
+
+    if method_name:
+        if method_name == 'delete_db_cluster':
+            call_method(client, module, method_name, eval(method_options_name)(parameters))
+            changed = True
+        else:
+            changed |= ensure_present(cluster, parameters, method_name, method_options_name)
+
+    if not module.check_mode and module.params['new_db_cluster_identifier'] and module.params['apply_immediately']:
+        cluster_id = module.params['new_db_cluster_identifier']
+    else:
+        cluster_id = module.params['db_cluster_identifier']
+
+    result = camel_dict_to_snake_dict(get_cluster(cluster_id))
+
+    if result:
+        result['tags'] = get_tags(client, module, result['db_cluster_arn'])
+
+    module.exit_json(changed=changed, **result)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/plugins/modules/rds_cluster_info.py b/plugins/modules/rds_cluster_info.py
new file mode 100644
--- /dev/null
+++ b/plugins/modules/rds_cluster_info.py
@@ -0,0 +1,307 @@
+#!/usr/bin/python
+# Copyright (c) 2022 Ansible Project
+# Copyright (c) 2022 Alina Buzachis (@alinabuzachis)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+module: rds_cluster_info
+version_added: 3.2.0
+short_description: Obtain information about one or more RDS clusters
+description:
+  - Obtain information about one or more RDS clusters.
+options:
+    db_cluster_identifier:
+        description:
+          - The user-supplied DB cluster identifier.
+          - If this parameter is specified, information from only the specific DB cluster is returned.
+        aliases:
+          - cluster_id
+          - id
+          - cluster_name
+        type: str
+    filters:
+        description:
+            - A filter that specifies one or more DB clusters to describe.
+              See U(https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBClusters.html).
+        type: dict
+author:
+    - Alina Buzachis (@alinabuzachis)
+extends_documentation_fragment:
+- amazon.aws.aws
+- amazon.aws.ec2
+
+'''
+
+EXAMPLES = r'''
+- name: Get info of all existing DB clusters
+  amazon.aws.rds_cluster_info:
+  register: _result_cluster_info
+
+- name: Get info on a specific DB cluster
+  amazon.aws.rds_cluster_info:
+    cluster_id: "{{ cluster_id }}"
+  register: _result_cluster_info
+
+- name: Get info all DB clusters with specific engine
+  amazon.aws.rds_cluster_info:
+    engine: "aurora"
+  register: _result_cluster_info
+'''
+
+RETURN = r'''
+clusters:
+  description: List of RDS clusters.
+  returned: always
+  type: list
+  contains:
+    activity_stream_status:
+        description: The status of the database activity stream.
+        type: str
+        sample: stopped
+    allocated_storage:
+        description:
+        - The allocated storage size in gigabytes. Since aurora storage size is not fixed this is
+          always 1 for aurora database engines.
+        type: int
+        sample: 1
+    associated_roles:
+        description:
+        - A list of dictionaries of the AWS Identity and Access Management (IAM) roles that are associated
+          with the DB cluster. Each dictionary contains the role_arn and the status of the role.
+        type: list
+        sample: []
+    availability_zones:
+        description: The list of availability zones that instances in the DB cluster can be created in.
+        type: list
+        sample:
+        - us-east-1c
+        - us-east-1a
+        - us-east-1e
+    backup_retention_period:
+        description: The number of days for which automatic DB snapshots are retained.
+        type: int
+        sample: 1
+    cluster_create_time:
+        description: The time in UTC when the DB cluster was created.
+        type: str
+        sample: '2018-06-29T14:08:58.491000+00:00'
+    copy_tags_to_snapshot:
+        description:
+        - Specifies whether tags are copied from the DB cluster to snapshots of the DB cluster.
+        type: bool
+        sample: false
+    cross_account_clone:
+        description:
+        - Specifies whether the DB cluster is a clone of a DB cluster owned by a different Amazon Web Services account.
+        type: bool
+        sample: false
+    db_cluster_arn:
+        description: The Amazon Resource Name (ARN) for the DB cluster.
+        type: str
+        sample: arn:aws:rds:us-east-1:123456789012:cluster:rds-cluster-demo
+    db_cluster_identifier:
+        description: The lowercase user-supplied DB cluster identifier.
+        type: str
+        sample: rds-cluster-demo
+    db_cluster_members:
+        description:
+        - A list of dictionaries containing information about the instances in the cluster.
+          Each dictionary contains the I(db_instance_identifier), I(is_cluster_writer) (bool),
+          I(db_cluster_parameter_group_status), and I(promotion_tier) (int).
+        type: list
+        sample: []
+    db_cluster_parameter_group:
+        description: The parameter group associated with the DB cluster.
+        type: str
+        sample: default.aurora5.6
+    db_cluster_resource_id:
+        description: The AWS Region-unique, immutable identifier for the DB cluster.
+        type: str
+        sample: cluster-D2MEQDN3BQNXDF74K6DQJTHASU
+    db_subnet_group:
+        description: The name of the subnet group associated with the DB Cluster.
+        type: str
+        sample: default
+    deletion_protection:
+        description:
+        - Indicates if the DB cluster has deletion protection enabled.
+          The database can't be deleted when deletion protection is enabled.
+        type: bool
+        sample: false
+    domain_memberships:
+        description:
+        - The Active Directory Domain membership records associated with the DB cluster.
+        type: list
+        sample: []
+    earliest_restorable_time:
+        description: The earliest time to which a database can be restored with point-in-time restore.
+        type: str
+        sample: '2018-06-29T14:09:34.797000+00:00'
+    endpoint:
+        description: The connection endpoint for the primary instance of the DB cluster.
+        type: str
+        sample: rds-cluster-demo.cluster-cvlrtwiennww.us-east-1.rds.amazonaws.com
+    engine:
+        description: The database engine of the DB cluster.
+        type: str
+        sample: aurora
+    engine_mode:
+        description: The DB engine mode of the DB cluster.
+        type: str
+        sample: provisioned
+    engine_version:
+        description: The database engine version.
+        type: str
+        sample: 5.6.10a
+    hosted_zone_id:
+        description: The ID that Amazon Route 53 assigns when you create a hosted zone.
+        type: str
+        sample: Z2R2ITUGPM61AM
+    http_endpoint_enabled:
+        description:
+        - A value that indicates whether the HTTP endpoint for an Aurora Serverless DB cluster is enabled.
+        type: bool
+        sample: false
+    iam_database_authentication_enabled:
+        description: Whether IAM accounts may be mapped to database accounts.
+        type: bool
+        sample: false
+    latest_restorable_time:
+        description: The latest time to which a database can be restored with point-in-time restore.
+        type: str
+        sample: '2018-06-29T14:09:34.797000+00:00'
+    master_username:
+        description: The master username for the DB cluster.
+        type: str
+        sample: username
+    multi_az:
+        description: Whether the DB cluster has instances in multiple availability zones.
+        type: bool
+        sample: false
+    port:
+        description: The port that the database engine is listening on.
+        type: int
+        sample: 3306
+    preferred_backup_window:
+        description: The UTC weekly time range during which system maintenance can occur.
+        type: str
+        sample: 10:18-10:48
+    preferred_maintenance_window:
+        description: The UTC weekly time range during which system maintenance can occur.
+        type: str
+        sample: tue:03:23-tue:03:53
+    read_replica_identifiers:
+        description: A list of read replica ID strings associated with the DB cluster.
+        type: list
+        sample: []
+    reader_endpoint:
+        description: The reader endpoint for the DB cluster.
+        type: str
+        sample: rds-cluster-demo.cluster-ro-cvlrtwiennww.us-east-1.rds.amazonaws.com
+    status:
+        description: The status of the DB cluster.
+        type: str
+        sample: available
+    storage_encrypted:
+        description: Whether the DB cluster is storage encrypted.
+        type: bool
+        sample: false
+    tag_list:
+        description: A list of tags consisting of key-value pairs.
+        type: list
+        elements: dict
+        sample: [
+            {
+                "key": "Created_By",
+                "value": "Ansible_rds_cluster_integration_test"
+            }
+        ]
+    tags:
+        description: A dictionary of key value pairs.
+        type: dict
+        sample: {
+            "Name": "rds-cluster-demo"
+        }
+    vpc_security_groups:
+        description: A list of the DB cluster's security groups and their status.
+        type: complex
+        contains:
+            status:
+                description: Status of the security group.
+                type: str
+                sample: active
+            vpc_security_group_id:
+                description: Security group of the cluster.
+                type: str
+                sample: sg-12345678
+'''
+
+
+try:
+    import botocore
+except ImportError:
+    pass  # handled by AnsibleAWSModule
+
+from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
+from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict
+from ansible_collections.amazon.aws.plugins.module_utils.rds import get_tags
+
+
+@AWSRetry.jittered_backoff(retries=10)
+def _describe_db_clusters(client, **params):
+    try:
+        paginator = client.get_paginator('describe_db_clusters')
+        return paginator.paginate(**params).build_full_result()['DBClusters']
+    except is_boto3_error_code('DBClusterNotFoundFault'):
+        return []
+
+
+def cluster_info(client, module):
+    cluster_id = module.params.get('db_cluster_identifier')
+    filters = module.params.get('filters')
+
+    params = dict()
+    if cluster_id:
+        params['DBClusterIdentifier'] = cluster_id
+    if filters:
+        params['Filters'] = ansible_dict_to_boto3_filter_list(filters)
+
+    try:
+        result = _describe_db_clusters(client, **params)
+    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
+        module.fail_json_aws(e, "Couldn't get RDS cluster information.")
+
+    for cluster in result:
+        cluster['Tags'] = get_tags(client, module, cluster['DBClusterArn'])
+
+    return dict(changed=False, clusters=[camel_dict_to_snake_dict(cluster, ignore_list=['Tags']) for cluster in result])
+
+
+def main():
+    argument_spec = dict(
+        db_cluster_identifier=dict(aliases=['cluster_id', 'id', 'cluster_name']),
+        filters=dict(type='dict'),
+    )
+
+    module = AnsibleAWSModule(
+        argument_spec=argument_spec,
+        supports_check_mode=True,
+    )
+
+    try:
+        client = module.client('rds', retry_decorator=AWSRetry.jittered_backoff(retries=10))
+    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
+        module.fail_json_aws(e, msg='Failed to connect to AWS.')
+
+    module.exit_json(**cluster_info(client, module))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/plugins/modules/rds_cluster_snapshot.py b/plugins/modules/rds_cluster_snapshot.py
new file mode 100644
--- /dev/null
+++ b/plugins/modules/rds_cluster_snapshot.py
@@ -0,0 +1,372 @@
+#!/usr/bin/python
+# Copyright (c) 2014 Ansible Project
+# Copyright (c) 2021 Alina Buzachis (@alinabuzachis)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = r'''
+---
+module: rds_cluster_snapshot
+version_added: 4.0.0
+short_description: Manage Amazon RDS snapshots of DB clusters
+description:
+  - Create, modify and delete RDS snapshots of DB clusters.
+options:
+  state:
+    description:
+      - Specify the desired state of the snapshot.
+    default: present
+    choices: [ 'present', 'absent']
+    type: str
+  db_cluster_snapshot_identifier:
+    description:
+      - The identifier of the DB cluster snapshot.
+    required: true
+    aliases:
+      - snapshot_id
+      - id
+      - snapshot_name
+    type: str
+  db_cluster_identifier:
+    description:
+      - The identifier of the DB cluster to create a snapshot for.
+      - Required when I(state=present).
+    aliases:
+      - cluster_id
+      - cluster_name
+    type: str
+  source_db_cluster_snapshot_identifier:
+     description:
+      - The identifier of the DB cluster snapshot to copy.
+      - If the source snapshot is in the same AWS region as the copy, specify the snapshot's identifier.
+      - If the source snapshot is in a different AWS region as the copy, specify the snapshot's ARN.
+     aliases:
+      - source_id
+      - source_snapshot_id
+     type: str
+  source_region:
+    description:
+      - The region that contains the snapshot to be copied.
+    type: str
+  copy_tags:
+    description:
+      - Whether to copy all tags from I(source_db_cluster_snapshot_identifier) to I(db_cluster_snapshot_identifier).
+    type: bool
+    default: False
+  wait:
+    description:
+      - Whether or not to wait for snapshot creation or deletion.
+    type: bool
+    default: false
+  wait_timeout:
+    description:
+      - How long before wait gives up, in seconds.
+    default: 300
+    type: int
+notes:
+  - Retrieve the information about a specific DB cluster or list the DB cluster snapshots for a specific DB cluster
+    can de done using M(community.aws.rds_snapshot_info).
+author:
+  - Alina Buzachis (@alinabuzachis)
+extends_documentation_fragment:
+  - amazon.aws.aws
+  - amazon.aws.ec2
+  - amazon.aws.tags
+'''
+
+EXAMPLES = r'''
+- name: Create a DB cluster snapshot
+  amazon.aws.rds_cluster_snapshot:
+    db_cluster_identifier: "{{ cluster_id }}"
+    db_cluster_snapshot_identifier: new-cluster-snapshot
+
+- name: Delete a DB cluster snapshot
+  amazon.aws.rds_cluster_snapshot:
+    db_cluster_snapshot_identifier: new-cluster-snapshot
+    state: absent
+
+- name: Copy snapshot from a different region and copy its tags
+  amazon.aws.rds_cluster_snapshot:
+    id: new-database-snapshot-copy
+    region: us-east-1
+    source_id: "{{ snapshot.db_snapshot_arn }}"
+    source_region: us-east-2
+    copy_tags: true
+'''
+
+RETURN = r'''
+availability_zone:
+  description: Availability zone of the database from which the snapshot was created.
+  returned: always
+  type: str
+  sample: us-west-2a
+db_cluster_snapshot_identifier:
+  description: Specifies the identifier for the DB cluster snapshot.
+  returned: always
+  type: str
+  sample: ansible-test-16638696-test-snapshot
+db_cluster_identifier:
+  description: Specifies the DB cluster identifier of the DB cluster that this DB cluster snapshot was created from.
+  returned: always
+  type: str
+  sample: ansible-test-16638696
+snapshot_create_time:
+  description: Provides the time when the snapshot was taken, in Universal Coordinated Time (UTC).
+  returned: always
+  type: str
+  sample: '2019-06-15T10:46:23.776000+00:00'
+engine:
+  description: Specifies the name of the database engine for this DB cluster snapshot.
+  returned: always
+  type: str
+  sample: "aurora"
+engine_mode:
+  description: Provides the engine mode of the database engine for this DB cluster snapshot.
+  returned: always
+  type: str
+  sample: "5.6.mysql_aurora.1.22.5"
+allocated_storage:
+  description: Specifies the allocated storage size in gibibytes (GiB).
+  returned: always
+  type: int
+  sample: 20
+status:
+  description: Specifies the status of this DB cluster snapshot.
+  returned: always
+  type: str
+  sample: available
+port:
+  description: Port on which the database is listening.
+  returned: always
+  type: int
+  sample: 3306
+vpc_id:
+  description: ID of the VPC in which the DB lives.
+  returned: always
+  type: str
+  sample: vpc-09ff232e222710ae0
+cluster_create_time:
+  description: Specifies the time when the DB cluster was created, in Universal Coordinated Time (UTC).
+  returned: always
+  type: str
+  sample: '2019-06-15T10:15:56.221000+00:00'
+master_username:
+  description: Provides the master username for this DB cluster snapshot.
+  returned: always
+  type: str
+  sample: test
+engine_version:
+  description: Version of the cluster from which the snapshot was created.
+  returned: always
+  type: str
+  sample: "5.6.mysql_aurora.1.22.5"
+license_model:
+  description: Provides the license model information for this DB cluster snapshot.
+  returned: always
+  type: str
+  sample: general-public-license
+snapshot_type:
+  description: How the snapshot was created (always manual for this module!).
+  returned: always
+  type: str
+  sample: manual
+percent_progress:
+  description: Specifies the percentage of the estimated data that has been transferred.
+  returned: always
+  type: int
+  sample: 100
+storage_encrypted:
+  description: Specifies whether the DB cluster snapshot is encrypted.
+  returned: always
+  type: bool
+  sample: false
+kms_key_id:
+  description: The Amazon Web Services KMS key identifier is the key ARN, key ID, alias ARN, or alias name for the KMS key.
+  returned: always
+  type: str
+db_cluster_snapshot_arn:
+  description: Amazon Resource Name for the snapshot.
+  returned: always
+  type: str
+  sample: arn:aws:rds:us-west-2:123456789012:snapshot:ansible-test-16638696-test-snapshot
+source_db_cluster_snapshot_arn:
+  description: If the DB cluster snapshot was copied from a source DB cluster snapshot, the ARN for the source DB cluster snapshot, otherwise, null.
+  returned: always
+  type: str
+  sample: null
+iam_database_authentication_enabled:
+  description: Whether IAM database authentication is enabled.
+  returned: always
+  type: bool
+  sample: false
+tag_list:
+  description: A list of tags.
+  returned: always
+  type: list
+  sample: []
+tags:
+  description: Tags applied to the snapshot.
+  returned: always
+  type: complex
+  contains: {}
+'''
+
+try:
+    import botocore
+except ImportError:
+    pass  # caught by AnsibleAWSModule
+
+from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
+from ansible_collections.amazon.aws.plugins.module_utils.core import is_boto3_error_code
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict
+from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_tag_list
+from ansible_collections.amazon.aws.plugins.module_utils.rds import get_tags
+from ansible_collections.amazon.aws.plugins.module_utils.rds import ensure_tags
+from ansible_collections.amazon.aws.plugins.module_utils.rds import call_method
+from ansible_collections.amazon.aws.plugins.module_utils.core import get_boto3_client_method_parameters
+from ansible_collections.amazon.aws.plugins.module_utils.rds import get_rds_method_attribute
+from ansible_collections.amazon.aws.plugins.module_utils.rds import arg_spec_to_rds_params
+
+
+def get_snapshot(snapshot_id):
+    try:
+        snapshot = client.describe_db_cluster_snapshots(DBClusterSnapshotIdentifier=snapshot_id, aws_retry=True)["DBClusterSnapshots"][0]
+        snapshot["Tags"] = get_tags(client, module, snapshot["DBClusterSnapshotArn"])
+    except is_boto3_error_code("DBClusterSnapshotNotFound"):
+        return {}
+    except is_boto3_error_code("DBClusterSnapshotNotFoundFault"):  # pylint: disable=duplicate-except
+        return {}
+    except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:  # pylint: disable=duplicate-except
+        module.fail_json_aws(e, msg="Couldn't get snapshot {0}".format(snapshot_id))
+    return snapshot
+
+
+def get_parameters(parameters, method_name):
+    if method_name == 'copy_db_cluster_snapshot':
+        parameters['TargetDBClusterSnapshotIdentifier'] = module.params['db_cluster_snapshot_identifier']
+
+    required_options = get_boto3_client_method_parameters(client, method_name, required=True)
+    if any(parameters.get(k) is None for k in required_options):
+        module.fail_json(msg='To {0} requires the parameters: {1}'.format(
+            get_rds_method_attribute(method_name, module).operation_description, required_options))
+    options = get_boto3_client_method_parameters(client, method_name)
+    parameters = dict((k, v) for k, v in parameters.items() if k in options and v is not None)
+
+    return parameters
+
+
+def ensure_snapshot_absent():
+    snapshot_name = module.params.get("db_cluster_snapshot_identifier")
+    params = {"DBClusterSnapshotIdentifier": snapshot_name}
+    changed = False
+
+    snapshot = get_snapshot(snapshot_name)
+    if not snapshot:
+        module.exit_json(changed=changed)
+    elif snapshot and snapshot["Status"] != "deleting":
+        snapshot, changed = call_method(client, module, "delete_db_cluster_snapshot", params)
+
+    module.exit_json(changed=changed)
+
+
+def copy_snapshot(params):
+    changed = False
+    snapshot_id = module.params.get('db_cluster_snapshot_identifier')
+    snapshot = get_snapshot(snapshot_id)
+
+    if not snapshot:
+        method_params = get_parameters(params, 'copy_db_cluster_snapshot')
+        if method_params.get('Tags'):
+            method_params['Tags'] = ansible_dict_to_boto3_tag_list(method_params['Tags'])
+        result, changed = call_method(client, module, 'copy_db_cluster_snapshot', method_params)
+
+    return changed
+
+
+def ensure_snapshot_present(params):
+    source_id = module.params.get('source_db_cluster_snapshot_identifier')
+    snapshot_name = module.params.get("db_cluster_snapshot_identifier")
+    changed = False
+
+    snapshot = get_snapshot(snapshot_name)
+
+    # Copy snapshot
+    if source_id:
+        changed |= copy_snapshot(params)
+
+    # Create snapshot
+    elif not snapshot:
+        changed |= create_snapshot(params)
+
+    # Snapshot exists and we're not creating a copy - modify exising snapshot
+    else:
+        changed |= modify_snapshot()
+
+    snapshot = get_snapshot(snapshot_name)
+    module.exit_json(changed=changed, **camel_dict_to_snake_dict(snapshot, ignore_list=['Tags']))
+
+
+def create_snapshot(params):
+    method_params = get_parameters(params, 'create_db_cluster_snapshot')
+    if method_params.get('Tags'):
+        method_params['Tags'] = ansible_dict_to_boto3_tag_list(method_params['Tags'])
+    snapshot, changed = call_method(client, module, 'create_db_cluster_snapshot', method_params)
+
+    return changed
+
+
+def modify_snapshot():
+    # TODO - add other modifications aside from purely tags
+    changed = False
+    snapshot_id = module.params.get('db_cluster_snapshot_identifier')
+    snapshot = get_snapshot(snapshot_id)
+
+    if module.params.get('tags'):
+        changed |= ensure_tags(client, module, snapshot['DBClusterSnapshotArn'], snapshot['Tags'], module.params['tags'], module.params['purge_tags'])
+
+    return changed
+
+
+def main():
+    global client
+    global module
+
+    argument_spec = dict(
+        state=dict(type='str', choices=['present', 'absent'], default='present'),
+        db_cluster_snapshot_identifier=dict(type='str', aliases=['id', 'snapshot_id', 'snapshot_name'], required=True),
+        db_cluster_identifier=dict(type='str', aliases=['cluster_id', 'cluster_name']),
+        source_db_cluster_snapshot_identifier=dict(type='str', aliases=['source_id', 'source_snapshot_id']),
+        wait=dict(type='bool', default=False),
+        wait_timeout=dict(type='int', default=300),
+        tags=dict(type='dict', aliases=['resource_tags']),
+        purge_tags=dict(type='bool', default=True),
+        copy_tags=dict(type='bool', default=False),
+        source_region=dict(type='str'),
+    )
+
+    module = AnsibleAWSModule(
+        argument_spec=argument_spec,
+        supports_check_mode=True,
+    )
+
+    retry_decorator = AWSRetry.jittered_backoff(retries=10)
+    try:
+        client = module.client('rds', retry_decorator=retry_decorator)
+    except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
+        module.fail_json_aws(e, msg="Failed to connect to AWS.")
+
+    state = module.params.get("state")
+
+    if state == "absent":
+        ensure_snapshot_absent()
+    elif state == "present":
+        params = arg_spec_to_rds_params(dict((k, module.params[k]) for k in module.params if k in argument_spec))
+        ensure_snapshot_present(params)
+
+
+if __name__ == '__main__':
+    main()


Test patch:
diff --git a/tests/integration/targets/rds_cluster/aliases b/tests/integration/targets/rds_cluster/aliases
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/aliases
@@ -0,0 +1,3 @@
+cloud/aws
+
+rds_cluster_info
diff --git a/tests/integration/targets/rds_cluster/inventory b/tests/integration/targets/rds_cluster/inventory
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/inventory
@@ -0,0 +1,23 @@
+[tests]
+# basic rds_cluster cretion tests
+create
+
+# restore cluster tests
+restore
+
+# TODO: Cannot be tested in the CI because:
+# An error occurred (InvalidParameterValue) when calling the CreateDBCluster operation: Replication from cluster in same region is not supported
+# promote
+
+# security groups db tests
+create_sgs
+
+# basic modify operations applied on the rds cluster
+modify
+
+# tag rds cluster test
+tag
+
+[all:vars]
+ansible_connection=local
+ansible_python_interpreter="{{ ansible_playbook_python }}"
diff --git a/tests/integration/targets/rds_cluster/main.yml b/tests/integration/targets/rds_cluster/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/main.yml
@@ -0,0 +1,10 @@
+# Beware: most of our tests here are run in parallel.
+# To add new tests you'll need to add a new host to the inventory and a matching
+# '{{ inventory_hostname }}'.yml file in roles/rds_cluster/tasks/
+
+- hosts: all
+  gather_facts: no
+  strategy: free
+  serial: 6
+  roles:
+  - rds_cluster
diff --git a/tests/integration/targets/rds_cluster/meta/main.yml b/tests/integration/targets/rds_cluster/meta/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/meta/main.yml
@@ -0,0 +1 @@
+dependencies: []
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/defaults/main.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/defaults/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/defaults/main.yml
@@ -0,0 +1,37 @@
+# defaults file for rds_cluster
+
+# Create cluster
+cluster_id: ansible-test-{{ inventory_hostname | replace('_','-') }}{{ tiny_prefix
+  }}
+username: testrdsusername
+password: test-rds_password
+engine: aurora
+port: 3306
+tags_create:
+  Name: ansible-test-cluster-{{ tiny_prefix }}
+  Created_By: Ansible_rds_cluster_integration_test
+
+# Modify cluster
+new_cluster_id: ansible-test-cluster-{{ tiny_prefix }}-new
+new_port: 1155
+new_password: test-rds_password-new
+new_db_parameter_group_name: ansible-test-db-parameter-group-{{ tiny_prefix }}-new
+
+# Tag cluster
+tags_patch:
+  Name: '{{ tiny_prefix }}-new'
+  Created_by: Ansible rds_cluster integration tests
+
+# Create cluster in a VPC
+vpc_name: ansible-test-vpc-{{ tiny_prefix }}
+vpc_cidr: 10.{{ 256 | random(seed=tiny_prefix) }}.0.0/16
+subnets:
+- {cidr: '10.{{ 256 | random(seed=tiny_prefix) }}.1.0/24', zone: '{{ aws_region }}a'}
+- {cidr: '10.{{ 256 | random(seed=tiny_prefix) }}.2.0/24', zone: '{{ aws_region }}b'}
+- {cidr: '10.{{ 256 | random(seed=tiny_prefix) }}.3.0/24', zone: '{{ aws_region }}c'}
+- {cidr: '10.{{ 256 | random(seed=tiny_prefix) }}.4.0/24', zone: '{{ aws_region }}d'}
+
+security_groups:
+- '{{ tiny_prefix }}-sg-1'
+- '{{ tiny_prefix }}-sg-2'
+- '{{ tiny_prefix }}-sg-3'
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/meta/main.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/meta/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/meta/main.yml
@@ -0,0 +1 @@
+---
\ No newline at end of file
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/main.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/main.yml
@@ -0,0 +1,10 @@
+- name: rds_cluster integration tests
+  module_defaults:
+    group/aws:
+      region: '{{ aws_region }}'
+      aws_access_key: '{{ aws_access_key }}'
+      aws_secret_key: '{{ aws_secret_key }}'
+      security_token: '{{ security_token | default(omit) }}'
+
+  block:
+  - include: ./test_{{ inventory_hostname }}.yml
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create.yml
@@ -0,0 +1,123 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: yes
+
+  - name: Get info of all existing clusters
+    rds_cluster_info:
+    register: _result_cluster_info
+
+  - assert:
+      that:
+      - _result_cluster_info is successful
+
+  - name: Create minimal aurora cluster in default VPC and default subnet group (CHECK
+      MODE)
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_create_db_cluster
+    check_mode: true
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+
+  - name: Create minimal aurora cluster in default VPC and default subnet group
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+      - "'allocated_storage' in _result_create_db_cluster"
+      - _result_create_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_db_cluster"
+      - _result_create_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_db_cluster"
+      - "'db_cluster_identifier' in _result_create_db_cluster"
+      - _result_create_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_db_cluster"
+      - "'endpoint' in _result_create_db_cluster"
+      - "'engine' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_db_cluster"
+      - "'master_username' in _result_create_db_cluster"
+      - _result_create_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_db_cluster"
+      - _result_create_db_cluster.port == {{ port }}
+      - "'status' in _result_create_db_cluster"
+      - _result_create_db_cluster.status == 'available'
+      - _result_create_db_cluster.storage_encrypted == false
+      - "'tags' in _result_create_db_cluster"
+      - _result_create_db_cluster.tags | length == 2
+      - _result_create_db_cluster.tags["Created_By"] == "{{ tags_create["Created_By"]}}"
+      - _result_create_db_cluster.tags["Name"] == "{{ tags_create["Name"]}}"
+      - "'vpc_security_groups' in _result_create_db_cluster"
+  - name: Get info of the existing cluster
+    rds_cluster_info:
+      cluster_id: '{{ cluster_id }}'
+    register: result_cluster_info
+
+  - assert:
+      that:
+      - result_cluster_info is successful
+
+  - name: Create minimal aurora cluster in default VPC and default subnet group -
+      idempotence (CHECK MODE)
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_create_db_cluster
+    check_mode: true
+
+  - assert:
+      that:
+      - not _result_create_db_cluster.changed
+
+  - name: Create minimal aurora cluster in default VPC and default subnet group -
+      idempotence
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - not _result_create_db_cluster.changed
+
+  always:
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ cluster_id }}'
+      skip_final_snapshot: true
+    ignore_errors: true
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create_sgs.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create_sgs.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_create_sgs.yml
@@ -0,0 +1,208 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: yes
+
+  - name: Create a VPC
+    ec2_vpc_net:
+      name: '{{ vpc_name }}'
+      state: present
+      cidr_block: '{{ vpc_cidr }}'
+      tags:
+        Name: '{{ vpc_name }}'
+        Description: Created by rds_cluster integration tests
+    register: _result_create_vpc
+
+  - name: Create subnets
+    ec2_vpc_subnet:
+      cidr: '{{ item.cidr }}'
+      az: '{{ item.zone }}'
+      vpc_id: '{{ _result_create_vpc.vpc.id }}'
+      tags:
+        Name: '{{ resource_prefix }}-subnet'
+        Description: created by rds_cluster integration tests
+      state: present
+    register: _result_create_subnet
+    loop: '{{ subnets }}'
+
+  - name: Create security groups
+    ec2_group:
+      name: '{{ item }}'
+      description: Created by rds_cluster integration tests
+      state: present
+    register: _result_create_sg
+    loop: '{{ security_groups }}'
+
+  - name: Create an RDS cluster in the VPC with two security groups
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      vpc_security_group_ids:
+      - '{{ _result_create_sg.results.0.group_id }}'
+      - '{{ _result_create_sg.results.1.group_id }}'
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+      - "'allocated_storage' in _result_create_db_cluster"
+      - _result_create_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_db_cluster"
+      - _result_create_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_db_cluster"
+      - "'db_cluster_identifier' in _result_create_db_cluster"
+      - _result_create_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_db_cluster"
+      - "'endpoint' in _result_create_db_cluster"
+      - "'engine' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_db_cluster"
+      - "'master_username' in _result_create_db_cluster"
+      - _result_create_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_db_cluster"
+      - _result_create_db_cluster.port == {{ port }}
+      - "'status' in _result_create_db_cluster"
+      - _result_create_db_cluster.status == 'available'
+      - _result_create_db_cluster.storage_encrypted == false
+      - "'tags' in _result_create_db_cluster"
+      - "'vpc_security_groups' in _result_create_db_cluster"
+      - _result_create_db_cluster.vpc_security_groups | selectattr('status', 'in',
+        ['active', 'adding']) | list | length == 2
+
+  - name: Add a new security group without purge (check_mode)
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      vpc_security_group_ids:
+      - '{{ _result_create_sg.results.2.group_id }}'
+      apply_immediately: true
+      purge_security_groups: false
+    check_mode: true
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+
+  - name: Add a new security group without purge
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      vpc_security_group_ids:
+      - '{{ _result_create_sg.results.2.group_id }}'
+      apply_immediately: true
+      purge_security_groups: false
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+      - "'allocated_storage' in _result_create_db_cluster"
+      - _result_create_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_db_cluster"
+      - _result_create_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_db_cluster"
+      - "'db_cluster_identifier' in _result_create_db_cluster"
+      - _result_create_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_db_cluster"
+      - "'endpoint' in _result_create_db_cluster"
+      - "'engine' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_db_cluster"
+      - "'master_username' in _result_create_db_cluster"
+      - _result_create_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_db_cluster"
+      - _result_create_db_cluster.port == {{ port }}
+      - "'status' in _result_create_db_cluster"
+      - _result_create_db_cluster.status == 'available'
+      - _result_create_db_cluster.storage_encrypted == false
+      - "'tags' in _result_create_db_cluster"
+      - "'vpc_security_groups' in _result_create_db_cluster"
+      - _result_create_db_cluster.vpc_security_groups | selectattr('status', 'in',
+        ['active', 'adding']) | list | length == 3
+
+  - name: Add a new security group without purge (test idempotence)
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      vpc_security_group_ids:
+      - '{{ _result_create_sg.results.2.group_id }}'
+      apply_immediately: true
+      purge_security_groups: false
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - not _result_create_db_cluster.changed
+
+  - name: Add a security group with purge
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      vpc_security_group_ids:
+      - '{{ _result_create_sg .results.2.group_id }}'
+      apply_immediately: true
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+      - _result_create_db_cluster.db_cluster_identifier == '{{ cluster_id }}'
+      - _result_create_db_cluster.vpc_security_groups | selectattr('status', 'in',
+        ['active', 'adding']) | list | length == 1
+
+  always:
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ cluster_id }}'
+      skip_final_snapshot: true
+    ignore_errors: true
+
+  - name: Remove security groups
+    ec2_group:
+      name: '{{ item }}'
+      description: created by rds_cluster integration tests
+      state: absent
+    loop: '{{ security_groups }}'
+
+  - name: Remove subnets
+    ec2_vpc_subnet:
+      cidr: '{{ item.cidr }}'
+      az: '{{ item.zone }}'
+      vpc_id: '{{ _result_create_vpc.vpc.id }}'
+      tags:
+        Name: '{{ resource_prefix }}-subnet'
+        Description: Created by rds_cluster integration tests
+      state: absent
+    ignore_errors: yes
+    loop: '{{ subnets }}'
+
+  - name: Delete VPC
+    ec2_vpc_net:
+      name: '{{ vpc_name }}'
+      state: absent
+      cidr_block: '{{ vpc_cidr }}'
+      tags:
+        Name: '{{ vpc_name }}'
+        Description: Created by rds_cluster integration tests
+    ignore_errors: yes
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_modify.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_modify.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_modify.yml
@@ -0,0 +1,266 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: yes
+
+  - name: Create a DB cluster
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+    register: _result_create_source_db_cluster
+
+  - assert:
+      that:
+      - _result_create_source_db_cluster.changed
+      - _result_create_source_db_cluster.changed
+      - "'allocated_storage' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.db_cluster_identifier == '{{ cluster_id }}'
+      - "'db_cluster_parameter_group' in _result_create_source_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_source_db_cluster"
+      - "'endpoint' in _result_create_source_db_cluster"
+      - "'engine' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_source_db_cluster"
+      - "'master_username' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.port == {{ port }}
+      - "'status' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.status == "available"
+      - "'tags' in _result_create_source_db_cluster"
+      - "'vpc_security_groups' in _result_create_source_db_cluster"
+
+  - name: Modify DB cluster password
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      password: '{{ new_password }}'
+      force_update_password: true
+      apply_immediately: true
+    register: _result_modify_password
+
+  - assert:
+      that:
+      - _result_modify_password.changed
+      - "'allocated_storage' in _result_modify_password"
+      - _result_modify_password.allocated_storage == 1
+      - "'cluster_create_time' in _result_modify_password"
+      - _result_modify_password.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_modify_password"
+      - _result_modify_password.db_cluster_identifier == '{{ cluster_id }}'
+      - "'db_cluster_parameter_group' in _result_modify_password"
+      - "'db_cluster_resource_id' in _result_modify_password"
+      - "'endpoint' in _result_modify_password"
+      - "'engine' in _result_modify_password"
+      - _result_modify_password.engine == "{{ engine }}"
+      - "'engine_mode' in _result_modify_password"
+      - _result_modify_password.engine_mode == "provisioned"
+      - "'engine_version' in _result_modify_password"
+      - "'master_username' in _result_modify_password"
+      - _result_modify_password.master_username == "{{ username }}"
+      - "'port' in _result_create_source_db_cluster"
+      - _result_modify_password.port == {{ port }}
+      - "'status' in _result_modify_password"
+      - _result_modify_password.status == "available"
+      - "'tags' in _result_modify_password"
+      - "'vpc_security_groups' in _result_modify_password"
+
+  - name: Modify DB cluster port
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      port: '{{ new_port }}'
+    register: _result_modify_port
+
+  - assert:
+      that:
+      - _result_modify_port.changed
+      - "'allocated_storage' in _result_modify_port"
+      - _result_modify_port.allocated_storage == 1
+      - "'cluster_create_time' in _result_modify_port"
+      - _result_modify_port.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_modify_port"
+      - _result_modify_port.db_cluster_identifier == '{{ cluster_id }}'
+      - "'db_cluster_parameter_group' in _result_modify_port"
+      - "'db_cluster_resource_id' in _result_modify_port"
+      - "'endpoint' in _result_modify_port"
+      - "'engine' in _result_modify_port"
+      - _result_modify_port.engine == "{{ engine }}"
+      - "'engine_mode' in _result_modify_port"
+      - _result_modify_port.engine_mode == "provisioned"
+      - "'engine_version' in _result_modify_port"
+      - "'master_username' in _result_modify_port"
+      - _result_modify_port.master_username == "{{ username }}"
+      - "'port' in _result_modify_port"
+      - _result_modify_port.port == {{ new_port }}
+      - "'status' in _result_modify_port"
+      - _result_modify_port.status == "available"
+      - "'tags' in _result_modify_port"
+      - "'vpc_security_groups' in _result_modify_port"
+
+  - name: Modify DB cluster identifier
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      purge_tags: false
+      new_cluster_id: '{{ new_cluster_id }}'
+      apply_immediately: true
+    register: _result_modify_id
+
+  - assert:
+      that:
+      - _result_modify_id.changed
+      - "'allocated_storage' in _result_modify_id"
+      - _result_modify_id.allocated_storage == 1
+      - "'cluster_create_time' in _result_modify_id"
+      - _result_modify_id.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_modify_id"
+      - _result_modify_id.db_cluster_identifier == '{{ new_cluster_id }}'
+      - "'db_cluster_parameter_group' in _result_modify_id"
+      - "'db_cluster_resource_id' in _result_modify_id"
+      - "'endpoint' in _result_modify_id"
+      - "'engine' in _result_modify_id"
+      - _result_modify_id.engine == "{{ engine }}"
+      - "'engine_mode' in _result_modify_id"
+      - _result_modify_id.engine_mode == "provisioned"
+      - "'engine_version' in _result_modify_id"
+      - "'master_username' in _result_modify_id"
+      - _result_modify_id.master_username == "{{ username }}"
+      - "'port' in _result_modify_id"
+      - _result_modify_id.port == {{ new_port }}
+      - "'status' in _result_modify_id"
+      - _result_modify_id.status == "available"
+      - "'tags' in _result_modify_id"
+      - "'vpc_security_groups' in _result_modify_id"
+
+  - name: Check if DB cluster parameter group exists
+    command: aws rds describe-db-cluster-parameter-groups --db-cluster-parameter-group-name
+      {{ new_db_parameter_group_name }}
+    environment:
+      AWS_ACCESS_KEY_ID: '{{ aws_access_key }}'
+      AWS_SECRET_ACCESS_KEY: '{{ aws_secret_key }}'
+      AWS_SESSION_TOKEN: "{{ security_token | default('') }}"
+      AWS_DEFAULT_REGION: '{{ aws_region }}'
+    register: _result_check_db_parameter_group
+    ignore_errors: true
+    changed_when: _result_check_db_parameter_group.rc == 0
+
+  - name: Create DB cluster parameter group if not exists
+    command: aws rds create-db-cluster-parameter-group --db-cluster-parameter-group-name
+      {{ new_db_parameter_group_name }} --db-parameter-group-family aurora5.6 --description
+      "Test DB cluster parameter group"
+    environment:
+      AWS_ACCESS_KEY_ID: '{{ aws_access_key }}'
+      AWS_SECRET_ACCESS_KEY: '{{ aws_secret_key }}'
+      AWS_SESSION_TOKEN: "{{ security_token | default('') }}"
+      AWS_DEFAULT_REGION: '{{ aws_region }}'
+    register: _result_create_db_parameter_group
+    when: _result_check_db_parameter_group.rc != 0
+
+  - name: Modify DB cluster parameter group
+    rds_cluster:
+      id: '{{ new_cluster_id }}'
+      state: present
+      db_cluster_parameter_group_name: '{{ new_db_parameter_group_name }}'
+      apply_immediately: true
+    register: _result_modify_db_parameter_group_name
+
+  - assert:
+      that:
+      - _result_modify_db_parameter_group_name.changed
+      - "'allocated_storage' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.allocated_storage == 1
+      - "'cluster_create_time' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.db_cluster_identifier == '{{ new_cluster_id
+        }}'
+      - "'db_cluster_parameter_group' in _result_modify_db_parameter_group_name"
+      - "'db_cluster_resource_id' in _result_modify_db_parameter_group_name"
+      - "'endpoint' in _result_modify_db_parameter_group_name"
+      - "'engine' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.engine == "{{ engine }}"
+      - "'engine_mode' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.engine_mode == "provisioned"
+      - "'engine_version' in _result_modify_db_parameter_group_name"
+      - "'master_username' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.master_username == "{{ username }}"
+      - "'port' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.db_cluster_parameter_group == "{{ new_db_parameter_group_name
+        }}"
+      - "'status' in _result_modify_db_parameter_group_name"
+      - _result_modify_db_parameter_group_name.status == "available"
+      - "'tags' in _result_modify_db_parameter_group_name"
+      - "'vpc_security_groups' in _result_modify_db_parameter_group_name"
+
+  - name: Delete DB cluster without creating a final snapshot (CHECK MODE)
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ new_cluster_id }}'
+      skip_final_snapshot: true
+    register: _result_delete_cluster
+    check_mode: true
+
+  - assert:
+      that:
+      - _result_delete_cluster.changed
+
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ new_cluster_id }}'
+      skip_final_snapshot: true
+    register: _result_delete_cluster
+
+  - assert:
+      that:
+      - _result_delete_cluster.changed
+
+  - name: Delete DB cluster without creating a final snapshot (idempotence)
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ new_cluster_id }}'
+      skip_final_snapshot: true
+    register: _result_delete_cluster
+
+  - assert:
+      that:
+      - not _result_delete_cluster.changed
+
+  always:
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ cluster_id }}'
+      skip_final_snapshot: true
+    ignore_errors: true
+
+  - name: Delete cluster parameter group
+    command: aws rds delete-db-cluster-parameter-group --db-cluster-parameter-group-name
+      {{ new_db_parameter_group_name }}
+    environment:
+      AWS_ACCESS_KEY_ID: '{{ aws_access_key }}'
+      AWS_SECRET_ACCESS_KEY: '{{ aws_secret_key }}'
+      AWS_SESSION_TOKEN: "{{ security_token | default('') }}"
+      AWS_DEFAULT_REGION: '{{ aws_region }}'
+    ignore_errors: true
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_promote.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_promote.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_promote.yml
@@ -0,0 +1,187 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: yes
+
+  - name: Set the two regions for the source DB and the read replica
+    set_fact:
+      region_src: '{{ aws_region }}'
+      region_dest: '{{ aws_region }}'
+
+  - name: Create a source DB cluster
+    rds_cluster:
+      cluster_id: '{{ cluster_id }}'
+      state: present
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      region: '{{ region_src }}'
+      tags:
+        Name: '{{ cluster_id }}'
+        Created_by: Ansible rds_cluster tests
+    register: _result_create_src_db_cluster
+
+  - assert:
+      that:
+      - _result_create_src_db_cluster.changed
+      - "'allocated_storage' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.db_cluster_identifier == '{{ cluster_id }}'
+      - "'db_cluster_parameter_group' in _result_create_src_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_src_db_cluster"
+      - "'endpoint' in _result_create_src_db_cluster"
+      - "'engine' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_src_db_cluster"
+      - "'master_username' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.port == {{ port }}
+      - "'status' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.status == "available"
+      - "'tags' in _result_create_src_db_cluster"
+      - _result_create_src_db_cluster.tags | length == 2
+      - _result_create_src_db_cluster.tags.Name == '{{ cluster_id }}'
+      - _result_create_src_db_cluster.tags.Created_by == 'Ansible rds_cluster tests'
+      - "'vpc_security_groups' in _result_create_src_db_cluster"
+
+  - name: Get info on DB cluster
+    rds_cluster_info:
+      db_cluster_identifier: '{{ cluster_id }}'
+    register: _result_cluster_info
+
+  - assert:
+      that:
+      - _result_cluster_info is successful
+
+  - name: Set the ARN of the source DB cluster
+    set_fact:
+      src_db_cluster_arn: '{{ _result_cluster_info.clusters[0].db_cluster_arn}}'
+
+  - name: Create a DB cluster read replica in a different region
+    rds_cluster:
+      id: '{{ cluster_id }}-replica'
+      state: present
+      replication_source_identifier: '{{ src_db_cluster_arn }}'
+      engine: '{{ engine}}'
+      region: '{{ region_dest }}'
+      tags:
+        Name: '{{ cluster_id }}'
+        Created_by: Ansible rds_cluster tests
+      wait: yes
+    register: _result_create_replica_db_cluster
+
+  - assert:
+      that:
+      - _result_create_replica_db_cluster.changed
+      - "'allocated_storage' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.db_cluster_identifier == '{{ cluster_id
+        }}'
+      - "'db_cluster_parameter_group' in _result_create_replica_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_replica_db_cluster"
+      - "'endpoint' in _result_create_replica_db_cluster"
+      - "'engine' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_replica_db_cluster"
+      - "'master_username' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.port == {{ port }}
+      - "'status' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.status == "available"
+      - "'tags' in _result_create_replica_db_cluster"
+      - _result_create_replica_db_cluster.tags | length == 2
+      - _result_create_replica_db_cluster.tags.Name == '{{ cluster_id }}'
+      - _result_create_replica_db_cluster.tags.Created_by == 'Ansible rds_cluster
+        tests'
+      - "'vpc_security_groups' in _result_create_replica_db_cluster"
+
+  - name: Test idempotence with a DB cluster read replica
+    rds_cluster:
+      id: '{{ cluster_id }}-replica'
+      state: present
+      replication_source_identifier: '{{ src_db_cluster_arn }}'
+      engine: '{{ engine}}'
+      region: '{{ region_dest }}'
+      tags:
+        Name: '{{ cluster_id }}'
+        Created_by: Ansible rds_cluster tests
+    register: _result_create_replica_db_cluster
+
+  - assert:
+      that:
+      - not _result_create_replica_db_cluster.changed
+
+  - name: Get info of existing DB cluster
+    rds_cluster_info:
+      db_cluster_identifier: '{{ cluster_id }}-replica'
+      region: '{{ region_dest }}'
+    register: _result_cluster_info
+
+  - assert:
+      that:
+      - _result_cluster_info is successful
+      # - _result_cluster_info.clusters | length == 0
+
+  - name: Promote the DB cluster read replica
+    rds_cluster:
+      cluster_id: '{{ cluster_id }}-replica'
+      state: present
+      promote: true
+      region: '{{ region_dest }}'
+    register: _result_promote_replica_db_cluster
+
+  - assert:
+      that:
+      - _result_promote_replica_db_cluster.changed
+
+  - name: Promote the DB cluster read replica (idempotence)
+    rds_cluster:
+      cluster_id: '{{ cluster_id }}-replica'
+      state: present
+      promote: true
+      region: '{{ region_dest }}'
+    register: _result_promote_replica_db_cluster
+
+  - assert:
+      that:
+      - not _result_promote_replica_db_cluster.changed
+
+  always:
+  - name: Remove the DB cluster
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      skip_final_snapshot: true
+      region: '{{ region_src }}'
+    ignore_errors: yes
+
+  - name: Remove the DB cluster read replica
+    rds_cluster:
+      id: '{{ cluster_id }}-replica'
+      state: absent
+      skip_final_snapshot: true
+      region: '{{ region_dest }}'
+    ignore_errors: yes
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_restore.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_restore.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_restore.yml
@@ -0,0 +1,185 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: true
+
+  - name: Create a source DB cluster
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: present
+      engine: '{{ engine}}'
+      backup_retention_period: 1
+      username: '{{ username }}'
+      password: '{{ password }}'
+      wait: true
+    register: _result_create_source_db_cluster
+
+  - assert:
+      that:
+      - _result_create_source_db_cluster.changed
+      - "'allocated_storage' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_source_db_cluster"
+      - "'db_cluster_identifier' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_source_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_source_db_cluster"
+      - "'endpoint' in _result_create_source_db_cluster"
+      - "'engine' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_source_db_cluster"
+      - "'master_username' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.port == {{ port }}
+      - "'status' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.status == 'available'
+      - _result_create_source_db_cluster.storage_encrypted == false
+      - "'tags' in _result_create_source_db_cluster"
+      - "'vpc_security_groups' in _result_create_source_db_cluster"
+
+  - name: Create a point in time DB cluster
+    rds_cluster:
+      state: present
+      id: '{{ cluster_id }}-point-in-time'
+      source_db_cluster_identifier: '{{ cluster_id }}'
+      creation_source: cluster
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      use_latest_restorable_time: true
+      tags:
+        Name: '{{ cluster_id }}'
+        Created_by: Ansible rds_cluster tests
+    register: _result_restored_db_cluster
+
+  - assert:
+      that:
+      - _result_restored_db_cluster.changed
+      - "'allocated_storage' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.db_cluster_identifier == '{{ cluster_id }}-point-in-time'
+      - "'db_cluster_parameter_group' in _result_restored_db_cluster"
+      - "'db_cluster_resource_id' in _result_restored_db_cluster"
+      - "'endpoint' in _result_restored_db_cluster"
+      - "'engine' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_restored_db_cluster"
+      - "'master_username' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.port == {{ port }}
+      - "'status' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.status == "available"
+      - "'tags' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.tags | length == 2
+      - _result_restored_db_cluster.tags.Name == '{{ cluster_id }}'
+      - _result_restored_db_cluster.tags.Created_by == 'Ansible rds_cluster tests'
+      - "'vpc_security_groups' in _result_restored_db_cluster"
+
+  - name: Create a point in time DB cluster (idempotence)
+    rds_cluster:
+      state: present
+      id: '{{ cluster_id }}-point-in-time'
+      source_db_cluster_identifier: '{{ cluster_id }}'
+      creation_source: cluster
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      restore_to_time: '{{ _result_restored_db_cluster.latest_restorable_time }}'
+      tags:
+        Name: '{{ cluster_id }}'
+        Created_by: Ansible rds_cluster tests
+    register: _result_restored_db_cluster
+
+  - assert:
+      that:
+      - not _result_restored_db_cluster.changed
+
+  - name: Take a snapshot of the DB cluster
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: '{{ cluster_id }}'
+      db_cluster_snapshot_identifier: '{{ cluster_id }}-snapshot'
+      wait: true
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+
+  - name: Restore DB cluster from source (snapshot)
+    rds_cluster:
+      creation_source: snapshot
+      engine: '{{ engine }}'
+      cluster_id: '{{ cluster_id }}-restored-snapshot'
+      snapshot_identifier: '{{ cluster_id }}-snapshot'
+      wait: true
+    register: _result_restored_db_cluster
+
+  - assert:
+      that:
+      - _result_restored_db_cluster.changed
+      - "'allocated_storage' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.db_cluster_identifier == '{{ cluster_id }}-restored-snapshot'
+      - "'db_cluster_parameter_group' in _result_restored_db_cluster"
+      - "'db_cluster_resource_id' in _result_restored_db_cluster"
+      - "'endpoint' in _result_restored_db_cluster"
+      - "'engine' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_restored_db_cluster"
+      - "'master_username' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.port == {{ port }}
+      - "'status' in _result_restored_db_cluster"
+      - _result_restored_db_cluster.status == "available"
+      - "'tags' in _result_restored_db_cluster"
+      - "'vpc_security_groups' in _result_restored_db_cluster"
+
+  # TODO: export a snapshot to an S3 bucket and restore cluster from it
+  # Requires rds_export_task module
+  always:
+  - name: Delete the snapshot
+    rds_cluster_snapshot:
+      db_cluster_snapshot_identifier: '{{ cluster_id }}-snapshot'
+      state: absent
+    register: _result_delete_snapshot
+    ignore_errors: true
+
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ item }}'
+      skip_final_snapshot: true
+    ignore_errors: true
+    loop:
+    - '{{ cluster_id }}'
+    - '{{ cluster_id }}-point-in-time'
+    - '{{ cluster_id }}-restored-snapshot'
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_tag.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_tag.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/tasks/test_tag.yml
@@ -0,0 +1,290 @@
+- block:
+  - name: Ensure the resource doesn't exist
+    rds_cluster:
+      id: '{{ cluster_id }}'
+      state: absent
+      engine: '{{ engine}}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      skip_final_snapshot: true
+    register: _result_delete_db_cluster
+
+  - assert:
+      that:
+      - not _result_delete_db_cluster.changed
+    ignore_errors: yes
+
+  - name: Create a DB cluster
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_create_db_cluster
+
+  - assert:
+      that:
+      - _result_create_db_cluster.changed
+      - "'allocated_storage' in _result_create_db_cluster"
+      - _result_create_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_db_cluster"
+      - _result_create_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_db_cluster"
+      - "'db_cluster_identifier' in _result_create_db_cluster"
+      - _result_create_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_db_cluster"
+      - "'endpoint' in _result_create_db_cluster"
+      - "'engine' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_db_cluster"
+      - _result_create_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_db_cluster"
+      - "'master_username' in _result_create_db_cluster"
+      - _result_create_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_db_cluster"
+      - _result_create_db_cluster.port == {{ port }}
+      - "'status' in _result_create_db_cluster"
+      - _result_create_db_cluster.status == 'available'
+      - _result_create_db_cluster.storage_encrypted == false
+      - "'tags' in _result_create_db_cluster"
+      - _result_create_db_cluster.tags | length == 2
+      - _result_create_db_cluster.tags["Created_By"] == "{{ tags_create["Created_By"]
+        }}"
+      - _result_create_db_cluster.tags["Name"] == "{{ tags_create["Name"]}}"
+      - "'vpc_security_groups' in _result_create_db_cluster"
+
+  - name: Test tags are not purged if purge_tags is False
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ new_password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: {}
+      purge_tags: false
+    register: _result_tag_db_cluster
+
+  - assert:
+      that:
+      - not _result_tag_db_cluster.changed
+      - "'allocated_storage' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_tag_db_cluster"
+      - "'db_cluster_identifier' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_tag_db_cluster"
+      - "'db_cluster_resource_id' in _result_tag_db_cluster"
+      - "'endpoint' in _result_tag_db_cluster"
+      - "'engine' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_tag_db_cluster"
+      - "'master_username' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.port == {{ port }}
+      - "'status' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.status == 'available'
+      - _result_tag_db_cluster.storage_encrypted == false
+      - "'tags' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.tags | length == 2
+      - _result_tag_db_cluster.tags["Created_By"] == "{{ tags_create["Created_By"]
+        }}"
+      - _result_tag_db_cluster.tags["Name"] == "{{ tags_create["Name"] }}"
+      - "'vpc_security_groups' in _result_tag_db_cluster"
+
+  - name: Add a tag and remove a tag (purge_tags is True)
+    rds_cluster:
+      cluster_id: '{{ cluster_id }}'
+      state: present
+      tags: '{{ tags_patch }}'
+    register: _result_tag_db_cluster
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+      - "'allocated_storage' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_tag_db_cluster"
+      - "'db_cluster_identifier' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_tag_db_cluster"
+      - "'db_cluster_resource_id' in _result_tag_db_cluster"
+      - "'endpoint' in _result_tag_db_cluster"
+      - "'engine' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_tag_db_cluster"
+      - "'master_username' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.port == {{ port }}
+      - "'status' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.status == 'available'
+      - _result_tag_db_cluster.storage_encrypted == false
+      - "'tags' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.tags | length == 2
+      - _result_tag_db_cluster.tags["Name"] == "{{ tags_patch['Name'] }}"
+      - "'vpc_security_groups' in _result_tag_db_cluster"
+
+  - name: Purge a tag from the cluster (CHECK MODE)
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags:
+        Created_By: Ansible_rds_cluster_integration_test
+    register: _result_tag_db_cluster
+    check_mode: true
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+
+  - name: Purge a tag from the cluster
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags:
+        Created_By: Ansible_rds_cluster_integration_test
+    register: _result_tag_db_cluster
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+      - "'allocated_storage' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_tag_db_cluster"
+      - "'db_cluster_identifier' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_tag_db_cluster"
+      - "'db_cluster_resource_id' in _result_tag_db_cluster"
+      - "'endpoint' in _result_tag_db_cluster"
+      - "'engine' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_tag_db_cluster"
+      - "'master_username' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.port == {{ port }}
+      - "'status' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.status == 'available'
+      - _result_tag_db_cluster.storage_encrypted == false
+      - "'tags' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.tags | length == 1
+      - _result_tag_db_cluster.tags["Created_By"] == "Ansible_rds_cluster_integration_test"
+      - "'vpc_security_groups' in _result_tag_db_cluster"
+
+  - name: Add a tag to the cluster (CHECK MODE)
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags:
+        Name: cluster-{{ resource_prefix }}
+        Created_By: Ansible_rds_cluster_integration_test
+    register: _result_tag_db_cluster
+    check_mode: true
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+
+  - name: Add a tag to the cluster
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: '{{ tags_create }}'
+    register: _result_tag_db_cluster
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+      - "'allocated_storage' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_tag_db_cluster"
+      - "'db_cluster_identifier' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_tag_db_cluster"
+      - "'db_cluster_resource_id' in _result_tag_db_cluster"
+      - "'endpoint' in _result_tag_db_cluster"
+      - "'engine' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_tag_db_cluster"
+      - "'master_username' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.port == {{ port }}
+      - "'status' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.status == 'available'
+      - _result_tag_db_cluster.storage_encrypted == false
+      - "'tags' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.tags | length == 2
+      - _result_tag_db_cluster.tags["Created_By"] == "{{ tags_create["Created_By"]}}"
+      - _result_tag_db_cluster.tags["Name"] == "{{ tags_create["Name"]}}"
+      - "'vpc_security_groups' in _result_tag_db_cluster"
+  - name: Remove all tags
+    rds_cluster:
+      engine: '{{ engine }}'
+      username: '{{ username }}'
+      password: '{{ password }}'
+      cluster_id: '{{ cluster_id }}'
+      tags: {}
+    register: _result_tag_db_cluster
+
+  - assert:
+      that:
+      - _result_tag_db_cluster.changed
+      - "'allocated_storage' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_tag_db_cluster"
+      - "'db_cluster_identifier' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_tag_db_cluster"
+      - "'db_cluster_resource_id' in _result_tag_db_cluster"
+      - "'endpoint' in _result_tag_db_cluster"
+      - "'engine' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_tag_db_cluster"
+      - "'master_username' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.port == {{ port }}
+      - "'status' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.status == 'available'
+      - _result_tag_db_cluster.storage_encrypted == false
+      - "'tags' in _result_tag_db_cluster"
+      - _result_tag_db_cluster.tags | length == 0
+      - "'vpc_security_groups' in _result_tag_db_cluster"
+  always:
+  - name: Delete DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: '{{ cluster_id }}'
+      skip_final_snapshot: true
+    ignore_errors: true
diff --git a/tests/integration/targets/rds_cluster/roles/rds_cluster/vars/main.yml b/tests/integration/targets/rds_cluster/roles/rds_cluster/vars/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/roles/rds_cluster/vars/main.yml
@@ -0,0 +1 @@
+---
diff --git a/tests/integration/targets/rds_cluster/runme.sh b/tests/integration/targets/rds_cluster/runme.sh
new file mode 100755
--- /dev/null
+++ b/tests/integration/targets/rds_cluster/runme.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+#
+# Beware: most of our tests here are run in parallel.
+# To add new tests you'll need to add a new host to the inventory and a matching
+# '{{ inventory_hostname }}'.yml file in roles/rds_cluster/tasks/
+
+
+set -eux
+
+export ANSIBLE_ROLES_PATH=../
+
+ansible-playbook main.yml -i inventory "$@"
diff --git a/tests/integration/targets/rds_cluster_snapshot/aliases b/tests/integration/targets/rds_cluster_snapshot/aliases
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster_snapshot/aliases
@@ -0,0 +1,3 @@
+cloud/aws
+
+rds_snapshot_info
diff --git a/tests/integration/targets/rds_cluster_snapshot/defaults/main.yml b/tests/integration/targets/rds_cluster_snapshot/defaults/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster_snapshot/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+# defaults file for rds_cluster_snapshot
+_resource_prefix: 'ansible-test-{{ tiny_prefix }}'
+
+# Create RDS cluster
+cluster_id: '{{ _resource_prefix }}-rds-cluster'
+username: 'testrdsusername'
+password: "{{ lookup('password', 'dev/null length=12 chars=ascii_letters,digits') }}"
+engine: 'aurora'
+port: 3306
+
+# Create snapshot
+snapshot_id: '{{ _resource_prefix }}-rds-cluster-snapshot'
diff --git a/tests/integration/targets/rds_cluster_snapshot/tasks/main.yml b/tests/integration/targets/rds_cluster_snapshot/tasks/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster_snapshot/tasks/main.yml
@@ -0,0 +1,480 @@
+---
+- module_defaults:
+    group/aws:
+      region: "{{ aws_region }}"
+      aws_access_key: "{{ aws_access_key }}"
+      aws_secret_key: "{{ aws_secret_key }}"
+      security_token: "{{ security_token | default(omit) }}"
+  collections:
+    - amazon.aws
+
+  block:
+  - name: Create a source DB cluster
+    rds_cluster:
+      id: "{{ cluster_id }}"
+      state: present
+      engine: "{{ engine}}"
+      backup_retention_period: 1
+      username: "{{ username }}"
+      password: "{{ password }}"
+      preferred_backup_window: "01:15-01:45"
+    register: _result_create_source_db_cluster
+
+  - assert:
+      that:
+      - _result_create_source_db_cluster.changed
+      - "'allocated_storage' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_parameter_group' in _result_create_source_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_source_db_cluster"
+      - "'endpoint' in _result_create_source_db_cluster"
+      - "'engine' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_source_db_cluster"
+      - "'master_username' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_source_db_cluster"
+      - "_result_create_source_db_cluster.port == {{ port }}"
+      - "'status' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.status == "available"
+      - "'tags' in _result_create_source_db_cluster"
+      - "'vpc_security_groups' in _result_create_source_db_cluster"
+
+  - name: Get all RDS snapshots for the existing DB cluster
+    rds_snapshot_info:
+      db_cluster_identifier: "{{ cluster_id }}"
+    register: _result_cluster_snapshot_info
+
+  - assert:
+      that:
+      - _result_cluster_snapshot_info is successful
+      - _result_cluster_snapshot_info.cluster_snapshots | length == 0
+
+  - name: Take a snapshot of the existing DB cluster (CHECK_MODE)
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}"
+    check_mode: true
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+
+  - name: Take a snapshot of the existing DB cluster
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}"
+      wait: true
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+      - "'allocated_storage' in _result_cluster_snapshot"
+      - "'cluster_create_time' in _result_cluster_snapshot"
+      - "'db_cluster_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_snapshot_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}"
+      - "'db_cluster_snapshot_arn' in _result_cluster_snapshot"
+      - "'engine' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.engine == "{{ engine }}"
+      # - "'engine_mode' in _result_cluster_snapshot"
+      # - _result_cluster_snapshot.engine_mode == "provisioned"
+      - "'engine_version' in _result_cluster_snapshot"
+      - "'iam_database_authentication_enabled' in _result_cluster_snapshot"
+      - "'license_model' in _result_cluster_snapshot"
+      - "'master_username' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.master_username == "{{ username }}"
+      - "'snapshot_create_time' in _result_cluster_snapshot"
+      - "'snapshot_type' in _result_cluster_snapshot"
+      - "'status' in _result_cluster_snapshot"
+      - _result_create_source_db_cluster.status == "available"
+      - "'storage_encrypted' in _result_cluster_snapshot"
+      - "'tags' in _result_cluster_snapshot"
+      - "'vpc_id' in _result_cluster_snapshot"
+
+  - name: Get information about the existing DB snapshot
+    rds_snapshot_info:
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}"
+    register: _result_cluster_snapshot_info
+
+  - assert:
+      that:
+      - _result_cluster_snapshot_info is successful
+      - _result_cluster_snapshot_info.cluster_snapshots[0].db_cluster_identifier == "{{ cluster_id }}"
+      - _result_cluster_snapshot_info.cluster_snapshots[0].db_cluster_snapshot_identifier == "{{ snapshot_id }}"
+
+  - name: Get info of the existing DB cluster
+    rds_cluster_info:
+      cluster_id: "{{ cluster_id }}"
+    register: result_cluster_info
+
+  - assert:
+      that:
+      - result_cluster_info is successful
+
+  - name: Create another source DB cluster
+    rds_cluster:
+      id: "{{ cluster_id }}-b"
+      state: present
+      engine: "{{ engine}}"
+      backup_retention_period: 1
+      username: "{{ username }}"
+      password: "{{ password }}"
+      preferred_backup_window: "01:15-01:45"
+    register: _result_create_source_db_cluster
+
+  - assert:
+      that:
+      - _result_create_source_db_cluster.changed
+      - "'allocated_storage' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.allocated_storage == 1
+      - "'cluster_create_time' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.copy_tags_to_snapshot == false
+      - "'db_cluster_arn' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.db_cluster_identifier == "{{ cluster_id }}-b"
+      - "'db_cluster_parameter_group' in _result_create_source_db_cluster"
+      - "'db_cluster_resource_id' in _result_create_source_db_cluster"
+      - "'endpoint' in _result_create_source_db_cluster"
+      - "'engine' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine == "{{ engine }}"
+      - "'engine_mode' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.engine_mode == "provisioned"
+      - "'engine_version' in _result_create_source_db_cluster"
+      - "'master_username' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.master_username == "{{ username }}"
+      - "'port' in _result_create_source_db_cluster"
+      - "_result_create_source_db_cluster.port == {{ port }}"
+      - "'status' in _result_create_source_db_cluster"
+      - _result_create_source_db_cluster.status == "available"
+      - "'tags' in _result_create_source_db_cluster"
+      - "'vpc_security_groups' in _result_create_source_db_cluster"
+
+  - name: Take another snapshot of the existing DB cluster
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}-b"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+      wait: true
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+      - "'allocated_storage' in _result_cluster_snapshot"
+      - "'cluster_create_time' in _result_cluster_snapshot"
+      - "'db_cluster_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_identifier == "{{ cluster_id }}-b"
+      - "'db_cluster_snapshot_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-b"
+      - "'db_cluster_snapshot_arn' in _result_cluster_snapshot"
+      - "'engine' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.engine == "{{ engine }}"
+      # - "'engine_mode' in _result_cluster_snapshot"
+      # - _result_cluster_snapshot.engine_mode == "provisioned"
+      - "'engine_version' in _result_cluster_snapshot"
+      - "'iam_database_authentication_enabled' in _result_cluster_snapshot"
+      - "'license_model' in _result_cluster_snapshot"
+      - "'master_username' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.master_username == "{{ username }}"
+      - "'snapshot_create_time' in _result_cluster_snapshot"
+      - "'snapshot_type' in _result_cluster_snapshot"
+      - "'status' in _result_cluster_snapshot"
+      - _result_create_source_db_cluster.status == "available"
+      - "'storage_encrypted' in _result_cluster_snapshot"
+      - "'tags' in _result_cluster_snapshot"
+      - "'vpc_id' in _result_cluster_snapshot"
+
+  - name: Get all RDS snapshots for the existing DB cluster
+    rds_snapshot_info:
+      db_cluster_identifier: "{{ cluster_id }}-b"
+    register: _result_cluster_snapshot_info
+
+  - assert:
+      that:
+      - _result_cluster_snapshot_info is successful
+      - _result_cluster_snapshot_info.cluster_snapshots | length == 1
+
+  - name: Delete existing DB cluster snapshot (CHECK_MODE)
+    rds_cluster_snapshot:
+      state: absent
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+    register: _result_delete_snapshot
+    check_mode: true
+
+  - assert:
+      that:
+      - _result_delete_snapshot.changed
+
+  - name: Delete the existing DB cluster snapshot
+    rds_cluster_snapshot:
+      state: absent
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+    register: _result_delete_snapshot
+
+  - assert:
+      that:
+      - _result_delete_snapshot.changed
+
+  - name: Get info of the existing DB cluster
+    rds_cluster_info:
+      cluster_id: "{{ cluster_id }}"
+    register: _result_cluster_info
+
+  - assert:
+      that:
+      - result_cluster_info is successful
+
+  - name: Take another snapshot of the existing DB cluster and assign tags
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+      wait: true
+      tags:
+        tag_one: '{{ snapshot_id }}-b One'
+        "Tag Two": 'two {{ snapshot_id }}-b'
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+      - "'allocated_storage' in _result_cluster_snapshot"
+      - "'cluster_create_time' in _result_cluster_snapshot"
+      - "'db_cluster_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_snapshot_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-b"
+      - "'db_cluster_snapshot_arn' in _result_cluster_snapshot"
+      - "'engine' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.engine == "{{ engine }}"
+      # - "'engine_mode' in _result_cluster_snapshot"
+      # - _result_cluster_snapshot.engine_mode == "provisioned"
+      - "'engine_version' in _result_cluster_snapshot"
+      - "'iam_database_authentication_enabled' in _result_cluster_snapshot"
+      - "'license_model' in _result_cluster_snapshot"
+      - "'master_username' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.master_username == "{{ username }}"
+      - "'snapshot_create_time' in _result_cluster_snapshot"
+      - "'snapshot_type' in _result_cluster_snapshot"
+      - "'status' in _result_cluster_snapshot"
+      - _result_create_source_db_cluster.status == "available"
+      - "'storage_encrypted' in _result_cluster_snapshot"
+      - "'tags' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.tags | length == 2
+      - _result_cluster_snapshot.tags["tag_one"] == "{{ snapshot_id }}-b One"
+      - _result_cluster_snapshot.tags["Tag Two"] == "two {{ snapshot_id }}-b"
+      - "'vpc_id' in _result_cluster_snapshot"
+
+  - name: Attempt to take another snapshot of the existing DB cluster and assign tags (idempotence)
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+      wait: true
+      tags:
+        tag_one: '{{ snapshot_id }}-b One'
+        "Tag Two": 'two {{ snapshot_id }}-b'
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - not _result_cluster_snapshot.changed
+
+  - name: Take another snapshot of the existing DB cluster and update tags
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+      tags:
+        tag_three: '{{ snapshot_id }}-b Three'
+        "Tag Two": 'two {{ snapshot_id }}-b'
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+      - "'allocated_storage' in _result_cluster_snapshot"
+      - "'cluster_create_time' in _result_cluster_snapshot"
+      - "'db_cluster_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_snapshot_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-b"
+      - "'db_cluster_snapshot_arn' in _result_cluster_snapshot"
+      - "'engine' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.engine == "{{ engine }}"
+      # - "'engine_mode' in _result_cluster_snapshot"
+      # - _result_cluster_snapshot.engine_mode == "provisioned"
+      - "'engine_version' in _result_cluster_snapshot"
+      - "'iam_database_authentication_enabled' in _result_cluster_snapshot"
+      - "'license_model' in _result_cluster_snapshot"
+      - "'master_username' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.master_username == "{{ username }}"
+      - "'snapshot_create_time' in _result_cluster_snapshot"
+      - "'snapshot_type' in _result_cluster_snapshot"
+      - "'status' in _result_cluster_snapshot"
+      - _result_create_source_db_cluster.status == "available"
+      - "'storage_encrypted' in _result_cluster_snapshot"
+      - "'tags' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.tags | length == 2
+      - _result_cluster_snapshot.tags["tag_three"] == "{{ snapshot_id }}-b Three"
+      - _result_cluster_snapshot.tags["Tag Two"] == "two {{ snapshot_id }}-b"
+      - "'vpc_id' in _result_cluster_snapshot"
+
+  - name: Take another snapshot of the existing DB cluster and update tags without purge
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+      purge_tags: false
+      tags:
+        tag_one: '{{ snapshot_id }}-b One'
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - _result_cluster_snapshot.changed
+      - "'allocated_storage' in _result_cluster_snapshot"
+      - "'cluster_create_time' in _result_cluster_snapshot"
+      - "'db_cluster_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+      - "'db_cluster_snapshot_identifier' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-b"
+      - "'db_cluster_snapshot_arn' in _result_cluster_snapshot"
+      - "'engine' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.engine == "{{ engine }}"
+      # - "'engine_mode' in _result_cluster_snapshot"
+      # - _result_cluster_snapshot.engine_mode == "provisioned"
+      - "'engine_version' in _result_cluster_snapshot"
+      - "'iam_database_authentication_enabled' in _result_cluster_snapshot"
+      - "'license_model' in _result_cluster_snapshot"
+      - "'master_username' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.master_username == "{{ username }}"
+      - "'snapshot_create_time' in _result_cluster_snapshot"
+      - "'snapshot_type' in _result_cluster_snapshot"
+      - "'status' in _result_cluster_snapshot"
+      - _result_create_source_db_cluster.status == "available"
+      - "'storage_encrypted' in _result_cluster_snapshot"
+      - "'tags' in _result_cluster_snapshot"
+      - _result_cluster_snapshot.tags | length == 3
+      - _result_cluster_snapshot.tags["tag_one"] == "{{ snapshot_id }}-b One"
+      - _result_cluster_snapshot.tags["Tag Two"] == "two {{ snapshot_id }}-b"
+      - _result_cluster_snapshot.tags["tag_three"] == "{{ snapshot_id }}-b Three"
+      - "'vpc_id' in _result_cluster_snapshot"
+
+  - name: Take another snapshot of the existing DB cluster and do not specify any tag to ensure previous tags are not removed
+    rds_cluster_snapshot:
+      state: present
+      db_cluster_identifier: "{{ cluster_id }}"
+      db_cluster_snapshot_identifier: "{{ snapshot_id }}-b"
+    register: _result_cluster_snapshot
+
+  - assert:
+      that:
+      - not _result_cluster_snapshot.changed
+  
+  # ------------------------------------------------------------------------------------------
+   # Test copying a snapshot
+   ### Copying a DB cluster snapshot from a different region is supported, but not in CI,
+   ### because the aws-terminator only terminates resources in one region.
+  - set_fact:
+      _snapshot_arn: "{{ _result_cluster_snapshot.db_cluster_snapshot_arn }}"
+
+  - name: Copy a DB cluster snapshot (check mode)
+    rds_cluster_snapshot:
+      id: "{{ snapshot_id }}-copy"
+      source_id: "{{ snapshot_id }}-b"
+      copy_tags: yes
+      wait: true
+    register: _result_cluster_copy_snapshot
+    check_mode: yes
+
+  - assert:
+      that:
+        - _result_cluster_copy_snapshot.changed
+
+  - name: Copy a DB cluster snapshot
+    rds_cluster_snapshot:
+      id: "{{ snapshot_id }}-copy"
+      source_id: "{{ snapshot_id }}-b"
+      copy_tags: yes
+      wait: true
+    register: _result_cluster_copy_snapshot
+
+  - assert:
+      that:
+        - _result_cluster_copy_snapshot.changed
+        - _result_cluster_copy_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+        - _result_cluster_copy_snapshot.source_db_cluster_snapshot_arn == "{{ _snapshot_arn }}"
+        - _result_cluster_copy_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-copy"
+        - "'tags' in _result_cluster_copy_snapshot"
+        - _result_cluster_copy_snapshot.tags | length == 3
+        - _result_cluster_copy_snapshot.tags["tag_one"] == "{{ snapshot_id }}-b One"
+        - _result_cluster_copy_snapshot.tags["Tag Two"] == "two {{ snapshot_id }}-b"
+        - _result_cluster_copy_snapshot.tags["tag_three"] == "{{ snapshot_id }}-b Three"
+
+  - name: Copy a DB cluster snapshot (idempotence - check mode)
+    rds_cluster_snapshot:
+      id: "{{ snapshot_id }}-copy"
+      source_id: "{{ snapshot_id }}-b"
+      copy_tags: yes
+      wait: true
+    register: _result_cluster_copy_snapshot
+    check_mode: yes
+
+  - assert:
+      that:
+        - not _result_cluster_copy_snapshot.changed
+
+  - name: Copy a DB cluster snapshot (idempotence)
+    rds_cluster_snapshot:
+      id: "{{ snapshot_id }}-copy"
+      source_id: "{{ snapshot_id }}-b"
+      copy_tags: yes
+      wait: true
+    register: _result_cluster_copy_snapshot
+
+  - assert:
+      that:
+        - not _result_cluster_copy_snapshot.changed
+        - _result_cluster_copy_snapshot.db_cluster_identifier == "{{ cluster_id }}"
+        - _result_cluster_copy_snapshot.source_db_cluster_snapshot_arn == "{{ _snapshot_arn }}"
+        - _result_cluster_copy_snapshot.db_cluster_snapshot_identifier == "{{ snapshot_id }}-copy"
+        - "'tags' in _result_cluster_copy_snapshot"
+        - _result_cluster_copy_snapshot.tags | length == 3
+        - _result_cluster_copy_snapshot.tags["tag_one"] == "{{ snapshot_id }}-b One"
+        - _result_cluster_copy_snapshot.tags["Tag Two"] == "two {{ snapshot_id }}-b"
+        - _result_cluster_copy_snapshot.tags["tag_three"] == "{{ snapshot_id }}-b Three"
+
+  always:
+  - name: Delete the existing DB cluster snapshots
+    rds_cluster_snapshot:
+      state: absent
+      db_cluster_snapshot_identifier: "{{ item }}"
+    register: _result_delete_snapshot
+    ignore_errors: true
+    loop:
+    - "{{ snapshot_id }}"
+    - "{{ snapshot_id }}-b"
+    - "{{ snapshot_id }}-copy"
+
+  - name: Delete the existing DB cluster without creating a final snapshot
+    rds_cluster:
+      state: absent
+      cluster_id: "{{ item }}"
+      skip_final_snapshot: true
+    register: _result_delete_cluster
+    ignore_errors: true
+    loop:
+    - "{{ cluster_id }}"
+    - "{{ cluster_id }}-b"
diff --git a/tests/integration/targets/rds_cluster_snapshot/vars/main.yml b/tests/integration/targets/rds_cluster_snapshot/vars/main.yml
new file mode 100644
--- /dev/null
+++ b/tests/integration/targets/rds_cluster_snapshot/vars/main.yml
@@ -0,0 +1 @@
+---