首页 文章

如何处理Ansible角色中的服务器依赖性?

提问于
浏览
1

我是Ansible的新手 . 我的Ansible playbooks有以下目录结构:

$HOME/playbooks
├── project1
├── project2
└── roles

我在角色目录中收集常用角色,例如我的“nginx”角色,然后通过在每个项目的ansible.cfg文件中添加以下行,在项目目录中引用这些角色:

# $HOME/playbooks/project1/ansible.cfg
[defaults]
roles_path = $HOME/playbooks/roles

当常见角色任务取决于运行任务的服务器时,如何配置单独的Ansible playbook任务和常见角色任务?在我的例子中,我有一个用于配置我的Web服务器的“webservers.yml”手册和一个用于配置我的文件服务器的“fileservers.yml”手册 . 我的网站将在我的网络服务器上运行,但我的静态和媒体文件将从一个单独的文件服务器提供 . 我目前在我的nginx角色的main / task.yml文件中包含以下任务:

# $HOME/playbooks/roles/nginx/tasks/main.yml
- name: create nginx config file
  template: src=nginx.conf.j2
            dest=/etc/nginx/sites-available/{{ domain }}.conf
  notify: restart nginx
  become: True
  tags: nginx

问题是每台服务器上的nginx配置文件会有所不同,因为(我认为)在我的Web服务器上运行的nginx进程需要将静态文件请求重定向到在我的文件服务器上运行的nginx进程 . 我应该在我的常见nginx角色中保留“创建nginx配置文件”任务,并让它将最小模板复制到每个服务器上,然后在我的网络服务器和文件服务器手册中再次调用该任务,并让每个人都部署服务器特定版本的配置文件(例如nginx.webserver.conf.j2与nginx.fileserver.conf.j2)?我应该将创建配置文件从我的主要角色任务中删除,并在每个剧本中执行它吗? (这种方法对我来说似乎不对)或者是否有更强大的方法来做到这一点?

谢谢!

2 回答

  • 0

    @ Petro026已经提到的库存或组变量是一种选择 . 在您的nginx角色或配置模板中,您只需检查这些变量 .

    但我认为在这种情况下有更好的选择,因为角色是在Web服务器或文件服务器手册的上下文中显式调用的 . 您可以简单地引入一个影响角色工作方式的角色参数 .

    - role: nginx
      mode: direct
    

    或者对于网络服务器 mode: redirect .

    然后,您可以在任务级别上进行过滤

    - some: task
      when: mode == "redirect"
    

    或者根据条件处理模板中的所有内容 .

    {% if mode == "redirect" %}
    # I am a webserver
    {% else %}
    # I am a fileserver
    {% endif %}
    

    现在,结果与使用组或主机变量完全相同,但我认为看到该剧本的人发生的事情更加明显,nginx角色支持不同的模式以及该信息的位置被定义(作为角色参数) .

    我应该将创建配置文件从我的主要角色任务中删除,并在每个剧本中执行它吗? (这种方法对我来说似乎不对)或者是否有更强大的方法来做到这一点?

    这是另一种选择 . 实际上,把任务放在剧本中似乎是错误的 . 但是嵌套角色怎么样?这再次为您提供了一个干净的解决方

    保持你的nginx角色,只需删除文件服务器和web服务器之间不同的部分 .

    然后,您创建两个新角色 . 一个名为 nginx_web ,一个名为 nginx_file . 现在,在两个角色中,您都在 <role>/meta/main.yml 中设置了对常见 nginx 角色的依赖关系:

    dependencies:
      - role: nginx
        tags: nginx
    

    现在,您只需将不同的部分添加到_265932_和 nginx_filetasks/main.yml 中,看起来它只是单个模板任务 . 您甚至可以保留处理程序以在您的常见 nginx 角色中重新启动nginx,并从其他角色调用它 .

    你现在需要在你的剧本中引用的是 nginx_webnginx_file . nginx 角色自动在nginx_web / file中的任务之前作为依赖项执行 .


    更新:描述角色参数

    角色可以以不同的方式应用 . 作为字符串或字典 . 示例为字符串

    roles:
      - roleName
    

    如果您希望添加其他信息,例如标签,条件或其他参数,则可以提供字典 . 在这种情况下,角色名称将进入dict键 role

    roles:
      - role: roleName
        tags: someTag
        when: someVar is defined
        become: True
        foo: bar
    

    所有其他数据都会传递给角色内的每个任务 . Ansible将表现为 tagsbecomewhen 应用于角色内的每个任务 . Ansible不知道的其他所有内容都将被视为一个变量 .

    或者,您可以将dict编写为JSON,因为YAML支持有限的JSON格式 .

    roles:
      - {role: "roleName", tags: "someTag", when: "someVar is defined", become: True, foo: "bar"}
    

    但我觉得这很难看,更喜欢纯YAML的定义

    后者是documentation中显示的格式:

    此外,如果您希望通过添加变量来参数化角色,您可以这样做,如下所示:---

    • 主机:网络服务器
      角色:
    • 常见
    • {role:foo_app_instance,dir:'/ opt / a',app_port:5000}
    • {role:foo_app_instance,dir:'/ opt / b',app_port:5001}
  • 0

    如果每台机器上的nginx配置不同,那么您应该有库存变量来驱动每台服务器上配置文件的生成 . 适当地模板化你的nginx.conf文件以处理你的web服务器和文件服务器配置 . 如果配置完全不同,您应该考虑为每个配置设置单独的角色(nginx_web和nginx_file)或至少单独的jinja模板 .

相关问题