Ansible幂等MySQL安装Playbook

nde*_*ker 41 mysql command-line amazon-ec2 amazon-web-services ansible

我想在AWS上设置MySQL服务器,使用Ansible进行配置管理.我正在使用Amazon的默认AMI(ami-3275ee5b),它yum用于包管理.

当下面的Playbook被执行时,一切顺利.但是当我第二次运行它时,任务Configure the root credentials失败了,因为MySQL的旧密码不再匹配,因为它上次运行这个Playbook时已经更新了.

这使得Playbook非幂等,我不喜欢.我希望能够根据需要多次运行Playbook.

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name=$item
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    - name: Configure the root credentials
      action: command mysqladmin -u root -p $mysql_root_password
Run Code Online (Sandbox Code Playgroud)

什么是解决这个问题的最佳方法,这意味着使Playbook具有幂等性?提前致谢!

Lor*_*ein 35

我在coderwall上发布了这个,但我会在我原来的帖子的评论中重现dennisjac的改进.

理所当然地做这件事的诀窍就是知道mysql_user模块会在找到一个〜/ .my.cnf文件时加载它.

我首先更改密码,然后使用密码凭据复制.my.cnf文件.当您尝试再次运行它时,myqsl_user ansible模块将找到.my.cnf并使用新密码.

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name={{ item }}
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    # 'localhost' needs to be the last item for idempotency, see
    # http://ansible.cc/docs/modules.html#mysql-user
    - name: update mysql root password for all root accounts
      mysql_user: name=root host={{ item }} password={{ mysql_root_password }} priv=*.*:ALL,GRANT
      with_items:
        - "{{ ansible_hostname }}"
        - 127.0.0.1
        - ::1
        - localhost

    - name: copy .my.cnf file with root password credentials
      template: src=templates/root/.my.cnf dest=/root/.my.cnf owner=root mode=0600
Run Code Online (Sandbox Code Playgroud)

.my.cnf模板如下所示:

[client]
user=root
password={{ mysql_root_password }}
Run Code Online (Sandbox Code Playgroud)

编辑:在评论中添加Dhananjay Nene建议的权限,并更改变量插值以使用大括号而不是美元符号.


nde*_*ker 29

用于安全MySQL安装的Ansible版本.

mysql_secure_installation.yml

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name={{ item }}
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    # 'localhost' needs to be the last item for idempotency, see
    # http://ansible.cc/docs/modules.html#mysql-user
    - name: update mysql root password for all root accounts
      mysql_user: name=root host={{ item }} password={{ mysql_root_password }}
      with_items:
        - "{{ ansible_hostname }}"
        - 127.0.0.1
        - ::1
        - localhost

    - name: copy .my.cnf file with root password credentials
      template: src=templates/root/my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600

    - name: delete anonymous MySQL server user for $server_hostname
      action: mysql_user user="" host="{{ server_hostname }}" state="absent"

    - name: delete anonymous MySQL server user for localhost
      action: mysql_user user="" state="absent"

    - name: remove the MySQL test database
      action: mysql_db db=test state=absent
Run Code Online (Sandbox Code Playgroud)

模板/根/ my.cnf.j2

[client]
user=root
password={{ mysql_root_password }}
Run Code Online (Sandbox Code Playgroud)

参考

  • 注意新用户.如果你得到```失败:[...] msg:无法连接数据库,请检查login_user和login_password是否正确,或者〜/ .my.cnf有凭据.``,检查你运行的数据库是否正常运行存在. (3认同)

Dha*_*ene 5

这是@LorinHochStein提出的解决方案的替代解决方案

我的一个限制是确保服务器上的任何地方都没有密码存储在纯文本文件中.因此.my.cnf不是一个实际的主张

方案:

- name: update mysql root password for all root accounts from local servers
  mysql_user: login_user=root 
              login_password={{ current_password }} 
              name=root 
              host=$item 
              password={{ new_password }} 
              priv=*.*:ALL,GRANT
  with_items:
      - $ansible_hostname
      - 127.0.0.1
      - ::1
      - localhost
Run Code Online (Sandbox Code Playgroud)

并在vars文件中

current_password: foobar
new_password: "{{ current_password }}"
Run Code Online (Sandbox Code Playgroud)

当没有改变mysql密码时,像往常一样在命令行上运行ansible playbook.

更改mysql密码时,请将以下内容添加到命令行.在命令行上指定它允许在命令行上设置的参数优先于vars文件中的默认值.

$ ansible-playbook ........ --extra-vars "new_password=buzzz"
Run Code Online (Sandbox Code Playgroud)

运行该命令后,按如下所示更改vars文件

current_password=buzzz
new_password={{ current_password }}
Run Code Online (Sandbox Code Playgroud)


mah*_*off 5

添加到之前的答案,我不想在运行命令之前进行手动步骤,即我想启动新服务器并运行playbook而无需第一次手动更改root密码.当root密码为null时,我不相信{{mysql_password}}会第一次工作,因为仍然需要在某处定义mysql_password(除非你想用-e覆盖它).

所以我添加了一个规则,如果失败则会被忽略.这是此处的任何其他命令的补充,并且在此之前出现.

- name: Change root user password on first run
  mysql_user: login_user=root
              login_password=''
              name=root
              password={{ mysql_root_password }}
              priv=*.*:ALL,GRANT
              host={{ item }}
      with_items:
        - $ansible_hostname
        - 127.0.0.1
        - ::1
        - localhost
      ignore_errors: true
Run Code Online (Sandbox Code Playgroud)


ann*_*neb 5

对于 ansible 1.3+ :

- name: ensure mysql local root password is zwx123
  mysql_user: check_implicit_admin=True login_user=root login_password="zwx123" name=root password="zwx123" state=present
Run Code Online (Sandbox Code Playgroud)