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

feat: add support config allow_connection and some things about read only routing #338

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
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
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,30 @@ Default: no default

Type: `string`

#### mssql_ha_secondary_role_allow_connections

A host var it means allow connections type when the replica is secondary role.

The available values are: `ALL`, `READ_ONLY`, `NO`.

Default: `ALL`

Type: `string`

#### mssql_ha_read_only_routing_list

Read only routing list in availability group for when the replica is primary role.

If variable is undefined will not set read only routing list.

See the doc from microsoft https://learn.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/configure-read-only-routing-for-an-availability-group-sql-server?view=sql-server-ver16

The example: 'node-4','node-6' or ('node-4','node-6')

Default: ``

Type: `string`

#### mssql_ha_endpoint_port

The TCP port used to replicate data for an Always On availability group.
Expand Down
46 changes: 38 additions & 8 deletions templates/configure_ag.j2
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,14 @@ removing this replica re-create it';
"setting_value":hostvars[item]['__mssql_ha_seeding_mode']
},
"allow_connections":{
"sql_setting_name": "SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)",
"sql_setting_name": "SECONDARY_ROLE (ALLOW_CONNECTIONS = " + (hostvars[item]['mssql_ha_secondary_role_allow_connections'] | default('ALL')) + ")",
"sys_setting_name": "secondary_role_allow_connections_desc",
"setting_value": "ALL"
"setting_value": (hostvars[item]['mssql_ha_secondary_role_allow_connections'] | default('ALL'))
},
"read_only_routing_url":{
"sql_setting_name": "SECONDARY_ROLE (READ_ONLY_ROUTING_URL = " + "N'tcp://" + hostvars[item]['ansible_fqdn'] + ":" + mssql_tcp_port | string + "'" + ")",
"sys_setting_name": "read_only_routing_url",
"setting_value":"N'tcp://" + hostvars[item]['ansible_fqdn'] + ":" + mssql_tcp_port | string + "'"
}
}) %}
{% elif hostvars[item]['mssql_ha_replica_type'] == 'witness' %}
Expand All @@ -155,7 +160,7 @@ removing this replica re-create it';
WHERE groups.name = '{{ mssql_ha_ag_name }}' AND
replicas.replica_server_name =
'{{ hostvars[item]['ansible_hostname'] }}' AND
{% if key == 'endpoint_url' %}
{% if key in ['endpoint_url', 'read_only_routing_url'] %}
{{ value.sys_setting_name }} = {{ value.setting_value }}
{% else %}
{{ value.sys_setting_name }} = '{{ value.setting_value }}'
Expand All @@ -164,24 +169,43 @@ removing this replica re-create it';
BEGIN
ALTER AVAILABILITY GROUP {{ mssql_ha_ag_name }} MODIFY REPLICA ON
N'{{ hostvars[item]['ansible_hostname'] }}' WITH (
{% if key == 'allow_connections' %}
{% if key in ['allow_connections', 'read_only_routing_url'] %}
{{ value.sql_setting_name }}
{% else %}
{{ value.sql_setting_name }} = {{ value.setting_value }}
{% endif %}
);
PRINT '{{ hostvars[item]['ansible_hostname'] }}: \
The {{ value.sql_setting_name }} setting on this \
The
{% if key == 'read_only_routing_url' %}
{{ value.sys_setting_name }}
{% else %}
{{ value.sql_setting_name }}
{% endif %}
setting on this \
{{ hostvars[item]['mssql_ha_replica_type'] }} replica configured successfully';
END
ELSE
BEGIN
PRINT '{{ hostvars[item]['ansible_hostname'] }}: \
The {{ value.sql_setting_name }} setting on this \
The
{% if key == 'read_only_routing_url' %}
{{ value.sys_setting_name }}
{% else %}
{{ value.sql_setting_name }}
{% endif %}
setting on this \
{{ hostvars[item]['mssql_ha_replica_type'] }} replica is already set \
correctly, skipping';
END
{% endfor %}
{% if not (hostvars[item]['mssql_ha_read_only_routing_list'] | default('')) == '' %}
ALTER AVAILABILITY GROUP {{ mssql_ha_ag_name }} MODIFY REPLICA ON
N'{{ hostvars[item]['ansible_hostname'] }}' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = ( {{ hostvars[item]['mssql_ha_read_only_routing_list'] }} )))
PRINT '{{ hostvars[item]['ansible_hostname'] }}: \
The mssql_ha_read_only_routing_list setting on this \
{{ hostvars[item]['mssql_ha_replica_type'] }} replica configured successfully';
{% endif %}
END
{% elif hostvars[item]['mssql_ha_replica_type'] == 'absent' %}
IF NOT EXISTS (
Expand Down Expand Up @@ -246,7 +270,10 @@ BEGIN
AVAILABILITY_MODE = {{ hostvars[item]['__mssql_ha_availability_mode'] }},
FAILOVER_MODE = {{ hostvars[item]['__mssql_ha_failover_mode'] }},
SEEDING_MODE = {{ hostvars[item]['__mssql_ha_seeding_mode'] }},
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
SECONDARY_ROLE (ALLOW_CONNECTIONS = {{ hostvars[item]['mssql_ha_secondary_role_allow_connections'] | default('ALL') }},READ_ONLY_ROUTING_URL = N'tcp://{{ hostvars[item]['ansible_fqdn'] }}:{{ mssql_tcp_port }}')
{% if not (hostvars[item]['mssql_ha_read_only_routing_list'] | default('')) == '' %}
,PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = ( {{ hostvars[item]['mssql_ha_read_only_routing_list'] }} ))
{% endif %}
{% elif hostvars[item]['mssql_ha_replica_type'] in ['synchronous', 'asynchronous'] %}
),
N'{{ hostvars[item]['ansible_hostname'] }}' WITH (
Expand All @@ -255,7 +282,10 @@ BEGIN
AVAILABILITY_MODE = {{ hostvars[item]['__mssql_ha_availability_mode'] }},
FAILOVER_MODE = {{ hostvars[item]['__mssql_ha_failover_mode'] }},
SEEDING_MODE = {{ hostvars[item]['__mssql_ha_seeding_mode'] }},
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
SECONDARY_ROLE (ALLOW_CONNECTIONS = {{ hostvars[item]['mssql_ha_secondary_role_allow_connections'] | default('ALL') }},READ_ONLY_ROUTING_URL = N'tcp://{{ hostvars[item]['ansible_fqdn'] }}:{{ mssql_tcp_port }}')
{% if not (hostvars[item]['mssql_ha_read_only_routing_list'] | default('')) == '' %}
,PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = ( {{ hostvars[item]['mssql_ha_read_only_routing_list'] }} ))
{% endif %}
{% elif hostvars[item]['mssql_ha_replica_type'] == 'witness' %}
),
N'{{ hostvars[item]['ansible_hostname'] }}' WITH (
Expand Down
134 changes: 134 additions & 0 deletions tests/test_ag_with_read_only_url_list_allow_connection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
#all:
# hosts:
# 192.168.200.136:
# ansible_user: root
# ansible_ssh_pass: "1q!"
# mssql_ha_replica_type: primary
# mssql_ha_secondary_role_allow_connections: READ_ONLY
# mssql_ha_read_only_routing_list: ('node-5','node-6')
# ha_cluster:
# node_name: node-4
# pcs_address: node-4
# corosync_addresses:
# - 192.168.200.136
# 192.168.200.137:
# ansible_user: root
# ansible_ssh_pass: "1q!"
# mssql_ha_replica_type: synchronous
# mssql_ha_secondary_role_allow_connections: READ_ONLY
# mssql_ha_read_only_routing_list: ('node-4','node-6')
# ha_cluster:
# node_name: node-5
# pcs_address: node-5
# corosync_addresses:
# - 192.168.200.137
# 192.168.200.138:
# ansible_user: root
# ansible_ssh_pass: "1q!"
# mssql_ha_replica_type: synchronous
# mssql_ha_secondary_role_allow_connections: READ_ONLY
# mssql_ha_read_only_routing_list: ('node-4','node-5')
# ha_cluster:
# node_name: node-6
# pcs_address: node-6
# corosync_addresses:
# - 192.168.200.138


- name: Test AG with read only URL list allow connection
hosts: all
vars:
mssql_accept_microsoft_odbc_driver_17_for_sql_server_eula: true
mssql_accept_microsoft_odbc_driver_for_sql_server_eula: true
mssql_accept_microsoft_cli_utilities_for_sql_server_eula: true
mssql_accept_microsoft_sql_server_standard_eula: true
mssql_version: 2022
mssql_password: "p@55w0rD"
mssql_edition: 2Q48Q-PB48J-DRCVN-GB844-X2H4Q
mssql_datadir: "/data/mssql/1433/database/"
mssql_logdir: "/data/mssql/1433/database/"
#mssql_pre_input_sql_content: "USE MASTER;CREATE DATABASE ExampleDB2;BACKUP DATABASE ExampleDB2 TO DISK='nil'with compression;"
mssql_enable_sql_agent: true
mssql_manage_firewall: true
mssql_run_selinux_confined: false
mssql_ha_configure: true
mssql_manage_ha_cluster: true
mssql_ha_prep_for_pacemaker: true
mssql_ha_ag_cluster_type: external
mssql_ha_endpoint_port: 5022
mssql_ha_cert_name: ExampleCert
mssql_ha_master_key_password: "p@55w0rD1"
mssql_ha_private_key_password: "p@55w0rD2"
mssql_ha_reset_cert: true
mssql_ha_endpoint_name: Example_Endpoint
mssql_ha_ag_name: ExampleAG
mssql_ha_db_names:
- test_1
mssql_ha_login: pacemakerLogin
mssql_ha_login_password: "p@55w0rD3"
mssql_ha_virtual_ip: 192.168.200.139
ha_cluster_cluster_name: "{{ mssql_ha_ag_name }}"
ha_cluster_hacluster_password: "p@55w0rD4"
ha_cluster_cluster_properties:
- attrs:
- name: cluster-recheck-interval
value: 2min
- name: start-failure-is-fatal
value: false
- name: stonith-enabled
value: false
ha_cluster_resource_primitives:
- id: ag_cluster
agent: ocf:mssql:ag
instance_attrs:
- attrs:
- name: ag_name
value: "{{ mssql_ha_ag_name }}"
meta_attrs:
- attrs:
- name: failure-timeout
value: 60s
- id: virtualip
agent: ocf:heartbeat:IPaddr2
instance_attrs:
- attrs:
- name: ip
value: "{{ mssql_ha_virtual_ip }}"
operations:
- action: monitor
attrs:
- name: interval
value: 30s
ha_cluster_resource_clones:
- resource_id: ag_cluster
promotable: yes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
promotable: yes
promotable: true

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the README example uses yes - but this fails ansible-lint - Ansible strongly prefers the use of true/false

meta_attrs:
- attrs:
- name: notify
value: true
ha_cluster_constraints_colocation:
- resource_leader:
id: ag_cluster-clone
role: Promoted
resource_follower:
id: virtualip
options:
- name: score
value: INFINITY
ha_cluster_constraints_order:
- resource_first:
id: ag_cluster-clone
action: promote
resource_then:
id: virtualip
action: start
tasks:
# - name: Set facts to create a test DB on primary as a pre task
# set_fact:
# mssql_pre_input_sql_file: create_ExampleDB.sql
# when: mssql_ha_replica_type == 'primary'

- name: Run on all hosts to configure HA cluster
include_role:
name: microsoft.sql.server