community.mysql.mysql_role 模块 – 添加、删除或更新 MySQL 或 MariaDB 角色

注意

此模块是 community.mysql 集合 (版本 3.11.0) 的一部分。

如果您正在使用 ansible 包,则可能已经安装了此集合。它不包含在 ansible-core 中。要检查它是否已安装,请运行 ansible-galaxy collection list

要安装它,请使用:ansible-galaxy collection install community.mysql。您需要其他要求才能使用此模块,请参阅 要求 获取详细信息。

要在 playbook 中使用它,请指定:community.mysql.mysql_role

community.mysql 2.2.0 中的新增功能

概要

  • 添加、删除或更新 MySQL 或 MariaDB 角色。

  • 从 MySQL 8.0.0 和 MariaDB 10.0.5 开始支持角色。

要求

在执行此模块的主机上需要以下要求。

  • PyMySQL (Python 2.7 和 Python 3.x)

参数

参数

注释

admin

字符串

MariaDB 支持。

角色的管理员用户名(默认为 _login_user_)。

append_members

布尔值

将由 _members_ 选项定义的成员添加到此角色的现有成员中,而不是覆盖它们。

与 _detach_members_ 和 _admin_ 选项互斥。

选项

  • false ← (默认)

  • true

append_privs

布尔值

将由 _priv_ 选项定义的权限添加到此角色的现有权限中,而不是覆盖它们。与 _subtract_privs_ 互斥。

选项

  • false ← (默认)

  • true

ca_cert

别名:ssl_ca

路径

证书颁发机构 (CA) 证书的路径。如果使用此选项,则必须指定与服务器使用的证书相同的证书。

check_hostname

布尔值

community.mysql 1.1.0 中新增

当需要 SSL 连接时是否验证服务器主机名。对应于 MySQL CLI 的 --ssl 开关。

将其设置为 false 将禁用主机名验证。谨慎使用。

需要 pymysql >= 0.7.11。

选项

  • false

  • true

check_implicit_admin

布尔值

在尝试提供的凭据之前,检查 mysql 是否允许以 root/nopassword 登录。

如果成功,则将忽略传递的 _login_user_/_login_password_。

选项

  • false ← (默认)

  • true

client_cert

别名:ssl_cert

路径

客户端公钥证书的路径。

client_key

别名:ssl_key

路径

客户端私钥的路径。

column_case_sensitive

布尔值

community.mysql 3.8.0 中新增

默认为 false

true 时,模块不会将权限中的字段大写。

false 时,字段名将大写。这是引入此功能之前的默认设置,但由于 MySQL/MariaDB 区分大小写,因此在大多数情况下应将其设置为 true

选项

  • false

  • true

config_file

路径

指定从中读取用户和密码的配置文件。

如果存在,则即使未指定 _config_file_,也会读取默认配置文件 ~/.my.cnf

如果存在,默认配置文件 ~/.my.cnf 必须包含 [client] 部分,这是 MySQL 连接器的要求。

要阻止读取默认配置文件,请将 _config_file_ 设置为空字符串。

默认值: "~/.my.cnf"

connect_timeout

整数

连接到 MySQL 服务器时的连接超时。

默认值: 30

detach_members

布尔值

从角色中分离由 _members_ 选项定义的成员,而不是覆盖所有当前成员。

与 _append_members_ 和 _admin_ 选项互斥。

选项

  • false ← (默认)

  • true

login_host

字符串

运行数据库的主机。

在某些情况下,对于本地连接,需要使用 _login_unix_socket=/path/to/mysqld/socket_,通常为 /var/run/mysqld/mysqld.sock,而不是 _login_host=localhost_。

默认值: "localhost"

login_password

字符串

用于身份验证的密码。

login_port

整数

MySQL 服务器的端口。如果使用 login_port,则需要将 _login_host_ 定义为 localhost 以外的值。

默认值: 3306

login_unix_socket

字符串

本地连接的 Unix 域套接字的路径。

使用此参数避免 Please explicitly state intended protocol 错误。

login_user

字符串

用于身份验证的用户名。

members

列表 / 元素=字符串

角色成员列表。

对于用户,使用格式 username@hostname。始终明确指定主机名部分。

对于角色,使用格式 rolename

与 _admin_ 互斥。

members_must_exist

布尔值

yes 时,如果 _members_ 中的任何用户不存在,则模块将失败。

no 时,将跳过 _members_ 中不存在的用户。

