Ansible idempotent MySQL installation Playbook

后端 未结 11 1381
后悔当初
后悔当初 2021-01-30 04:29

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

相关标签:
11条回答
  • 2021-01-30 04:47

    For 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
    
    0 讨论(0)
  • 2021-01-30 04:49

    We have spent a lot of time on this issue. For MySQL 5.7 and above we concluded it is easier to simply ignore the root account, and set permissions on a regular MySQL user.

    Reasons

    1. Setting the root password is difficult
    2. unix_socket auth plugin conflicts with the standard auth plugin
    3. Reliably changing the root password after disabling unix_socket plugin is almost impossible
    4. Ansible is not well suited to atomically changing the root password in one step
    5. Using a normal account broadly works well

    If you abandon idempotency, then you can get it to work fine. However, since the ansible value proposition is that idempotency is possible, we find that developers waste time with the wrong assumption.

    The mere existence of a hack option like check_implicit_admin starts to hint to us that deterministic MySQL setup is not that easy. If it's actually deterministic, there should be no "check", there should only be "do".

    0 讨论(0)
  • 2021-01-30 04:56

    This is an alternative solution to the one proposed by @LorinHochStein

    One of my constraints was to ensure that no passwords are stored in plain text files anywhere on the server. Thus .my.cnf was not a practical proposition

    Solution :

    - 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
    

    And in the vars file

    current_password: foobar
    new_password: "{{ current_password }}"
    

    When not changing the mysql password run ansible playbook on command line as usual.

    When changing the mysql password, add the following to the command line. Specifying it on the commandline allows the parameter set on the command line to take precedence over the one defaulted to in the vars file.

    $ ansible-playbook ........ --extra-vars "new_password=buzzz"
    

    After running the command change the vars file as follows

    current_password=buzzz
    new_password={{ current_password }}
    
    0 讨论(0)
  • 2021-01-30 04:56

    Adding to the previous answers, I didn't want a manual step before running the command, ie I want to spin up a new server and just run the playbook without having to manually change the root password first time. I don't believe {{ mysql_password }} will work the first time, when root password is null, because mysql_password still has to be defined somewhere (unless you want to override it with -e).

    So I added a rule to do that, which is ignored if it fails. This is in addition to, and appears before, any of the other commands here.

    - 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
    
    0 讨论(0)
  • 2021-01-30 04:57

    The following will Work (Insert my.cnf in between 2 mysql_user calls)


    - 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"
    
    0 讨论(0)
提交回复
热议问题