Ansible:如何处理同一主机上的服务器?

时间:2016-02-09 13:40:40

标签: ansible development-environment production-environment

我一直在努力设置Ansible,以便为我的项目启动开发环境,然后再部署到测试版和实时服务器。该项目并不是那么大,但似乎Ansible在小项目方面不够灵活。

广告

[development]
web_server ansible_connection=docker
db_server  ansible_connection=docker

[production]
web_server ansible_host=10.10.10.10  ansible_user=tom  ansible_connection=ssh
db_server  ansible_host=10.10.10.10  ansible_user=tom  ansible_connection=ssh

我想保持web_serverdb_server别名不变,这样我就可以在脚本中切换开发和制作,而不用喧嚣。主要问题是我无法弄清楚如何创建一个可以很好地适应上述设置的剧本。

这个解决方案不起作用,因为它运行所有任务两次!

---
- hosts: staging
  tasks:
    - name: Setup web server
      command: uptime
      delegate_to: web_server
    - name: Setup db server
      command: ls
      delegate_to: db_server

此解决方案解决了上述问题,但即使运行db任务,它也会打印错误的别名(web_server)!

---
- hosts: staging
  run_once: true
  tasks:
    - name: Setup web servers
      command: uptime
      delegate_to: web_server
    - name: Setup db servers
      command: ls
      delegate_to: db_server

此解决方案似乎是合理的,但Ansible不支持从组中访问单个主机:

---
- hosts: staging:web_server
  tasks:
    - name: Deploy to web server
      command: uptime

---
- hosts: staging:db_server
  tasks:
    - name: Deploy to db server
      command: ls

有没有办法实现我想要的? Ansible感觉相当严格,直到这一点在听到我所听到的所有赞美之后才是一个无赖。

--------------------------在udondan的建议之后编辑------------- ---------

我尝试过udondan的建议,似乎有效。但是,当我向库存添加新组时,它会中断。

[development]
web_server ansible_connection=docker
db_server  ansible_connection=docker

[staging]
web_server ansible_host=20.20.20.20  ansible_user=tom  ansible_connection=ssh
db_server  ansible_host=20.20.20.20  ansible_user=tom  ansible_connection=ssh

[production]
web_server ansible_host=10.10.10.10  ansible_user=tom  ansible_connection=ssh
db_server  ansible_host=10.10.10.10  ansible_user=tom  ansible_connection=ssh

在这种情况下,运行生产剧本时将使用登台服务器的IP(20.20.20.20)。

1 个答案:

答案 0 :(得分:2)

  

这个解决方案不起作用,因为它运行所有任务两次!

假设hosts: staging是您在development中定义的内容,这是预期的行为。您定义了一组主机,并通过针对该组运行任务或角色,将处理该组的所有主机。通过将任务委派给其他主机,您只强制在其他地方执行任务,但仍然会为该组的每个主机执行该任务。

我认为你想要的是:

---

- hosts: web_server
  tasks:
    - name: Setup web server
      command: uptime

- hosts: db_server
  tasks:
    - name: Setup db server
      command: ls

回复后更新:

问题是您对所有环境使用相同的主机名,并尝试将它们委派给不同的连接器。但Ansible正在做的是:

它从上到下读取您的库存,查找组并按字母顺序处理组。 (开发,生产,登台)它在组web_server中找到主机development,因此它创建该组,添加该主机并为该主机设置var ansible_connection。它继续进行组production,再次找到主机web_server,然后将其添加到组production,并设置变量ansible_hostansible_user和{ {1}}。但这不是针对这个群体的。它是为主机名ansible_connection设置的,覆盖了先前的web_server值。 Ansible继续到ansible_connection组并再次覆盖所有设置。主机staging属于所有3个组,并且其vars已合并,即使您仅定位了一个组,例如web_server。该限制仅限制匹配主机的播放,但主机仍属于所有组,并具有已定义的所有(合并)变量。

强烈建议每个环境都有一个清单文件。不是专门针对您所面临的问题,而只是添加另一层安全性,以便在您真正想要定位分段框时不会意外地对生产主机执行任何操作。但它也会解决你的问题。因此,而不是像您一样的库存文件:

ansible-playbook ... --limit=development

inventory/development

[development] web_server db_server [development:vars] ansible_connection=docker

inventory/staging

[staging] web_server db_server [staging:vars] ansible_host=20.20.20.20 ansible_user=tom ansible_connection=ssh

inventory/production

然后,您使用相应的广告资源文件调用Ansible:

[production]
web_server
db_server

[production:vars]
ansible_host=10.10.10.10
ansible_user=tom
ansible_connection=ssh

如果您不能这样做并且需要单个清单文件,则需要确保主机名是唯一的,以便不会覆盖连接详细信息。