选项

  • false

  • true ← (默认)

name

字符串 / 必需

要添加或删除的角色名称。

priv

any

MySQL 权限字符串,格式为:db.table:priv1,priv2

您可以使用正斜杠分隔多个权限:db.table:priv/db.table:priv

此格式基于 MySQL GRANT 语句。

数据库和表名可以使用 MySQL 风格的引号。

如果使用列权限,则 priv1,priv2 部分必须与 SHOW GRANT 语句返回的结果完全一致。如果不遵循此规则,模块将始终报告更改。这包括按权限对列进行分组(SELECT(col1,col2)而不是 SELECT(col1,SELECT(col2)))。

可以作为字典传递(参见示例)。

支持针对存储过程和函数的 GRANT(有关 community.mysql.mysql_user 模块的示例,请参见示例)。

set_default_role_all

布尔值

MariaDB 不支持此选项,在使用 MariaDB 时将被静默忽略。

如果为 yes,则在更改时对每个 *成员* 运行 **SET DEFAULT ROLE ALL TO**。

如果要避免此行为,请显式地将此选项设置为 no

选项

  • false

  • true ← (默认)

state

字符串

如果为 present 且角色不存在,则创建该角色。

如果为 present 且角色存在,则不执行任何操作或更新其属性。

如果为 absent,则删除该角色。

选项

  • "absent"

  • "present" ← (默认)

subtract_privs

布尔值

在 community.mysql 3.2.0 中添加

撤销由 *priv* 选项定义的权限,并保留其他现有权限。如果设置了此选项,则会忽略 *priv* 中无效的权限。与 *append_privs* 互斥。

选项

  • false ← (默认)

  • true

属性

属性

支持

描述

check_mode

支持:完全支持

可以在 check_mode 下运行,并在不修改目标的情况下返回更改状态预测。

备注

注意

  • 从 MySQL 8.0.0 和 MariaDB 10.0.5 开始支持角色。

  • 请注意,当状态发生更改时,模块默认情况下会对所有传递的 *成员* 运行 SET DEFAULT ROLE ALL TO。如果要避免此行为,请将 *set_default_role_all* 设置为 no

  • 需要在远程主机上安装 PyMySQL(Python 2.7 和 Python 3.X)包。可以使用 apt-get install python-pymysql(Ubuntu;参见 ansible.builtin.apt)或 yum install python2-PyMySQL(RHEL/CentOS/Fedora;参见 ansible.builtin.yum)安装 Python 包。对于较新的 Fedora 版本,您还可以使用 dnf install python2-PyMySQL;参见 ansible.builtin.dnf

  • 确保 Ansible 检测到的 Python 解释器在目标机器上安装了 PyMySQL 库。例如,如果 Ansible 检测到并使用 Python 3,则需要安装 Python 3 版本的 PyMySQL。如果 Ansible 检测到并使用 Python 2,则需要安装 Python 2 版本的 PyMySQL。

  • 如果遇到问题,指定 ansible_python_interpreter 强制 Ansible 使用所需的 Python 解释器可能会有所帮助。有关更多信息,请参见 https://docs.ansible.org.cn/ansible/latest/reference_appendices/interpreter_discovery.html

  • 传递凭据时,需要同时使用 login_passwordlogin_user。如果两者都不存在,模块将尝试从 ~/.my.cnf 读取凭据,最后回退到使用 MySQL 默认登录名“root”且不使用密码。

  • 如果本地连接存在问题,使用 *login_unix_socket=/path/to/mysqld/socket* 而不是 *login_host=localhost* 可能会有所帮助。例如,10.4 及更高版本的 MariaDB 默认安装使用 unix_socket 身份验证插件,如果不使用 *login_unix_socket=/var/run/mysqld/mysqld.sock*(默认路径),则会导致错误“Host ‘127.0.0.1’ is not allowed to connect to this MariaDB server”。

  • 如果不需要从配置文件(例如,/root/.my.cnf)中读取凭据来连接到数据库服务器,但该文件存在且不包含 [client] 部分(在任何其他有效指令之前),则会读取该文件,这会导致连接失败,为避免这种情况,请将其设置为空字符串(例如 config_file: '')。

  • 要避免 Please explicitly state intended protocol 错误,请使用 *login_unix_socket* 参数,例如 login_unix_socket: /run/mysqld/mysqld.sock

  • 或者,为了避免在每次调用时都使用 *login_unix_socket* 参数,您可以在目标主机上的 MySQL 配置文件(通常为 ~/.my.cnf)中使用 `socket` 选项指定套接字路径,例如 socket=/var/lib/mysql/mysql.sock

