You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用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
关键逻辑说明
  1. 幂等性保证:通过检查/root/.mysql_root_password文件是否存在,判断密码是否已配置。只有文件不存在时,才执行密码生成、设置和.my.cnf配置步骤,彻底避免多次运行playbook重复修改密码。
  2. 密码持久化:生成的密码会存储在目标主机的安全文件中(权限0600,仅root可访问),即使playbook中途中断,下次运行也能读取已有密码,不会导致密码丢失。
  3. 密码规则满足:用lookup('password', '/dev/null chars=ascii_letters,digits length=32')生成严格的32位字母数字随机密码,符合你的要求。
  4. 免密访问配置:生成的.my.cnf文件包含root密码,后续直接运行mysql等命令无需手动输入密码,同时0600权限确保密码安全。
额外注意事项
  • 如果目标主机已存在root密码,但没有/root/.mysql_root_password文件,请手动创建该文件并写入现有密码,否则playbook会重新设置密码导致原有密码失效。
  • 确保Ansible控制节点与目标主机的网络连通,且目标主机已安装MySQL/MariaDB服务。

内容的提问来源于stack exchange,提问作者Gert van den Berg

火山引擎 最新活动