I want to setup a MySQL server on AWS, using Ansible for the configuration management. I am using the default AMI from Amazon (ami-3275ee5b), which uses yum
for package management.
When the Playbook below is executed, all goes well. But when I run it for a second time, the task Configure the root credentials
fails, because the old password of MySQL doesn't match anymore, since it has been updated the last time I ran this Playbook.
This makes the Playbook non-idempotent, which I don't like. I want to be able to run the Playbook as many times as I want.
- 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
What would be the best way to solve this, which means make the Playbook idempotent? Thanks in advance!
I posted about this on coderwall, but I'll reproduce dennisjac's improvement in the comments of my original post.
The trick to doing it idempotently is knowing that the mysql_user module will load a ~/.my.cnf file if it finds one.
I first change the password, then copy a .my.cnf file with the password credentials. When you try to run it a second time, the myqsl_user ansible module will find the .my.cnf and use the new password.
- 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
The .my.cnf template looks like this:
[client] user=root password={{ mysql_root_password }}
Edit: Added privileges as recommended by Dhananjay Nene in the comments, and changed variable interpolation to use braces instead of dollar sign.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With