diff --git a/README.md b/README.md index 24c74f4d..abc57d62 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,28 @@ Default: `null` Type: `string` +#### mssql_tools_versions + +List of versions of SQL Tools package (mssql-tools) to install and use `sqlcmd` from. + +The role uses `sqlcmd` for the following tasks: + +* Checking password for the sa user. +* Running T-SQL scripts with variables [mssql_pre_input_sql_file and mssql_post_input_sql_file](#mssql_pre_input_sql_file-and-mssql_post_input_sql_file), [mssql_pre_input_sql_content and mssql_post_input_sql_content](#mssql_pre_input_sql_content-and-mssql_post_input_sql_content). + +By default, installs and uses the latest version 18. + +You can set this variable to `[17, 18]` to install two versions in parallel. +In the case when this variable contains multiple elements, the role instals both but uses latest provided version. + +The role does not remove mssql-tools packages if you unset a version with this variable. + +If you use version 18 and [mssql_tls_enable](#mssql_tls_enable) with self-signed certificates, you must set [mssql_tls_self_sign](#mssql_tls_self_sign) to `true`. + +Default: `[18]` + +Type: `list` + #### mssql_enable_sql_agent Optional: Set this variable to `true` or `false` to enable or disable the SQL agent. @@ -600,6 +622,16 @@ Default: `false` Type: `bool` +#### mssql_tls_self_sign + +Whether certificates that you use are self-signed or not. + +Based on this, the role decides whether to run `sqlcmd` with the `-C` argument to trust certificates. + +Default: `false` + +Type: `bool` + ### TLS Certificates Example Playbooks #### Configuring SQL Server with TLS Encryption with Certificate Files diff --git a/defaults/main.yml b/defaults/main.yml index ea659485..74fdcb3d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -7,6 +7,7 @@ mssql_version: null mssql_upgrade: false mssql_password: null mssql_edition: null +mssql_tools_versions: [18] mssql_tcp_port: 1433 mssql_manage_firewall: false mssql_ip_address: null @@ -32,6 +33,7 @@ mssql_tls_force: false mssql_tls_version: 1.2 mssql_tls_remote_src: false mssql_tls_certificates: [] +mssql_tls_self_sign: false mssql_rpm_key: https://packages.microsoft.com/keys/microsoft.asc mssql_server_repository: "{{ __mssql_server_repository }}" diff --git a/tasks/main.yml b/tasks/main.yml index cae30fab..5dc9b772 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -492,6 +492,111 @@ environment: ACCEPT_EULA: Y +- name: Configure TLS encryption + when: mssql_tls_enable is not none + block: + - name: >- + Create certificate and private_key files and set mssql_tls_cert + and _private_key + when: + - mssql_tls_enable | bool + - mssql_tls_certificates | length > 0 + block: + - name: Create certificates using the certificate role + include_role: + name: fedora.linux_system_roles.certificate + vars: + certificate_requests: | + {% for _cert in mssql_tls_certificates %} + {% set _basename = _cert.name | basename %} + {% set _ = _cert.__setitem__('name', _basename) %} + {% set _ = _cert.__setitem__('owner', 'mssql') %} + {% set _ = _cert.__setitem__('group', 'mssql') %} + {% set _ = _cert.__setitem__('mode', '0600') %} + {% endfor %} + {{ mssql_tls_certificates }} + + - name: Set mssql_tls_cert and _private_key based on the cert name + set_fact: + mssql_tls_cert: "{{ mssql_tls_certificates.0.name }}.crt" + mssql_tls_private_key: "{{ mssql_tls_certificates.0.name }}.key" + + - name: Copy certificate and private_key files to the host + when: + - mssql_tls_enable | bool + - mssql_tls_certificates | length == 0 + copy: + src: "{{ item }}" + remote_src: "{{ mssql_tls_remote_src }}" + dest: >- + /etc/pki/tls/{{ 'certs' if item == mssql_tls_cert + else 'private' }}/{{ item | basename }} + owner: mssql + group: mssql + mode: "0600" + force: "{{ mssql_tls_force }}" + with_items: + - "{{ mssql_tls_cert }}" + - "{{ mssql_tls_private_key }}" + + - name: Configure the tlscert setting + include_tasks: mssql_conf_setting.yml + vars: + __mssql_tls_cert_dest: >- + /etc/pki/tls/certs/{{ mssql_tls_cert | basename }} + __mssql_conf_setting: "network tlscert" + __mssql_conf_setting_value: >- + {{ __mssql_tls_cert_dest if mssql_tls_enable else 'unset' }} + + - name: Configure the tlskey setting + include_tasks: mssql_conf_setting.yml + vars: + __mssql_tls_private_key_dest: >- + /etc/pki/tls/private/{{ mssql_tls_private_key | basename }} + __mssql_conf_setting: "network tlskey" + __mssql_conf_setting_value: >- + {{ __mssql_tls_private_key_dest if mssql_tls_enable else 'unset' }} + + - name: Configure the tlsprotocols setting + include_tasks: mssql_conf_setting.yml + vars: + __mssql_conf_setting: "network tlsprotocols" + __mssql_conf_setting_value: >- + {{ mssql_tls_version if mssql_tls_enable else 'unset' }} + + - name: Configure the forceencryption setting + include_tasks: mssql_conf_setting.yml + vars: + __mssql_conf_setting: "network forceencryption" + __mssql_conf_setting_value: "{{ '1' if mssql_tls_enable else 'unset' }}" + +- name: Append -C to sqlcmd + when: __sqlcmd_ver | int == 18 + block: + - name: Get the setting forceencryption + shell: >- + set -euo pipefail; + grep '^forceencryption' {{ __mssql_conf_path }} + | sed 's/forceencryption = //g' + changed_when: false + failed_when: false + register: __mssql_forceencryption_val + + - name: Append -No to sqlcmd when TLS is not configured + when: + - __mssql_forceencryption_val.stdout != '1' + - "'-No' not in __sqlcmd_cli" + set_fact: + __sqlcmd_cli: "{{ __sqlcmd_cli + ' -No' }}" + + - name: Append -C to sqlcmd when TLS is configured but certs are self-signed + when: + - __mssql_forceencryption_val.stdout == '1' + - mssql_tls_self_sign | bool + - "'-C' not in __sqlcmd_cli" + set_fact: + __sqlcmd_cli: "{{ __sqlcmd_cli + ' -C' }}" + - name: Set a new password for the MSSQL sa user when: - __mssql_conf_setup is skipped @@ -741,85 +846,6 @@ __mssql_conf_setting_value: >- {{ 1 if mssql_tune_for_fua_storage else 0 }} -- name: Configure TLS encryption - when: - - mssql_tls_enable is not none - block: - - name: >- - Create certificate and private_key files and set mssql_tls_cert - and _private_key - when: - - mssql_tls_enable | bool - - mssql_tls_certificates | length > 0 - block: - - name: Create certificates using the certificate role - include_role: - name: fedora.linux_system_roles.certificate - vars: - certificate_requests: | - {% for _cert in mssql_tls_certificates %} - {% set _basename = _cert.name | basename %} - {% set _ = _cert.__setitem__('name', _basename) %} - {% set _ = _cert.__setitem__('owner', 'mssql') %} - {% set _ = _cert.__setitem__('group', 'mssql') %} - {% set _ = _cert.__setitem__('mode', '0600') %} - {% endfor %} - {{ mssql_tls_certificates }} - - - name: Set mssql_tls_cert and _private_key based on the cert name - set_fact: - mssql_tls_cert: "{{ mssql_tls_certificates.0.name }}.crt" - mssql_tls_private_key: "{{ mssql_tls_certificates.0.name }}.key" - - - name: Copy certificate and private_key files to the host - when: - - mssql_tls_enable | bool - - mssql_tls_certificates | length == 0 - copy: - src: "{{ item }}" - remote_src: "{{ mssql_tls_remote_src }}" - dest: >- - /etc/pki/tls/{{ 'certs' if item == mssql_tls_cert - else 'private' }}/{{ item | basename }} - owner: mssql - group: mssql - mode: "0600" - force: "{{ mssql_tls_force }}" - with_items: - - "{{ mssql_tls_cert }}" - - "{{ mssql_tls_private_key }}" - - - name: Configure the tlscert setting - include_tasks: mssql_conf_setting.yml - vars: - __mssql_tls_cert_dest: >- - /etc/pki/tls/certs/{{ mssql_tls_cert | basename }} - __mssql_conf_setting: "network tlscert" - __mssql_conf_setting_value: >- - {{ __mssql_tls_cert_dest if mssql_tls_enable else 'unset' }} - - - name: Configure the tlskey setting - include_tasks: mssql_conf_setting.yml - vars: - __mssql_tls_private_key_dest: >- - /etc/pki/tls/private/{{ mssql_tls_private_key | basename }} - __mssql_conf_setting: "network tlskey" - __mssql_conf_setting_value: >- - {{ __mssql_tls_private_key_dest if mssql_tls_enable else 'unset' }} - - - name: Configure the tlsprotocols setting - include_tasks: mssql_conf_setting.yml - vars: - __mssql_conf_setting: "network tlsprotocols" - __mssql_conf_setting_value: >- - {{ mssql_tls_version if mssql_tls_enable else 'unset' }} - - - name: Configure the forceencryption setting - include_tasks: mssql_conf_setting.yml - vars: - __mssql_conf_setting: "network forceencryption" - __mssql_conf_setting_value: "{{ '1' if mssql_tls_enable else 'unset' }}" - - name: Configure Active Directory authentication when: mssql_ad_configure | bool block: diff --git a/tasks/verify_password.yml b/tasks/verify_password.yml index 68320d93..72084098 100644 --- a/tasks/verify_password.yml +++ b/tasks/verify_password.yml @@ -30,7 +30,7 @@ {{ __ipaddress if __ipaddress else '127.0.0.1' if __tcpport else '' }} set_fact: __mssql_sqlcmd_login_cmd: >- - /opt/mssql-tools/bin/sqlcmd + {{ __sqlcmd_cli }} {{ __s_arg }} {{ __ipaddress_arg }}{{ ',' if __tcpport else '' }}{{ __tcpport if __tcpport else '' }} diff --git a/tests/tasks/assert_fail_on_unsupported_ver.yml b/tests/tasks/assert_fail_on_unsupported_ver.yml index 17742cd5..e2dee1f9 100644 --- a/tests/tasks/assert_fail_on_unsupported_ver.yml +++ b/tests/tasks/assert_fail_on_unsupported_ver.yml @@ -8,9 +8,9 @@ (ansible_distribution in ['CentOS', 'RedHat'] and ansible_distribution_major_version is version('7', '=') and mssql_version | int == 2022) or - ((ansible_distribution in ['CentOS', 'RedHat'] and + (((ansible_distribution in ['CentOS', 'RedHat'] and ansible_distribution_major_version is version('9', '=')) or - (ansible_distribution in ['Fedora']) + (ansible_distribution in ['Fedora'])) and mssql_version | int != 2022) block: diff --git a/tests/tasks/cleanup.yml b/tests/tasks/cleanup.yml index 34753620..3abccbd4 100644 --- a/tests/tasks/cleanup.yml +++ b/tests/tasks/cleanup.yml @@ -46,7 +46,7 @@ name: - adutil - mssql-server - - mssql-tools + - mssql-tools* - unixODBC-devel - mssql-server-fts - mssql-server-ha diff --git a/tests/tasks/tests_password.yml b/tests/tasks/tests_password.yml index 60b20291..9b71a665 100644 --- a/tests/tasks/tests_password.yml +++ b/tests/tasks/tests_password.yml @@ -8,6 +8,7 @@ vars: mssql_password: "p@55w0rD" mssql_edition: Evaluation + mssql_tools_versions: [17] - name: Configure the mssql-server service start limit interval and burst include_tasks: tasks/mssql-sever-increase-start-limit.yml @@ -25,6 +26,12 @@ vars: __verify_mssql_password: "p@55w0rD11" +- name: Verify the package {{ __mssql_verify_package_name }} + include_tasks: verify_package.yml + vars: + __mssql_verify_package_name: mssql-tools + __mssql_verify_package_installed: true + - name: Change the IP address setting. include_role: name: linux-system-roles.mssql @@ -38,12 +45,19 @@ name: linux-system-roles.mssql vars: mssql_password: "p@55w0rD" + mssql_tools_versions: [17, 18] - name: Verify settings include_tasks: tasks/verify_settings.yml vars: __verify_mssql_password: "p@55w0rD" +- name: Verify the package {{ __mssql_verify_package_name }} + include_tasks: verify_package.yml + vars: + __mssql_verify_package_name: mssql-tools18 + __mssql_verify_package_installed: true + - name: Change the TCP port setting. include_role: name: linux-system-roles.mssql @@ -57,11 +71,18 @@ name: linux-system-roles.mssql vars: mssql_password: "p@55w0rD11" + mssql_tools_versions: [18] - name: Verify settings include_tasks: tasks/verify_settings.yml vars: __verify_mssql_password: "p@55w0rD11" +- name: Verify the package {{ __mssql_verify_package_name }} + include_tasks: verify_package.yml + vars: + __mssql_verify_package_name: mssql-tools18 + __mssql_verify_package_installed: true + - name: Check the ansible_managed header in the configuration file include_tasks: tasks/check_header.yml diff --git a/tests/tasks/verify_ad_auth.yml b/tests/tasks/verify_ad_auth.yml index 27804c05..d4f7a426 100644 --- a/tests/tasks/verify_ad_auth.yml +++ b/tests/tasks/verify_ad_auth.yml @@ -47,7 +47,7 @@ {{ ansible_fqdn }} "echo {{ ad_integration_password | quote }} | kinit {{ __mssql_kinit_user }} && - /opt/mssql-tools/bin/sqlcmd -S. -Q 'SELECT SYSTEM_USER'" + /opt/mssql-tools18/bin/sqlcmd -S. -Q 'SELECT SYSTEM_USER'" register: __mssql_ad_test changed_when: false always: diff --git a/tests/tests_tls_2017.yml b/tests/tests_tls_2017.yml index 6af991ea..18e071fc 100644 --- a/tests/tests_tls_2017.yml +++ b/tests/tests_tls_2017.yml @@ -10,6 +10,7 @@ mssql_edition: Evaluation mssql_tcp_port: 1433 mssql_version: 2017 + mssql_tls_self_sign: true __mssql_gather_facts_no_log: true tasks: - name: Run test in a block to clean up in always diff --git a/tests/tests_tls_2019.yml b/tests/tests_tls_2019.yml index 1cdce519..5eec25ed 100644 --- a/tests/tests_tls_2019.yml +++ b/tests/tests_tls_2019.yml @@ -10,6 +10,7 @@ mssql_edition: Evaluation mssql_tcp_port: 1433 mssql_version: 2019 + mssql_tls_self_sign: true __mssql_gather_facts_no_log: true tasks: - name: Run test in a block to clean up in always diff --git a/tests/tests_tls_2022.yml b/tests/tests_tls_2022.yml index 506eada1..9402ca44 100644 --- a/tests/tests_tls_2022.yml +++ b/tests/tests_tls_2022.yml @@ -10,6 +10,7 @@ mssql_edition: Evaluation mssql_tcp_port: 1433 mssql_version: 2022 + mssql_tls_self_sign: true mssql_manage_selinux: "{{ mssql_run_selinux_confined }}" __mssql_gather_facts_no_log: true tasks: diff --git a/vars/main.yml b/vars/main.yml index ad79f4ca..96296e29 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -12,7 +12,13 @@ __mssql_required_facts_subsets: "{{ ['!all', '!min'] + __mssql_required_facts }}" __mssql_server_packages: mssql-server __mssql_server_selinux_packages: mssql-server-selinux -__mssql_client_packages: [mssql-tools, unixODBC-devel] +__sqlcmd_ver: "{{ mssql_tools_versions | sort | last }}" +__sqlcmd_cli: "{{ + '/opt/mssql-tools/bin/sqlcmd' if __sqlcmd_ver == '17' + else '/opt/mssql-tools' + __sqlcmd_ver + '/bin/sqlcmd' }}" +__mssql_client_packages: + - mssql-tools{{ '' if __sqlcmd_ver == '17' else __sqlcmd_ver }} + - unixODBC-devel __mssql_server_fts_packages: mssql-server-fts __mssql_server_ha_packages: mssql-server-ha __mssql_powershell_packages: powershell