Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR #1647/51eeebbd backport][stable-6] Added started and stopped states for rds cluster #1684

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading