Как установить и сохранить случайный пароль для пользователя root MySQL / MariaDB с помощью Ansible?

0

Как использовать Ansible для установки случайного (32-символьного алфавитно-цифрового) пароля root для базы данных MariaDB/MySQL и сохранения его в файле ~/.my.cnf (чтобы команды могли находить этот пароль)?

Он должен настраивать его только один раз и не менять пароль каждый раз, если проигрыватель запускается несколько раз.

Это использует пароль из переменной.

Если я использую это, он меняет пароль каждый раз, когда запускается проигрыватель: (и он не может сохранить пароль - если проигрыватель прерван после этой задачи, пароль будет потерян)

- 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
  • 0
    (Такое ощущение, что это относится к ошибкам сервера, но мета не согласна )
Теги:
mariadb
ansible

1 ответ

0
Лучший ответ

Некоторые предположения:

  • Корневой пользователь достаточно покрыт 'root'@'localhost' а другие локальные пользователи root должны быть удалены
  • Задачи должны быть отказоустойчивыми. Если прервано, должно быть возможно запустить снова, насколько это возможно
  • Задачи Ansible выполняются как root - ~/.my.cnf расширяются до /root/.my.cnf
  • Все остальное, которое требует пароль, может получить его от ~/.my.cnf (все обычные инструменты, если они работают как правильный пользователь, root в этом случае)

Обзор:

  • Это генерирует пароль root с помощью этого
  • Он сохраняет его в ~/.my.cnf.new (чтобы убедиться, что он доступен на сервере до его установки, что позволяет (вручную) восстановить, если оно прерывается)
  • Он устанавливает пароль в базе данных
  • Он переименовывает файл (репликация функции mv в двух задачах - жесткая link и удаление) (link и unlink)
  • Он очищает любые другие эквивалентные пользователи, такие как 'root'@'127.0.0.1', 'root'@'::1', 'root'@'<hostname>' (используя несколько фактов, чтобы убедиться, что большинство возможностей )

Шаблон для пароля config: ('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 }}"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню