mysql - 如何使用 Ansible 为 MySQL/MariaDB root 用户设置并保存随 secret 码?

标签 mysql ansible mariadb

如何使用 Ansible 为 MariaDB/MySQL 数据库设置随机(32 个字母数字)根密码并将其保存到 ~/.my.cnf 文件中(以允许命令查找这个密码)?

它应该只配置一次,如果剧本运行多次,则不应每次都更改密码。

This使用变量中的密码。

如果我使用它,它会在每次运行剧本时更改密码:(并且无法保存密码 - 如果剧本在此任务后中断,密码就会丢失)

- name: "Change database root user password"
  mysql_user:
    name: root
    password: "{{ lookup('password','/dev/null chars=ascii_letters,digits length=32') }}"
    host: "{{ item }}"
    check_implicit_admin: yes
    priv: "*.*:ALL,GRANT"
    state: present
  when: mysql_root_result.stat.exists == False
  with_items:
  - localhost
  - "::1"
  - 127.0.0.1

最佳答案

一些假设:

  • 'root'@'localhost' 足以覆盖 root 用户以及其他本地root用户需要删除
  • 任务需要具有容错能力。如果中断,应该可以在合理的情况下再次运行
  • Ansible 任务以 root 身份运行 - ~/.my.cnf扩展到/root/.my.cnf
  • 其他需要密码的都可以从 ~/.my.cnf 获取(所有普通工具都可以,只要它们以正确的用户身份运行即可,在本例中为 root)

概述:

  • 这会使用 this 生成 root 密码
  • 它将其保存到 ~/.my.cnf.new (确保它在设置之前在服务器上可用。这允许在中断时进行(手动)恢复)
  • 它在数据库中设置密码
  • 它会重命名文件( replicating mv 's functionality in two tasks - 硬链接(hard link)并删除)( linkunlink )
  • 它会清除任何其他等效用户,例如 'root'@'127.0.0.1' , 'root'@'::1' , 'root'@'<hostname>' (使用一些事实来确保满足大多数可能性)

密码配置模板:(相对于角色目录的“templates/my_passwd.cnf.j2”)

[client]
user={{ item.user }}
password={{ item.password }}

任务:

# MariaDB: Set up secure root password
# Set up (and save) secure root password
# Check for /root/.my.cnf
# All the other things are skipped if this file already exists
- name: "Check if we already have a root password config"
  stat:
    path: /root/.my.cnf
  register: mysql_root_result

# Generate password
# This uses https://docs.ansible.com/ansible/latest/plugins/lookup/password.html
# to generate a 32 character random alphanumeric password
- name: "Generate database root password if needed"
  set_fact:
    mysql_root_passwd: "{{ lookup('password','/dev/null chars=ascii_letters,digits length=32') }}"
  when: mysql_root_result.stat.exists == False

# Generate /root/.my.cnf.new
# A temporary file is used to keep it from breaking further commands
# It also ensures that the password is on the server if the critical
# parts are interrupted
- name: "Save new root password in temporary file"
  template:
    src: my_passwd.cnf.j2
    dest: /root/.my.cnf.new
    owner: root
    group: root
    mode: 0400
  when: mysql_root_result.stat.exists == False
  with_items:
  - user: root
    password: "{{ mysql_root_passwd }}"

# START of area that you don't want to interrupt
# If this is interrupted after the first task
# it can be fixed by manually running this on the server
# mv /root/.my.cnf.new /root/.my.cnf
# If the playbook is reran before that. The password would be lost!
# Add DB user
- name: "Add database root user"
  mysql_user:
    name: root
    password: "{{ mysql_root_passwd }}"
    host: "{{ item }}"
    check_implicit_admin: yes
    priv: "*.*:ALL,GRANT"
    state: present
  when: mysql_root_result.stat.exists == False
  with_items:
  - localhost

# Now move the config in place
- name: "Rename config with root password to correct name - Step 1 - link"
  file:
    state: hard
    src: /root/.my.cnf.new
    dest: /root/.my.cnf
    force: yes
  when: mysql_root_result.stat.exists == False
# END of area that you don't want to interrupt

# Interrupting before this task will leave a temporary file around
# Everything will work as it should though
- name: "Rename config with root password to correct name - Step 2 - unlink"
  file:
    state: absent
    path: /root/.my.cnf.new
  when: mysql_root_result.stat.exists == False

# Remove additional root users - these don't have the password set
# You might want to ensure that none of these variables are `localhost`
# All return somewhat different values on my test system
- name: "Clean up additional root users"
  mysql_user:
    name: root
    host: "{{ item }}"
    check_implicit_admin: yes
    state: absent
  with_items:
  - "::1"
  - 127.0.0.1
  - "{{ ansible_fqdn }}"
  - "{{ inventory_hostname }}"
  - "{{ ansible_hostname }}"

关于mysql - 如何使用 Ansible 为 MySQL/MariaDB root 用户设置并保存随 secret 码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50563845/

相关文章:

java - 从 MySQL 迁移到 MariaDB

MySQL存储过程如何生成新的auto_increment?

mysql - 如何将列命名为星期几

php - 通过 PHP 函数截断 MySQL 表不起作用

mysql - 添加列来说明联合结果来自哪个表

docker - 在 Docker 与 VM 上运行 Ansible

python - 正则表达式字符串替换: omit comma if backref is empty

ansible - 如何在 Ansible 中执行用户创建任务

java - 无法连接到 mysql 中的特定模式

当不在另一个表中时,Mysql SUM 0