Skip to content

Commit

Permalink
Added started and stopped states for rds cluster (#1647)
Browse files Browse the repository at this point in the history
Added started and stopped states for rds cluster

SUMMARY

Fixes #1616

ISSUE TYPE


Feature Pull Request

COMPONENT NAME

plugins/modules/rds_cluster.py
ADDITIONAL INFORMATION

Reviewed-by: Alina Buzachis
Reviewed-by: Mike Graves <[email protected]>
  • Loading branch information
taehopark32 authored Aug 2, 2023
1 parent 625777a commit 51eeebb
Show file tree
Hide file tree
Showing 7 changed files with 315 additions and 4 deletions.
4 changes: 4 additions & 0 deletions changelogs/fragments/1647-add-type-started-and-stopped.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
- rds_cluster - add support for another ``state`` choice called ``started``. This starts the rds cluster (https://github.com/ansible-collections/amazon.aws/pull/1647/files).
- rds_cluster - add support for another ``state`` choice called ``stopped``. This stops the rds cluster (https://github.com/ansible-collections/amazon.aws/pull/1647/files).
2 changes: 2 additions & 0 deletions plugins/module_utils/rds.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"remove_tags_from_resource",
"list_tags_for_resource",
"promote_read_replica_db_cluster",
"stop_db_cluster",
"start_db_cluster",
]
instance_method_names = [
"create_db_instance",
Expand Down
28 changes: 24 additions & 4 deletions plugins/modules/rds_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
options:
# General module options
state:
description: Whether the snapshot should exist or not.
choices: ['present', 'absent']
description:
- Whether the snapshot should exist or not.
- C(started) and C(stopped) can only be used with aurora clusters
- Support for C(started) and C(stopped) was added in release 6.3.0.
choices: ['present', 'absent', 'started', 'stopped']
default: 'present'
type: str
creation_source:
Expand Down Expand Up @@ -689,7 +692,6 @@
sample: sg-12345678
"""


try:
import botocore
except ImportError:
Expand Down Expand Up @@ -921,6 +923,14 @@ def get_rds_method_attribute_name(cluster):
if cluster and cluster["Status"] not in ["deleting", "deleted"]:
method_name = "delete_db_cluster"
method_options_name = "get_delete_options"
elif state == "started":
if cluster and cluster["Status"] not in ["starting", "started", "available"]:
method_name = "start_db_cluster"
method_options_name = "get_modify_options"
elif state == "stopped":
if cluster and cluster["Status"] not in ["stopping", "stopped"]:
method_name = "stop_db_cluster"
method_options_name = "get_modify_options"
else:
if cluster:
method_name = "modify_db_cluster"
Expand Down Expand Up @@ -1030,6 +1040,16 @@ def changing_cluster_options(modify_params, current_cluster):
if apply_immediately is not None:
changing_params["ApplyImmediately"] = apply_immediately

if module.params["state"] == "started":
if current_cluster["Engine"] in ["mysql", "postgres"]:
module.fail_json("Only aurora clusters can use the state started")
changing_params["DBClusterIdentifier"] = db_cluster_id

if module.params["state"] == "stopped":
if current_cluster["Engine"] in ["mysql", "postgres"]:
module.fail_json("Only aurora clusters can use the state stopped")
changing_params["DBClusterIdentifier"] = db_cluster_id

return changing_params


Expand Down Expand Up @@ -1087,7 +1107,7 @@ def main():
global client

arg_spec = dict(
state=dict(choices=["present", "absent"], default="present"),
state=dict(choices=["present", "absent", "started", "stopped"], 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),
Expand Down
4 changes: 4 additions & 0 deletions tests/integration/targets/rds_cluster_states/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
time=30m
cloud/aws
rds_cluster
rds_cluster_info
11 changes: 11 additions & 0 deletions tests/integration/targets/rds_cluster_states/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cluster_id: ansible-test-cluster-{{ tiny_prefix }}
username: testrdsusername
password: test-rds_password
engine: aurora
db_cluster_instance_class: db.r5.large

mysql_cluster_id: ansible-test-mysql-cluster-{{ tiny_prefix }}
mysql_engine: mysql
mysql_allocated_storage: 100
mysql_iops: 1000
mysql_db_cluster_instance_class: db.m5d.large
240 changes: 240 additions & 0 deletions tests/integration/targets/rds_cluster_states/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
- module_defaults:
group/aws:
region: '{{ aws_region }}'
aws_access_key: '{{ aws_access_key }}'
aws_secret_key: '{{ aws_secret_key }}'
security_token: '{{ security_token | default(omit) }}'
block:
# ------------------------------------------------------------------------------------------
# Create DB cluster
- 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 an Aurora-PostgreSQL DB cluster
rds_cluster:
id: '{{ cluster_id }}'
state: present
engine: aurora-postgresql
engine_mode: provisioned
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"
- _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 == "aurora-postgresql"
- "'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"
- "'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"

# ------------------------------------------------------------------------------------------
# Test stopping db clusters
- name: Stop db clusters - checkmode
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: stopped
register: check_stopped_cluster
check_mode: yes

- assert:
that:
- check_stopped_cluster.changed

- name: Stop db clusters
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: stopped
register: stopped_cluster

- assert:
that:
- stopped_cluster.changed

- name: Wait until db clusters state is stopped
amazon.aws.rds_cluster_info:
cluster_id: '{{ cluster_id }}'
register: stopped_cluster_info
retries: 30
delay: 60
until: stopped_cluster_info.clusters[0].status == "stopped"

- name: Stop db clusters (idempotence) - checkmode
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: stopped
register: check_stopped_cluster_idem
check_mode: yes

- assert:
that:
- not check_stopped_cluster_idem.changed

- name: Stop db clusters (idempotence)
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: stopped
register: stopped_cluster_idem

- assert:
that:
- not stopped_cluster_idem.changed

# ------------------------------------------------------------------------------------------
# Test starting DB clusters
- name: Start db clusters - checkmode
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: started
register: check_started_cluster
check_mode: yes

- assert:
that:
- check_started_cluster.changed

- name: Start db clusters
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: started
register: started_cluster

- assert:
that:
- started_cluster.changed

- name: Start db clusters (idempotence) - checkmode
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: started
register: check_started_cluster
check_mode: yes

- assert:
that:
- not check_started_cluster.changed

- name: Start db clusters
amazon.aws.rds_cluster:
cluster_id: '{{ cluster_id }}'
state: started
register: started_cluster

- assert:
that:
- not started_cluster.changed

# ------------------------------------------------------------------------------------------
# Give errors for MySql DB cluster
- name: Ensure the resource doesn't exist
rds_cluster:
id: '{{ mysql_cluster_id }}'
state: absent
engine: '{{ mysql_engine }}'
username: '{{ username }}'
password: '{{ password }}'
skip_final_snapshot: true
register: _result_delete_mysql_db_cluster

- assert:
that:
- not _result_delete_mysql_db_cluster.changed
ignore_errors: yes

- name: Create an MySql DB cluster
rds_cluster:
id: '{{ mysql_cluster_id }}'
state: present
engine: '{{ mysql_engine }}'
engine_mode: provisioned
allocated_storage: '{{ mysql_allocated_storage }}'
iops: '{{ mysql_iops }}'
db_cluster_instance_class: '{{ mysql_db_cluster_instance_class }}'
username: '{{ username }}'
password: '{{ password }}'
ignore_errors: yes
register: mysql_cluster

- assert:
that:
- mysql_cluster.changed
- "'allocated_storage' in mysql_cluster"
- mysql_cluster.allocated_storage == 100
- "'cluster_create_time' in mysql_cluster"
- mysql_cluster.copy_tags_to_snapshot == false
- "'db_cluster_arn' in mysql_cluster"
- mysql_cluster.db_cluster_identifier == "{{ mysql_cluster_id }}"
- "'db_cluster_parameter_group' in mysql_cluster"
- "'db_cluster_resource_id' in mysql_cluster"
- "'endpoint' in mysql_cluster"
- "'engine' in mysql_cluster"
- mysql_cluster.engine == "{{ mysql_engine }}"
- "'engine_mode' in mysql_cluster"
- mysql_cluster.engine_mode == "provisioned"
- "'engine_version' in mysql_cluster"
- "'master_username' in mysql_cluster"
- mysql_cluster.master_username == "{{ username }}"
- "'port' in mysql_cluster"
- "'status' in mysql_cluster"
- mysql_cluster.status == "available"
- "'tags' in mysql_cluster"
- "'vpc_security_groups' in mysql_cluster"


- name: Stop MySql DB cluster
amazon.aws.rds_cluster:
cluster_id: '{{ mysql_cluster_id }}'
state: stopped
register: mysql_cluster
ignore_errors: true

- assert:
that:
- mysql_cluster is failed
- mysql_cluster.msg == "Only aurora clusters can use the state stopped"

always:
# ------------------------------------------------------------------------------------------
# Cleanup starts here
- name: Delete MySql db cluster without creating a final snapshot
rds_cluster:
state: absent
cluster_id: '{{ mysql_cluster_id }}'
skip_final_snapshot: true
ignore_errors: true

- name: Delete Aurora-PostgreSql db cluster without creating a final snapshot
rds_cluster:
state: absent
cluster_id: '{{ cluster_id }}'
skip_final_snapshot: true
ignore_errors: true
30 changes: 30 additions & 0 deletions tests/unit/module_utils/test_rds.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,36 @@ def test__wait_for_cluster_snapshot_status_failed(input, expected):
)
),
),
(
"start_db_cluster",
{
"new_db_cluster_identifier": "test",
},
*expected(
rds.Boto3ClientMethod(
name="start_db_cluster",
waiter="cluster_available",
operation_description="start DB cluster",
resource="cluster",
retry_codes=["InvalidDBClusterState"],
)
),
),
(
"stop_db_cluster",
{
"new_db_cluster_identifier": "test",
},
*expected(
rds.Boto3ClientMethod(
name="stop_db_cluster",
waiter="cluster_available",
operation_description="stop DB cluster",
resource="cluster",
retry_codes=["InvalidDBClusterState"],
)
),
),
(
"restore_db_cluster_from_snapshot",
{
Expand Down

0 comments on commit 51eeebb

Please sign in to comment.