--- - vars: mysql_parameters: &mysql_params login_user: '{{ mysql_user }}' login_password: '{{ mysql_password }}' login_host: 127.0.0.1 login_port: '{{ mysql_primary_port }}' block: # ============================================================ - name: find out the database version mysql_info: <<: *mysql_params filter: version register: db_version - name: Drop mysql user {{ item }} if exists mysql_user: <<: *mysql_params name: '{{ item }}' state: absent with_items: ['{{ user_name_1 }}', '{{ user_name_2 }}', '{{ user_name_3 }}'] - name: create user with TLS requirements in check mode (expect changed=true) mysql_user: <<: *mysql_params name: "{{ user_name_1 }}" password: "{{ user_password_1 }}" tls_requires: SSL: check_mode: yes register: result - name: Assert check mode user create reports changed state assert: that: - result is changed - include: assert_no_user.yml user_name={{user_name_1}} - name: create user with TLS requirements state=present (expect changed=true) mysql_user: <<: *mysql_params name: '{{ item[0] }}' password: '{{ user_password_1 }}' tls_requires: '{{ item[1] }}' with_together: - [ '{{ user_name_1 }}', '{{ user_name_2 }}', '{{ user_name_3 }}'] - - SSL: - X509: - subject: '/CN=alice/O=MyDom, Inc./C=US/ST=Oregon/L=Portland' cipher: 'ECDHE-ECDSA-AES256-SHA384' issuer: '/CN=org/O=MyDom, Inc./C=US/ST=Oregon/L=Portland' - block: - name: retrieve TLS requirements for users in old database version command: "{{ mysql_command }} -L -N -s -e \"SHOW GRANTS for '{{ item }}'@'localhost'\"" register: old_result with_items: ['{{ user_name_1 }}', '{{ user_name_2 }}', '{{ user_name_3 }}'] - name: set old database separator set_fact: separator: '\n' # Semantically: when mysql version <= 5.6 or MariaDB version <= 10.1 when: db_version.version.major <= 5 and db_version.version.minor <= 6 or db_version.version.major == 10 and db_version.version.minor < 2 - block: - name: retrieve TLS requirements for users in new database version command: "{{ mysql_command }} -L -N -s -e \"SHOW CREATE USER '{{ item }}'@'localhost'\"" register: new_result with_items: ['{{ user_name_1 }}', '{{ user_name_2 }}', '{{ user_name_3 }}'] - name: set new database separator set_fact: separator: 'PASSWORD' # Semantically: when mysql version >= 5.7 or MariaDB version >= 10.2 when: db_version.version.major == 5 and db_version.version.minor >= 7 or db_version.version.major > 5 and db_version.version.major < 10 or db_version.version.major == 10 and db_version.version.minor >= 2 - block: - name: assert user1 TLS requirements assert: that: - "'SSL' in reqs" vars: - reqs: "{{((old_result.results[0] is skipped | ternary(new_result, old_result)).results | selectattr('item', 'contains', user_name_1) | first).stdout.split('REQUIRE')[1].split(separator)[0].strip()}}" - name: assert user2 TLS requirements assert: that: - "'X509' in reqs" vars: - reqs: "{{((old_result.results[0] is skipped | ternary(new_result, old_result)).results | selectattr('item', 'contains', user_name_2) | first).stdout.split('REQUIRE')[1].split(separator)[0].strip()}}" - name: assert user3 TLS requirements assert: that: - "'/CN=alice/O=MyDom, Inc./C=US/ST=Oregon/L=Portland' in (reqs | select('contains', 'SUBJECT') | first)" - "'/CN=org/O=MyDom, Inc./C=US/ST=Oregon/L=Portland' in (reqs | select('contains', 'ISSUER') | first)" - "'ECDHE-ECDSA-AES256-SHA384' in (reqs | select('contains', 'CIPHER') | first)" vars: - reqs: "{{((old_result.results[0] is skipped | ternary(new_result, old_result)).results | selectattr('item', 'contains', user_name_3) | first).stdout.split('REQUIRE')[1].split(separator)[0].replace(\"' \", \"':\").split(\":\")}}" # CentOS 6 uses an older version of jinja that does not provide the selectattr filter. when: ansible_distribution != 'CentOS' or ansible_distribution_major_version != '6' - name: modify user with TLS requirements state=present in check mode (expect changed=true) mysql_user: <<: *mysql_params name: '{{ user_name_1 }}' password: '{{ user_password_1 }}' tls_requires: X509: check_mode: yes register: result - name: Assert check mode user update reports changed state assert: that: - result is changed - name: retrieve TLS requirements for users in old database version command: "{{ mysql_command }} -L -N -s -e \"SHOW GRANTS for '{{ user_name_1 }}'@'localhost'\"" register: old_result when: db_version.version.major <= 5 and db_version.version.minor <= 6 or db_version.version.major == 10 and db_version.version.minor < 2 - name: retrieve TLS requirements for users in new database version command: "{{ mysql_command }} -L -N -s -e \"SHOW CREATE USER '{{ user_name_1 }}'@'localhost'\"" register: new_result when: db_version.version.major == 5 and db_version.version.minor >= 7 or db_version.version.major > 5 and db_version.version.major < 10 or db_version.version.major == 10 and db_version.version.minor >= 2 - name: assert user1 TLS requirements was not changed assert: that: "'SSL' in reqs" vars: - reqs: "{{(old_result is skipped | ternary(new_result, old_result)).stdout.split('REQUIRE')[1].split(separator)[0].strip()}}" - name: modify user with TLS requirements state=present (expect changed=true) mysql_user: <<: *mysql_params name: '{{ user_name_1 }}' password: '{{ user_password_1 }}' tls_requires: X509: - name: retrieve TLS requirements for users in old database version command: "{{ mysql_command }} -L -N -s -e \"SHOW GRANTS for '{{ user_name_1 }}'@'localhost'\"" register: old_result when: db_version.version.major <= 5 and db_version.version.minor <= 6 or db_version.version.major == 10 and db_version.version.minor < 2 - name: retrieve TLS requirements for users in new database version command: "{{ mysql_command }} -L -N -s -e \"SHOW CREATE USER '{{ user_name_1 }}'@'localhost'\"" register: new_result when: db_version.version.major == 5 and db_version.version.minor >= 7 or db_version.version.major > 5 and db_version.version.major < 10 or db_version.version.major == 10 and db_version.version.minor >= 2 - name: assert user1 TLS requirements assert: that: "'X509' in reqs" vars: - reqs: "{{(old_result is skipped | ternary(new_result, old_result)).stdout.split('REQUIRE')[1].split(separator)[0].strip()}}" - name: remove TLS requirements from user (expect changed=true) mysql_user: <<: *mysql_params name: '{{ user_name_1 }}' password: '{{ user_password_1 }}' tls_requires: - name: retrieve TLS requirements for users command: "{{ mysql_command }} -L -N -s -e \"SHOW CREATE USER '{{ user_name_1 }}'@'localhost'\"" register: result - name: assert user1 TLS requirements assert: that: "'REQUIRE ' not in result.stdout or 'REQUIRE NONE' in result.stdout" - include: remove_user.yml user_name={{user_name_1}} user_password={{ user_password_1 }} - include: remove_user.yml user_name={{user_name_2}} user_password={{ user_password_1 }} - include: remove_user.yml user_name={{user_name_3}} user_password={{ user_password_1 }} - include: assert_no_user.yml user_name={{user_name_1}} - include: assert_no_user.yml user_name={{user_name_2}} - include: assert_no_user.yml user_name={{user_name_3}}