进行ansible检查远程主机上是否存在数据库

时间:2014-12-22 16:00:45

标签: mysql ansible ansible-playbook

为了确保主机A可以连接到主机B的数据库,我尝试在远程主机上使用mysql_db

- name: Make sure A can connect to B database
  mysql_db:
    login_user=root
    login_password=password
    login_host=B_address
    login_port=B_port
    name=B_database
    state=present

即使登录/传递正确

,我也会收到该错误消息
msg: unable to connect, check login_user and login_password are correct, 
or alternatively check ~/.my.cnf contains credentials

我错过了什么吗?我可以使用特定的ansible主机设置login_host吗?

7 个答案:

答案 0 :(得分:5)

    Did you configure the mysql to accept the connection from Host A because 
by default mysql only accept connection from localhost.

如果您已配置mysql接受来自主机A的连接,那么您可以验证数据库是否存在

- name: check if DB exists
   shell: mysql -e 'SHOW DATABASES;' | grep {{ B_database }}
   register: dbstatus
   failed_when: dbstatus.rc == 2

然后,如果B_database存在,则可以运行任务

- name: Make sure A can connect to B database
  mysql_db:
    login_user=root
    login_password=password
    login_host=B_address
    login_port=B_port
    name=B_database
    state=present
  when: dbstatus.rc == 0 
  no_log: yes # You can disable this, if you want to print the stdout

如果您确定上述情况属实并且仍然出现错误,请执行以下操作:

在task / main.yml

中添加此任务
- name: Copy the root credentials as .my.cnf file
   template:
     src: root.cnf.j2
     dest: "~/.my.cnf"
     mode: 0600

这将是你的root.cnf.j2

[client]
user=root
password={{ password }}

它将做的是,从没有密码的root用户连接mysql并执行这些任务。你可以在运行完所有任务后将其删除,或者保留它,因为它在root下并具有严格的权限。

答案 1 :(得分:1)

因为当找不到grep退出代码时ansible失败了,我找到了一种不同的方法来过滤数据库:

> mysql -e "SHOW DATABASES LIKE '<database>'" -sN

然后您可以执行以下操作:

  when: dbstatus.stdout_lines

因为python会将空数组视为false

答案 2 :(得分:1)

使用上述答案的组合

- name: check if DB exists
  shell: mysql --host={{ db_host }} --user={{ db_username }} --password={{ db_password }} -e 'SHOW DATABASES;' | grep -c {{ db_name }}
  register: dbstatus
  failed_when: dbstatus.rc == 2

- name: Create database
  mysql_db: name={{db_name}} collation=utf8mb4_unicode_ci state=present login_host={{ db_host }} login_user={{ db_root_username }} login_password={{ db_root_password }}
  when: dbstatus.stdout == "0"

- name: Create application user in the database
  mysql_user: name={{ db_username }} password={{ db_password }} host={{ db_connection_host }} append_privs=true priv={{ db_name }}.*:ALL state=present login_host={{ db_host }} login_user={{ db_root_username }} login_password={{ db_root_password }}
  when: dbstatus.stdout == "0"

有用的注意事项,你可以通过在运行playbook时添加-vvv来获取dbstatus的输出

答案 3 :(得分:0)

请记住,这里涉及3个主机:

  • “ansible execution host”,您正在运行ansible的主机;
  • “安全目标主机”,主机是您的任务目标;
  • mysql主机,即数据库服务器。

在这种情况下,目标主机需要能够使用login_password作为login_user连接到mysql主机。

检查:

  • 提供者用户和密码被授予从目标主机
  • 到mysql主机的连接
  • 目标和mysql主机之间的防火墙允许mysql连接(通常是端口3306)。如果这些事情有效,那么ansible模块也应该如此。

答案 4 :(得分:0)

在我的情况下,创建数据库后,我只想导入一次SQL文件。这是Ansible方法的实现方法:

jq 'def addNewKey: map_values(if type == "object" and has("key") then . + { "new key" : null } elif type=="array" or type=="object" then addNewKey else . end); addNewKey'

答案 5 :(得分:0)

使用config_file:进行连接,并检查模式以确定数据库是否存在:

- name: Make sure A can connect to B database
  mysql_db:
    config_file: /etc/mysql/debian.cnf
    name=B_database
    state=present
  check_mode: yes
  register: database_exists

- debug: var=database_exists.changed

答案 6 :(得分:0)

我正在使用 postgresql 和更高版本的 ansible,因此使用上述答案我汇总了这个解决方案。

 - name: find out if db exists
   postgresql_query:
     query: |
       SELECT datname FROM pg_database where datname = '{{ dbname }}'
   register: result
   become: yes
   become_user: postgres

 - name: look at results {{ result.rowcount }}..... 
   debug:
     var: result

{{ dbname }} 是一个可以用文字替换的变量。第二个任务显示您可以查看 result.rowcount,如果它是 0,那么数据库不存在。如果为 1,则数据库存在。现在你可以使用 result.rowcount 和 when: 来确定一个任务是否被执行。例如,在我的情况下,我试图确定是否应该创建数据库,例如:

 - name: message if db exists....
   debug:
     msg: "yes it exist"
   when: "{{ result.rowcount }} == 1"