Repository: ansible-collections/community.aws

Issue:
Use community.aws.rds_instance module to create Aurora cluster
### Summary

I am trying to create an Aurora DB/Cluster from new. I am not clear from the documentation how to do this.

The documentation refers to: "see rds_cluster to manage it" - what does this mean as I do not see any modules for rds_cluster?

Would appreciate your support

Thank you

Tony

### Issue Type

Documentation Report

### Component Name

community.aws.rds_instance

### Ansible Version

```console (paste below)
$ ansible --version

```


### Collection Versions

```console (paste below)
$ ansible-galaxy collection list
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

_No response_

### Additional Information

_No response_

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
Support AWS RDS serverless
<!--- Verify first that your feature was not already discussed on GitHub -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
<!--- Describe the new feature/improvement briefly below -->

Ported from https://github.com/ansible/ansible/issues/45811

Support AWS RDS serverless


##### ISSUE TYPE
- Feature Idea

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
rds

##### ADDITIONAL INFORMATION
<!--- Describe how the feature would be used, why it is needed and what it would solve -->
This would allow the management of Aurora serverless instances https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.html



Discussion:
Hm, that's a typo in the example section, because there is no `rds_cluster` module.  
Basically you also use `rds_instance` to create a rds "cluster".

But "cluster" is here a buzzword. Because you always create a primary node. always. It does not matter if the engine is mariadb, mysql or aurora.  
After the primary node is deployed. you can attach read replicas to it.

```yml
    - name: add  reader nodes.
      rds_instance:
        engine: aurora-mysql
        db_instance_identifier: "{{ extra_node_name }}"
        instance_type: "{{ extra_node_type }}"
        cluster_id: "{{ cluster }}"
        region: "{{ region }}"
```

The question is, what else do you want to "manage"?  
You can force a failover also with `rds_instance`.   
A snapshot is targeting with `rds_instance_snapshot`.
TIL: https://github.com/ansible-collections/community.aws/pull/687  
`rds_cluster` is currently in development.
Files identified in the description:
* [`plugins/modules/rds.py`](https://github.com/ansible-collections/community.aws/blob/main/plugins/modules/rds.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @jillr @s-hertel @tremble @willthames @wimnat
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

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,1026 @@
+#!/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
+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_tags:
+        description:
+          - Whether or not to remove tags assigned to the DB cluster if not specified in the playbook. To remove all tags
+            set I(tags) to an empty dictionary in conjunction with this.
+        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
+    tags:
+        description:
+          - A dictionary of key value pairs to assign the DB cluster.
+        type: dict
+    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
+  community.aws.rds_cluster:
+    cluster_id: "{{ cluster_id }}"
+    engine: "aurora"
+    password: "{{ password }}"
+    username: "{{ username }}"
+
+- name: Add a new security group without purge
+  community.aws.rds_cluster:
+    id: "{{ cluster_id }}"
+    state: present
+    vpc_security_group_ids:
+      - sg-0be17ba10c9286b0b
+    purge_security_groups: false
+
+- name: Modify password
+  community.aws.rds_cluster:
+    id: "{{ cluster_id }}"
+    state: present
+    password: "{{ new_password }}"
+    force_update_password: true
+    apply_immediately: true
+
+- name: Rename the cluster
+  community.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
+  community.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
+  community.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_db_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
+
+    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'),
+        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
+  community.aws.rds_cluster_info:
+  register: _result_cluster_info
+
+- name: Get info on a specific DB cluster
+  community.aws.rds_cluster_info:
+    cluster_id: "{{ cluster_id }}"
+  register: _result_cluster_info
+
+- name: Get info all DB clusters with specific engine
+  community.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()


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,11 @@
+---
+# 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/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,36 @@
+---
+# 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'
+
+# 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,15 @@
+---
+- 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) }}"
+
+  collections:
+    - community.aws
+    - amazon.aws
+
+  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,122 @@
+---
+- 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,206 @@
+---
+- 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,197 @@
+---
+- 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: 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
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,186 @@
+---
+- 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: yes
+
+  - name: Create a source DB cluster
+    rds_cluster:
+      id: "{{ cluster_id }}"
+      state: present
+      engine: "{{ engine}}"
+      backup_retention_period: 1
+      username: "{{ username }}"
+      password: "{{ password }}"
+    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
+
+  # TODO: Requires rds_cluster_snapshot module
+  # - name: Take a snapshot of the DB cluster
+  #   rds_cluster_snapshot:
+  #     state: present
+  #     db_cluster_identifier: "{{ cluster_id }}"
+  #     db_snapshot_identifier: "{{ cluster_id }}-snapshot"
+  #   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-{{ resource_prefix }}-restored-snapshot"
+  #     snapshot_identifier: "cluster-{{ resource_prefix }}-snapshot"
+  #   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"
+  #     - "_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"
+
+  # 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_identifier: "{{ cluster_id }}-snapshot"
+  #   register: _result_delete_snapshot
+
+  - 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"
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,291 @@
+---
+- 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 "$@"