另请参见

另请参见

community.mysql.mysql_user

向 MySQL 或 MariaDB 数据库添加或删除用户。

MySQL 角色参考

MySQL 角色文档的完整参考。

示例

# If you encounter the "Please explicitly state intended protocol" error,
# use the login_unix_socket argument, for example, login_unix_socket: /run/mysqld/mysqld.sock

# Example of a .my.cnf file content for setting a root password
# [client]
# user=root
# password=n<_665{vS43y
#
# Example of a privileges dictionary passed through the priv option
# priv:
#   'mydb.*': 'INSERT,UPDATE'
#   'anotherdb.*': 'SELECT'
#   'yetanotherdb.*': 'ALL'
#
# You can also use the string format like in the community.mysql.mysql_user module, for example
# mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL
#
# For more examples on how to specify privileges, refer to the community.mysql.mysql_user module

# Create a role developers with all database privileges
# and add alice and bob as members.
# The statement 'SET DEFAULT ROLE ALL' to them will be run.
- name: Create role developers, add members
  community.mysql.mysql_role:
    name: developers
    state: present
    priv: '*.*:ALL'
    members:
    - 'alice@%'
    - 'bob@%'

- name: Same as above but do not run SET DEFAULT ROLE ALL TO each member
  community.mysql.mysql_role:
    name: developers
    state: present
    priv: '*.*:ALL'
    members:
    - 'alice@%'
    - 'bob@%'
    set_default_role_all: false

# Assuming that the role developers exists,
# add john to the current members
- name: Add members to an existing role
  community.mysql.mysql_role:
    name: developers
    state: present
    append_members: true
    members:
    - 'joe@localhost'

# Create role readers with the SELECT privilege
# on all tables in the fiction database
- name: Create role developers, add members
  community.mysql.mysql_role:
    name: readers
    state: present
    priv: 'fiction.*:SELECT'

# Assuming that the role readers exists,
# add the UPDATE privilege to the role on all tables in the fiction database
- name: Create role developers, add members
  community.mysql.mysql_role:
    name: readers
    state: present
    priv: 'fiction.*:UPDATE'
    append_privs: true

- name: Create role with the 'SELECT' and 'UPDATE' privileges in db1 and db2
  community.mysql.mysql_role:
    state: present
    name: foo
    priv:
      'db1.*': 'SELECT,UPDATE'
      'db2.*': 'SELECT,UPDATE'

- name: Remove joe from readers
  community.mysql.mysql_role:
    state: present
    name: readers
    members:
    - 'joe@localhost'
    detach_members: true

- name: Remove the role readers if exists
  community.mysql.mysql_role:
    state: absent
    name: readers

- name: Example of using login_unix_socket to connect to the server
  community.mysql.mysql_role:
    name: readers
    state: present
    login_unix_socket: /var/run/mysqld/mysqld.sock

# Pay attention that the admin cannot be changed later
# and will be ignored if a role currently exists.
# To change members, you need to run a separate task using the admin
# of the role as the login_user.
- name: On MariaDB, create the role readers with alice as its admin
  community.mysql.mysql_role:
    state: present
    name: readers
    admin: 'alice@%'

- name: Create the role business, add the role marketing to members
  community.mysql.mysql_role:
    state: present
    name: business
    members:
    - marketing

- name: Ensure the role foo does not have the DELETE privilege
  community.mysql.mysql_role:
    state: present
    name: foo
    subtract_privs: true
    priv:
      'db1.*': DELETE

- name: Add some members to a role and skip not-existent users
  community.mysql.mysql_role:
    state: present
    name: foo
    append_members: true
    members_must_exist: false
    members:
    - 'existing_user@localhost'
    - 'not_existing_user@localhost'

- name: Detach some members from a role and ignore not-existent users
  community.mysql.mysql_role:
    state: present
    name: foo
    detach_members: true
    members_must_exist: false
    members:
    - 'existing_user@localhost'
    - 'not_existing_user@localhost'

作者

  • Andrew Klychkov (@Andersson007)

  • Felix Hamme (@betanummeric)

  • kmarse (@kmarse)

  • Laurent Indermühle (@laurent-indermuehle)