ansible_adanced_oci

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ansible_adanced_oci [2022/01/30 21:33] andonovjansible_adanced_oci [2024/08/19 13:03] (current) andonovj
Line 483: Line 483:
 </Code> </Code>
  
-That playbook, will +That playbook, will create a block device, attach it and also attach it on the host using the following playbook: 
 + 
 +<Code:bash|execute_shell_commands> 
 +--- 
 + 
 +- name: Attach the device 
 +  vars: 
 +    ansible_user: opc 
 +    ansible_become: yes 
 +    ansible_become_method: sudo 
 + 
 +  hosts: '{{ instance_ip }}' 
 +  tasks: 
 +    - block: 
 +      - name: Execute commands 
 +        ansible.builtin.command: '{{ item }}' 
 +        loop: '{{ bash_commands }}' 
 +</Code> 
 + 
 +With all that, we can finally configure the refresh (resnap) and configure the replication: 
 + 
 + 
 +====Resnap the primary block device==== 
 +<Code:bash|setup_resnap> 
 +--- 
 + 
 +- hosts: localhost 
 +  collections: 
 +    - oracle.oci 
 +  vars_files: 
 +    - /Users/julien.andonov/Work/POCE-playbooks/oci-ansible-collection/samples/compute/venv/variables.yml 
 + 
 +  tasks: 
 +    - block: 
 +      - name: Get Replica instance details 
 +        oci_compute_instance_facts: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          lifecycle_state: "RUNNING" 
 +          display_name: "{{ REPLICA }}" 
 +        register: replica_details 
 + 
 +      - name: Save Replica info 
 +        set_fact: 
 +          instance: '{{ replica_details["instances"] }}' 
 +          replica_ip: '{{replica_details["instances"] | map(attribute="primary_public_ip" }}' 
 + 
 +      - name: Add replica instance(s) to in-memory inventory 
 +        add_host: 
 +          name: "replica_ip" 
 +          ansible_host: '{{ replica_ip }}' 
 + 
 +      - name: Get attached devices on Replica 
 +        oci_compute_volume_attachment_facts: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          instance_id: "{{ replica_details.instances[0].id }}" 
 +        register: replica_volume_attachment_facts 
 + 
 +- import_playbook: detach_iscsi.yml 
 +  vars: 
 +    instance_ip: '{{ hostvars["localhost"]["replica_ip"] }}' 
 + 
 +- name: Create iSCSI attachement 
 +  hosts: localhost 
 +  collections: 
 +    - oracle.oci 
 +  vars_files: 
 +    - /Users/julien.andonov/Work/POCE-playbooks/oci-ansible-collection/samples/compute/venv/variables.yml 
 +  tasks: 
 +    - block: 
 +      - name: Get Primary instance details 
 +        oci_compute_instance_facts: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          lifecycle_state: "RUNNING" 
 +          display_name: "{{ PRIMARY }}" 
 +        register: primary_details 
 + 
 +      - name: Save primary info 
 +        set_fact: 
 +          instance: '{{ primary_details["instances"] }}' 
 +          primary_ip: '{{primary_details["instances"] | map(attribute="primary_public_ip" }}' 
 +          primary_prv_ip: '{{primary_details["instances"] | map(attribute="primary_private_ip" }}' 
 + 
 +      - name: Add primary instance(s) to in-memory inventory 
 +        add_host: 
 +          name: '{{ item }}' 
 +        loop: '{{ primary_ip }}' 
 + 
 +      - name: Get attached devices on Primary 
 +        oci_compute_volume_attachment_facts: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          instance_id: "{{ primary_details.instances[0].id }}" 
 +        register: primary_volume_attachment_facts 
 + 
 +      - name: Get all devices on Replica 
 +        oci_compute_volume_attachment_facts: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          instance_id: "{{ replica_details.instances[0].id }}" 
 +        register: replica_volume_attachment_facts 
 + 
 +      - name: Set fact, attached device on the replica 
 +        set_fact: 
 +          replica_attached_blockdevice_id: '{{ replica_volume_attachment_facts.volume_attachments | selectattr("lifecycle_state", "equalto", "ATTACHED") | map(attribute="id") }}' 
 +          replica_attached_volume_id: '{{ replica_volume_attachment_facts.volume_attachments | selectattr("lifecycle_state", "equalto", "ATTACHED") | map(attribute="volume_id") }}' 
 + 
 +      - name: Detach block level attachement device from Clone 
 +        oci_compute_volume_attachment: 
 +          volume_attachment_id: '{{ replica_attached_blockdevice_id[0] }}' 
 +          state: absent 
 +        when: replica_attached_blockdevice_id|length != 0 
 + 
 +      - name: Delete the block volume 
 +        oci_blockstorage_volume: 
 +          volume_id: '{{ replica_attached_volume_id[0] }}' 
 +          state: absent 
 +        when: replica_attached_volume_id|length != 0 
 + 
 +      - name: Create a clone data from another block volume in the same availability domain 
 +        oci_blockstorage_volume: 
 +          name: '{{ REPLICA }}-bv-clone' 
 +          source_details: 
 +            id: '{{ primary_volume_attachment_facts.volume_attachments[0].volume_id }}' 
 +            type: 'volume' 
 +          availability_domain: '{{ instance_ad }}' 
 +          compartment_id: '{{ instance_compartment }}' 
 +          size_in_gbs: 50 
 +        register: created_clone_block_volume 
 + 
 +      - name: Attach the clone to the replica 
 +        oci_compute_volume_attachment: 
 +          compartment_id: "{{ instance_compartment }}" 
 +          instance_id: "{{ replica_details.instances[0].id }}" 
 +          type: service_determined 
 +          volume_id: "{{ created_clone_block_volume.volume.id }}" 
 +        register: attached_block_device 
 + 
 +      - name: Save attachement commands 
 +        set_fact:  
 +          iscsi_attach_commands: '{{ attached_block_device.volume_attachment.iscsi_attach_commands }}' 
 + 
 +- import_playbook: execute_shell_commands_root.yml 
 +  vars: 
 +    instance_ip: '{{ hostvars["localhost"]["replica_ip"] }}' 
 +    bash_commands: '{{ hostvars["localhost"]["iscsi_attach_commands"] }}' 
 + 
 +- import_playbook: setup_replication.yml 
 +  vars: 
 +    instance_ip: '{{ hostvars["localhost"]["replica_ip"] }}' 
 +    primary_host: '{{ PRIMARY }}' 
 +    primary_prv_ip: '{{ hostvars["localhost"]["primary_prv_ip"] }}' 
 +    primary_password: '{{ root_password }}' 
 +</Code> 
 + 
 + 
 +That playbook will use our final playbook: "setup_replication", which you can see below: 
 + 
 +====Setup replication==== 
 +<Code: bash|Setup replication> 
 +--- 
 + 
 +- name: Detach the device 
 +  vars: 
 +    ansible_user: opc 
 +    ansible_become: yes 
 +    ansible_become_method: sudo 
 +  vars_files: 
 +    - /Users/julien.andonov/Work/POCE-playbooks/oci-ansible-collection/samples/compute/venv/variables.yml 
 +     
 +  hosts: '{{ instance_ip }}' 
 +  tasks: 
 +    - name: Stop Firewall 
 +      service: name=firewalld state=stopped enabled=false 
 + 
 +    - name: Get file coordinate 
 +      shell: | 
 +        cat /var/lib/mysql/mysql5/{{ PRIMARY }}-bin.index | tail -1 
 +      register: replication_file 
 + 
 +    - name: Get position coordinate 
 +      shell: | 
 +        wc {{ replication_file.stdout }} | awk -F " " '{print $3}' 
 +      register: replication_position 
 + 
 +    - name: Change the UUID of MySQL 
 +      shell: | 
 +        newUUID=`uuidgen` 
 +        echo " 
 +        [auto] 
 +        server-uuid=${newUUID}" > /var/lib/mysql/mysql5/auto.cnf 
 + 
 +    - name: Start MySQL 
 +      service: name=mysqld state=started enabled=true 
 + 
 +    - name: Change primary on Replica 
 +      community.mysql.mysql_replication: 
 +        mode: changeprimary 
 +        primary_host: '{{ primary_prv_ip[0] }}' 
 +        primary_log_file: '{{ replication_file.stdout }}' 
 +        primary_log_pos: '{{ replication_position.stdout }}' 
 +        login_unix_socket: /var/lib/mysql/mysql5/mysql.sock 
 +        login_user: root 
 +        login_password: "{{ root_password }}" 
 +        primary_user: 'replication' 
 +        primary_password: "{{ root_password }}" 
 + 
 +    - name: Start replica 
 +      community.mysql.mysql_replication: 
 +        mode: startreplica 
 +        login_unix_socket: /var/lib/mysql/mysql5/mysql.sock 
 +        login_user: root 
 +        login_password: "{{ root_password }}" 
 +</Code> 
 + 
 +With this, we were able to setup replication using OCI and ansible. The resnap can be done as many time as needed. It will always clone the primary's block device and attach it on replica, then it will re-establish replication. 
 + 
 +There is one more playbook which we need to add. 
 + 
 +<Code:bash|detach_iscsi> 
 +--- 
 + 
 +- name: Detach the device 
 +  vars: 
 +    ansible_user: opc 
 +    ansible_become: yes 
 +    ansible_become_method: sudo 
 + 
 +  hosts: '{{ instance_ip }}' 
 +  tasks: 
 +    - name: Find the IQN 
 +      shell: | 
 +        iscsiadm --mode session  -P 3 | grep Target: | head | awk -F " " '{print $2}' 
 +      register: iqn 
 + 
 +    - name: Stop  MySQL 
 +      service: name=mysqld state=stopped enabled=false 
 +      when: iqn.stdout != "" 
 + 
 +    - name: Find possible processes holding the file system 
 +      shell: | 
 +        lsof +D /var/lib/mysql |  awk -F " " '{print $2}' | uniq | grep -v "PID" 
 +      register: locking_processes 
 +      ignore_errors: yes 
 + 
 +    - name: Print locking process 
 +      debug: 
 +        msg: '{{ locking_processes }}' 
 +      when: locking_processes.stdout_lines|length != 0 
 + 
 +    - name: Kill and unmount the file system 
 +      shell: | 
 +        kill -9 '{{ item }}' 
 +      with_items: '{{ locking_processes.stdout_lines }}' 
 +      when: locking_processes.stdout_lines|length != 0 
 + 
 +    - name: Print IQN 
 +      debug: 
 +        msg: '{{iqn.stdout}}' 
 + 
 +    - name: Unmount File system 
 +      mount: 
 +        path: /var/lib/mysql 
 +        state: unmounted 
 + 
 +    - name: Detach the iSCSI 
 +      community.general.open_iscsi: 
 +        login: no 
 +        target: '{{iqn.stdout}}' 
 +      when: iqn.stdout != "" 
 +</Code> 
 + 
 +That playbook will stop the MySQL and detach the iSCSI from the compute node, so we can safely, remove it from the OCI as well. 
 + 
 +=====MySQL Clusterset Automation===== 
 +This ansible project consists of 3 roles: 
 +  - MySQL Instance 
 +  - MySQL InnoDB Cluster 
 +  - MySQL Router 
 + 
 +That will create architecture with 1 InnoDB Clusterset and a replicaset attached to it. The full code, you can see here: 
 + 
 +https://github.com/JulienAndonov/MySQL_Cluster_Ansible 
 + 
  • ansible_adanced_oci.1643578433.txt.gz
  • Last modified: 2022/01/30 21:33
  • by andonovj