Question:
I have a problem installing MySQL with ansible on a vagrant ubuntu,
This is my MySQL part
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
--- - name: Install MySQL apt: name: "{{ item }}" with_items: - python-mysqldb - mysql-server - name: copy .my.cnf file with root password credentials template: src: templates/root/.my.cnf dest: ~/.my.cnf owner: root mode: 0600 - name: Start the MySQL service service: name: mysql state: started enabled: true # '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 |
And I have this error
1 2 3 4 5 6 7 8 9 |
failed: [default] => (item=vagrant-ubuntu-trusty-64) => {"failed": true, "item": "vagrant-ubuntu-trusty-64"} msg: unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials failed: [default] => (item=127.0.0.1) => {"failed": true, "item": "127.0.0.1"} msg: unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials failed: [default] => (item=::1) => {"failed": true, "item": "::1"} msg: unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials failed: [default] => (item=localhost) => {"failed": true, "item": "localhost"} msg: unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials |
my .my.cnf is
1 2 3 4 |
[client] user=root password={{ mysql_root_password }} |
and when copied on the server
1 2 3 4 |
[client] user=root password=root |
I don’t understand why, ~/.my.cnf is created
Project Github
Thanks
Answer:
When mysql-server
is installed headlessly, there’s no password. Therefore to make .my.cnf
work, it should have a blank password line. Here’s what I tested with for a .my.cnf
:
1 2 3 4 |
[client] user=root password= |
It’s also slightly strange to put .my.cnf
in your vagrant
user directory as owned by root and only readable as root.
After ensuring the password was blank in .my.cnf
, I was able to properly set the password for root in those four contexts. Note that it fails to run after that, since .my.cnf
would need to be updated, so it fails the idempotency test.
There’s a note on the ansible mysql_user module page that suggests writing the password and then writing the .my.cnf
file. If you do that, you need a where
clause to the mysql_user
action (probably with a file stat before that).
Even more elegant is to use check_implicit_admin
along with login_user
and login_password
. That’s beautifully idempotent.
As a third way, perhaps check_implicit_admin
makes it even easier.
Here’s my successful playbook showing the above, tested with a few fresh servers. Kinda proud of this. Note .my.cnf
is unnecessary for all of this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
--- - hosts: mysql vars: mysql_root_password: fart tasks: - name: Install MySQL apt: name={{ item }} update_cache=yes cache_valid_time=3600 state=present sudo: yes with_items: - python-mysqldb - mysql-server #- name: copy cnf # copy: src=.my.cnf dest=~/.my.cnf owner=ubuntu mode=0644 # sudo: yes - name: Start the MySQL service sudo: yes service: name: mysql state: started enabled: true - name: update mysql root password for all root accounts sudo: yes mysql_user: name: root host: "{{ item }}" password: "{{ mysql_root_password }}" login_user: root login_password: "{{ mysql_root_password }}" check_implicit_admin: yes priv: "*.*:ALL,GRANT" with_items: - "{{ ansible_hostname }}" - 127.0.0.1 - ::1 - localhost |