Ansible: Create new RDS DB from last snapshot of a

2019-09-01 16:38发布

Promote command does not seem to work on the version of Ansible that I am using. So I am trying to create a new database as a replica of an existing one and after making it master, delete the source database.

I was trying to do it like this:

  1. Make replica
  2. Promote replica
  3. Delete source database

But now I am thinking of this:

  1. Create new database from source database last snapshot [as master from the beginning]
  2. Delete the source database

How would that playbook go?

My playbook:

 - hosts: localhost
   vars:
     source_db_name: "{{ SOURCE_DB }}" # stagingdb
     new_db_name: "{{ NEW_DB  }}" # stagingdb2
   tasks:
   - name: Make RDS replica
     local_action:
       module: rds
       region: us-east-1
       command: replicate
       instance_name  : "{{ new_db_name  }}"
       source_instance: "{{ source_db_name  }}"
       wait: yes
       wait_timeout: 900 # wait 15 minutes

# Notice - not working [Ansible bug]
   - name: Promote RDS replica
     local_action:
       module: rds
       region: us-east-1
       command: promote
       instance_name: "{{ new_db_name }}" # stagingdb2
       backup_retention: 0
       wait: yes
       wait_timeout: 300

   - name: Delete source db
     local_action:
       command: delete
       instance_name: "{{ source_db_name }}"
       region: us-east-1

1条回答
霸刀☆藐视天下
2楼-- · 2019-09-01 17:06

You just need to use the restore command in the RDS module.

Your playbook would then look something like:

 - hosts: localhost
   connection: local
   gather_facts: yes
   vars:
     date: "{{ ansible_date_time.year }}-{{ ansible_date_time.month }}-{{ ansible_date_time.day }}-{{ ansible_date_time.hour }}-{{ ansible_date_time.minute }}"
     source_db_name: "{{ SOURCE_DB }}" # stagingdb
     new_db_name: "{{ NEW_DB  }}" # stagingdb2
     snapshot_name: "snapshot-{{ source_db_name }}--{{ date }}"
   tasks:
   - name : Take RDS snapshot
     rds  :
       command       : snapshot
       instance_name : "{{ source_db_name }}"
       snapshot      : "{{ snapshot_name }}"
       wait          : yes
     register: snapshot_out

    - name : get facts
      rds  :
        command       : facts
        instance_name : "{{ instance_name }}"
      register: db_facts

   - name : Restore RDS from snapshot
     rds  :
        command           : restore
        instance_name     : "{{ new_db_name }}"
        snapshot          : "{{ snapshot_name }}"
        instance_type     : "{{ db_facts.instance.instance_type }}"
        subnet            : primary # Unfortunately this isn't returned by db_facts
        wait              : yes
        wait_timeout      : 1200

   - name : Delete source db
     rds  :
        command       : delete
        instance_name : "{{ source_db_name }}"

There's a couple of extra tricks in there:

  • I set connection to local at the start of the play so, when combined with hosts: localhost all of the tasks will be local tasks.
  • I build a date time stamp that looks like YYYY-mm-dd-hh-mm from the Ansible host's own facts (from gather_facts and it only targeting localhost). This is then used for the snapshot name to make sure that we create it (if one exists with the same name then Ansible won't create another snapshot - something that could be bad in this case as it would use an older snapshot before deleting your source database).
  • I fetch the facts about the RDS instance in a task and use that to set the instance type to be the same as the source database. If you don't want that then you can define the instance_type directly and remove the whole get facts task
查看更多
登录 后发表回答