Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible idempotent MySQL installation Playbook

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!

like image 320
ndequeker Avatar asked May 08 '13 15:05

ndequeker


1 Answers

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.

like image 169
Lorin Hochstein Avatar answered Oct 01 '22 11:10

Lorin Hochstein