如何用Ansible为MySQL/MariaDB root设置随机密码并保存至~/.my.cnf且仅配置一次?
我来帮你解决这个问题!要实现一次性给MySQL/MariaDB的root用户设置32位随机密码,同时保证多次运行playbook不会重复修改,还要把密码写入~/.my.cnf让命令行工具能直接读取,我们可以这样来做:
完整Playbook实现
- name: 配置MySQL/MariaDB root密码与.my.cnf hosts: your_target_hosts become: yes vars: # 存储root密码的安全文件(仅root可读写) mysql_root_password_file: "/root/.mysql_root_password" # .my.cnf文件路径 my_cnf_path: "/root/.my.cnf" # 需要设置密码的root主机列表 mysql_root_hosts: - localhost - "::1" - 127.0.0.1 tasks: # 先安装MySQL Python依赖(按需选择对应系统的任务) - name: 安装Debian系MySQL Python依赖 apt: name: python3-pymysql state: present when: ansible_os_family == 'Debian' - name: 安装RedHat系MySQL Python依赖 yum: name: python3-PyMySQL state: present when: ansible_os_family == 'RedHat' # 检查密码是否已配置(通过标记文件判断) - name: 检查root密码存储文件是否存在 stat: path: "{{ mysql_root_password_file }}" register: mysql_root_password_exists # 生成32位字母数字随机密码(仅首次执行) - name: 生成root随机密码 set_fact: mysql_root_password: "{{ lookup('password', '/dev/null chars=ascii_letters,digits length=32') }}" when: not mysql_root_password_exists.stat.exists # 将密码安全存储到目标主机(防止playbook中断丢失) - name: 保存root密码到本地文件 copy: content: "{{ mysql_root_password }}" dest: "{{ mysql_root_password_file }}" mode: '0600' owner: root group: root when: not mysql_root_password_exists.stat.exists # 设置root用户密码(仅首次执行) - name: 配置MySQL root用户密码 mysql_user: name: root password: "{{ mysql_root_password if not mysql_root_password_exists.stat.exists else lookup('file', mysql_root_password_file) }}" host: "{{ item }}" check_implicit_admin: yes priv: "*.*:ALL,GRANT" state: present loop: "{{ mysql_root_hosts }}" when: not mysql_root_password_exists.stat.exists # 创建/更新.my.cnf文件(仅首次执行) - name: 生成.my.cnf实现免密登录 template: dest: "{{ my_cnf_path }}" mode: '0600' owner: root group: root content: | [client] user=root password={{ mysql_root_password if not mysql_root_password_exists.stat.exists else lookup('file', mysql_root_password_file) }} host=localhost when: not mysql_root_password_exists.stat.exists
关键逻辑说明
- 幂等性保证:通过检查
/root/.mysql_root_password文件是否存在,判断密码是否已配置。只有文件不存在时,才执行密码生成、设置和.my.cnf配置步骤,彻底避免多次运行playbook重复修改密码。 - 密码持久化:生成的密码会存储在目标主机的安全文件中(权限0600,仅root可访问),即使playbook中途中断,下次运行也能读取已有密码,不会导致密码丢失。
- 密码规则满足:用
lookup('password', '/dev/null chars=ascii_letters,digits length=32')生成严格的32位字母数字随机密码,符合你的要求。 - 免密访问配置:生成的
.my.cnf文件包含root密码,后续直接运行mysql等命令无需手动输入密码,同时0600权限确保密码安全。
额外注意事项
- 如果目标主机已存在root密码,但没有
/root/.mysql_root_password文件,请手动创建该文件并写入现有密码,否则playbook会重新设置密码导致原有密码失效。 - 确保Ansible控制节点与目标主机的网络连通,且目标主机已安装MySQL/MariaDB服务。
内容的提问来源于stack exchange,提问作者Gert van den Berg




