我想设置在AWS上一个MySQL服务器,使用Ansible的配置管理。 我使用亚马逊(AMI-3275ee5b),它使用默认的AMI yum
管理软件包。
当执行下面的剧本,一切顺利。 但是,当我运行它第二次,任务Configure the root credentials
失败,因为MySQL的旧密码不匹配了,因为它已被更新的最后一次,我跑了这个剧本。
这使得剧本非幂等的,我不喜欢。 我希望能够运行剧本多次,我想。
- 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
什么是解决这个的最佳方式,这意味着使剧本幂? 提前致谢!
Answer 1:
我贴这个的coderwall ,但我会重现dennisjac的改善,我原来的职位的意见。
诀窍idempotently做,就知道,如果它发现一个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
该.my.cnf模板看起来是这样的:
[client]
user=root
password={{ mysql_root_password }}
编辑:作为意见建议Dhananjay内内,并改变变量代换使用括号,而不是美元符号添加权限 。
Answer 2:
Ansible版本安全MySQL安装。
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
模板/根/ my.cnf.j2
[client]
user=root
password={{ mysql_root_password }}
参考
- 原来答案由洛林·霍克斯坦
- https://github.com/gaspaio/ansible-devbox/blob/master/roles/mysql/tasks/server.yml
Answer 3:
这是一种替代解决方案由@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
而在瓦尔文件
current_password: foobar
new_password: "{{ current_password }}"
如果不改变mysql的密码运行命令行照常ansible剧本。
当改变mysql的密码,添加以下命令行。 指定它的命令行允许参数在命令行设置为优先于一个默认为在瓦尔文件。
$ ansible-playbook ........ --extra-vars "new_password=buzzz"
运行该命令后更改瓦尔文件,如下所示
current_password=buzzz
new_password={{ current_password }}
Answer 4:
添加到以前的答案,我不想在运行命令之前手动工序,即我想旋转了一个新的服务器,只是运行的剧本,而不必手动修改root密码第一次。 我不相信{{mysql_password}}将努力在第一时间,当root密码为空,因为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
Answer 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
Answer 6:
好了,这次来到有点复杂。 我花在这个一整天,并与下面列出的解决方案上来。 关键的一点是如何Ansible安装MySQL服务器。 从该文档mysql_user模块(在页面上最后一个音符):
MySQL server installs with default login_user of ‘root’ and no password. To secure this user as part of an idempotent playbook, you must create at least two tasks: the first must change the root user’s password, without providing any login_user/login_password details. The second must drop a ~/.my.cnf file containing the new root credentials. Subsequent runs of the playbook will then succeed by reading the new credentials from the file.
与空白或空口令问题是一个很大的惊喜。
作用 :
---
- name: Install MySQL packages
sudo: yes
yum: name={{ item }} state=present
with_items:
- mysql
- mysql-server
- MySQL-python
- name: Start MySQL service
sudo: yes
service: name=mysqld state=started enabled=true
- name: Update MySQL root password for root account
sudo: yes
mysql_user: name=root password={{ db_root_password }} priv=*.*:ALL,GRANT
- name: Create .my.cnf file with root password credentials
sudo: yes
template: src=.my.cnf.j2 dest=/root/.my.cnf owner=root group=root mode=0600
notify:
- restart mysql
- name: Create a database
sudo: yes
mysql_db: name={{ db_name }}
collation=utf8_general_ci
encoding=utf8
state=present
- name: Create a database user
sudo: yes
mysql_user: name={{ db_user }}
password={{ db_user_password }}
priv="{{ db_name }}.*:ALL"
host=localhost
state=present
处理器 :
---
- name: restart mysql
service: name=mysqld state=restarted
.my.cnf.j2:
[client]
user=root
password={{ db_root_password }}
Answer 7:
下面的工作(在mysql_user电话2之间插入的my.cnf)
- name: 'Install MySQL'
yum: name={{ item }} state=present
with_items:
- MySQL-python
- mysql
- mysql-server
notify:
- restart-mysql
- name: 'Start Mysql Service'
action: service name=mysqld state=started enabled=yes
- name: 'Update Mysql Root Password'
mysql_user: name=root host=localhost password={{ mysql_root_password }} state=present
- name: 'Copy Conf file with root password credentials'
template: src=../templates/my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600
- name: 'Update Rest-Mysql Root Password'
mysql_user: name=root host={{ item }} password={{ mysql_root_password }} state=present
with_items:
- "{{ ansible_hostname }}"
- "{{ ansible_eth0.ipv4.address }}"
- 127.0.0.1
- ::1
- name: 'Delete anonymous MySQL server user from server'
mysql_user: name="" host={{ ansible_hostname }} state="absent"
Answer 8:
我知道这是一个老问题,但我分享的那些,谁是寻找它我的工作剧本:
mysql.yml
---
- name: Install the MySQL packages
apt: name={{ item }} state=installed update_cache=yes
with_items:
- mysql-server-5.6
- mysql-client-5.6
- python-mysqldb
- libmysqlclient-dev
- name: Copy the configuration file (my.cnf)
template: src=my.cnf.j2 dest=/etc/mysql/my.cnf
notify:
- Restart MySQL
- name: Update MySQL root password for all root accounts
mysql_user: name=root host={{ item }} password={{ mysql_root_pass }} state=present
with_items:
- "{{ ansible_hostname }}"
- 127.0.0.1
- ::1
- localhost
- name: Copy the root credentials as .my.cnf file
template: src=root.cnf.j2 dest=~/.my.cnf mode=0600
- name: Ensure Anonymous user(s) are not in the database
mysql_user: name='' host={{ item }} state=absent
with_items:
- localhost
- "{{ ansible_hostname }}"
- name: Remove the test database
mysql_db: name=test state=absent
notify:
- Restart MySQL
vars.yml
---
mysql_port: 3306 #Default is 3306, please change it if you are using non-standard
mysql_bind_address: "127.0.0.1" #Change it to "0.0.0.0",if you want to listen everywhere
mysql_root_pass: mypassword #MySQL Root Password
my.cnf.j2
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = {{ mysql_port }}
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address = {{ mysql_bind_address }}
key_buffer = 16M
max_allowed_packet = 64M
thread_stack = 192K
thread_cache_size = 8
myisam-recover = BACKUP
query_cache_limit = 1M
query_cache_size = 16M
log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 100M
[mysqldump]
quick
quote-names
max_allowed_packet = 64M
[mysql]
[isamchk]
key_buffer = 16M
!includedir /etc/mysql/conf.d/
root.cnf.j2
[client]
user=root
password={{ mysql_root_pass }}
Answer 9:
它启动/重新启动之前,设置root密码的MySQL服务器是很重要的。 另外,我已经想尽一切贴上去的这个帖子[日期],发现当务之急是要通过login_password
和login_user
。
(即)设置之后的任何播放mysql_user
user:root
和password= {{ SOMEPASSWORD }}
必须连接使用login_password
和login_user
对于任何后续的播放。
注: with_items
下面是基于Ansible及/ MariaDB的默认主机上创建的 。
例如用于确保MariaDB的服务器:
---
# 'secure_mariadb.yml'
- name: 'Ensure MariaDB server is started and enabled on boot'
service: name={{ mariadb_service_name }} state=started enabled=yes
# localhost needs to be the last item for idempotency, see
# http://ansible.cc/docs/modules.html#mysql-user
- name: 'Update Mysql Root Password'
mysql_user: name=root
host={{ item }}
password={{ root_db_password }}
priv=*.*:ALL,GRANT
state=present
with_items:
- 127.0.0.1
- ::1
- instance-1 # Created by MariaDB to prevent conflicts between port and sockets if multi-instances running on the same computer.
- localhost
- name: 'Create MariaDB main configuration file'
template: >
src=my.cnf.j2
dest=/etc/mysql/my.cnf
owner=root
group=root
mode=0600
- name: 'Ensure anonymous users are not in the database'
mysql_user: login_user=root
login_password={{ root_db_password }}
name=''
host={{ item }}
state=absent
with_items:
- 127.0.0.1
- localhost
- name: 'Remove the test database'
mysql_db: login_user=root
login_password={{ root_db_password }}
name=test
state=absent
- name: 'Reload privilege tables'
command: 'mysql -ne "{{ item }}"'
with_items:
- FLUSH PRIVILEGES
changed_when: False
- name: 'Ensure MariaDB server is started and enabled on boot'
service: name={{ mariadb_service_name }} state=started enabled=yes
# 'End Of File'
Answer 10:
我将我自己取的各种方法(CentOS的7)。
可变mysql_root_password应被存储在ansible-保管库(更好)或命令行传递(差)
- name: "Ensure mariadb packages are installed"
yum: name={{ item }} state="present"
with_items:
- mariadb
- mariadb-server
- name: "Ensure mariadb is running and configured to start at boot"
service: name=mariadb state=started enabled=yes
# idempotently ensure secure mariadb installation --
# - attempts to connect as root user with no password and then set the root@ mysql password for each mysql root user mode.
# - ignore_errors is true because this task will always fail on subsequent runs (as the root user password has been changed from "")
- name: Change root user password on first run, this will only succeed (and only needs to succeed) on first playbook 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
- name: Ensure the anonymous mysql user ""@{{ansible_hostname}} is deleted
action: mysql_user user="" host="{{ ansible_hostname }}" state="absent" login_user=root login_password={{ mysql_root_password }}
- name: Ensure the anonymous mysql user ""@localhost is deleted
action: mysql_user user="" state="absent" login_user=root login_password={{ sts_ad_password }}
- name: Ensure the mysql test database is deleted
action: mysql_db db=test state=absent login_user=root login_password={{ mysql_root_password }}
Answer 11:
我们花了很多时间在这个问题上。 对于MySQL 5.7和上面我们得出的结论很容易简单地忽略root帐户,并定期MySQL用户设置权限。
原因
- 设置root密码难
-
unix_socket
身份验证与标准的身份验证插件的插件冲突 - 停用后,确实改变了root密码
unix_socket
插件几乎是不可能的 - Ansible不能很好地适合于在一个步骤中以原子方式改变根密码
- 使用普通帐户广泛的工作良好
如果你放弃幂等,那么你就可以得到它的工作的罚款。 然而,由于ansible价值主张是幂等是可能的,我们发现开发人员浪费时间与错误的假设。
就像一个黑客选项仅仅存在check_implicit_admin
开始提示我们,确定MySQL的设置并不那么容易。 如果它实际上是确定性的,不应该有“检查”,应该只有“做”。
文章来源: Ansible idempotent MySQL installation Playbook