WoJ*_*WoJ 75 package-management ansible
我从ansible开始,并将使用它在几个 Linux 发行版上安装软件包。
我在文档中看到yum和apt命令是分开的 - 统一它们并使用这样的东西的最简单方法是什么:
- name: install the latest version of Apache
unified_install: name=httpd state=latest
Run Code Online (Sandbox Code Playgroud)
代替
- name: install the latest version of Apache on CentOS
yum: name=httpd state=latest
when: ansible_os_family == "RedHat"
- name: install the latest version of Apache on Debian
apt: pkg=httpd state=latest
when: ansible_os_family == "Debian"
Run Code Online (Sandbox Code Playgroud)
我理解这两个包管理器是不同的,但它们仍然有一组共同的基本用法。其他编排器(例如 salt)只有一个安装命令。
Tri*_*onX 77
package模块现在,当不同操作系统系列的包名称相同时,它很简单:
---
- name: Install foo
package: name=foo state=latest
Run Code Online (Sandbox Code Playgroud)
当不同操作系统系列的软件包名称不同时,您可以使用发行版或操作系统系列特定的 vars 文件来处理它:
---
# roles/apache/apache.yml: Tasks entry point for 'apache' role. Called by main.yml
# Load a variable file based on the OS type, or a default if not found.
- include_vars: "{{ item }}"
with_first_found:
- "../vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int}}.yml"
- "../vars/{{ ansible_distribution }}.yml"
- "../vars/{{ ansible_os_family }}.yml"
- "../vars/default.yml"
when: apache_package_name is not defined or apache_service_name is not defined
- name: Install Apache
package: >
name={{ apache_package_name }}
state=latest
- name: Enable apache service
service: >
name={{ apache_service_name }}
state=started
enabled=yes
tags: packages
Run Code Online (Sandbox Code Playgroud)
然后,对于您必须以不同方式处理的每个操作系统...创建一个 vars 文件:
---
# roles/apache/vars/default.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/RedHat.yml
apache_package_name: httpd
apache_service_name: httpd
---
# roles/apache/vars/SLES.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Debian.yml
apache_package_name: apache2
apache_service_name: apache2
---
# roles/apache/vars/Archlinux.yml
apache_package_name: apache
apache_service_name: httpd
Run Code Online (Sandbox Code Playgroud)
编辑: 由于 Michael DeHaan(Ansible 的创建者)选择不像Chef那样抽象出包管理器模块,
如果您仍在使用旧版本的 Ansible (Ansible < 2.0),不幸的是,您需要在所有剧本和角色中执行此操作。 恕我直言,这将许多不必要的重复工作推到剧本和角色作者身上......但它目前是这样。请注意,我并不是说我们应该在仍然尝试支持所有特定选项和命令的同时尝试将包管理器抽象化,而是有一种简单的方法来安装与包管理器无关的包。我也不是说我们都应该跳上智能包管理器潮流,但是配置管理工具中的某种包安装抽象层对于简化跨平台剧本/食谱非常有用。Smart 项目看起来很有趣,但是在没有太多采用的情况下统一跨发行版和平台的包管理是非常雄心勃勃的……看看它是否成功会很有趣。真正的问题只是包名有时会因发行版而不同,所以我们仍然需要做 case 语句或when:语句来处理差异。
我一直在处理它的方式是tasks在剧本或角色中遵循这个目录结构:
roles/foo
??? tasks
??? apt_package.yml
??? foo.yml
??? homebrew_package.yml
??? main.yml
??? yum_package.yml
Run Code Online (Sandbox Code Playgroud)
然后在我的main.yml:
---
# foo: entry point for tasks
# Generally only include other file(s) and add tags here.
- include: foo.yml tags=foo
Run Code Online (Sandbox Code Playgroud)
这在foo.yml(对于包“foo”):
---
# foo: Tasks entry point. Called by main.yml
- include: apt_package.yml
when: ansible_pkg_mgr == 'apt'
- include: yum_package.yml
when: ansible_pkg_mgr == 'yum'
- include: homebrew_package.yml
when: ansible_os_family == 'Darwin'
- name: Enable foo service
service: >
name=foo
state=started
enabled=yes
tags: packages
when: ansible_os_family != 'Darwin'
Run Code Online (Sandbox Code Playgroud)
然后对于不同的包管理器:
易于:
---
# tasks file for installing foo on apt based distros
- name: Install foo package via apt
apt: >
name=foo{% if foo_version is defined %}={{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
Run Code Online (Sandbox Code Playgroud)
嗯:
---
# tasks file for installing foo on yum based distros
- name: Install EPEL 6.8 repos (...because it's RedHat and foo is in EPEL for example purposes...)
yum: >
name={{ docker_yum_repo_url }}
state=present
tags: packages
when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6
- name: Install foo package via yum
yum: >
name=foo{% if foo_version is defined %}-{{ foo_version }}{% endif %}
state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
tags: packages
- name: Install RedHat/yum-based distro specific stuff...
yum: >
name=some-other-custom-dependency-on-redhat
state=latest
when: ansible_os_family == "RedHat"
tags: packages
Run Code Online (Sandbox Code Playgroud)
家酿:
---
- name: Tap homebrew foobar/foo
homebrew_tap: >
name=foobar/foo
state=present
- homebrew: >
name=foo
state=latest
Run Code Online (Sandbox Code Playgroud)
请注意,这是非常重复的而不是DRY,尽管在不同的平台上有些事情可能会有所不同并且必须处理,但通常我认为与 Chef 相比,这是冗长而笨拙的:
package 'foo' do
version node['foo']['version']
end
case node["platform"]
when "debian", "ubuntu"
# do debian/ubuntu things
when "redhat", "centos", "fedora"
# do redhat/centos/fedora things
end
Run Code Online (Sandbox Code Playgroud)
是的,有人认为某些软件包名称在发行版中是不同的。尽管目前缺乏易于访问的数据,但我敢于猜测大多数流行的包名称在发行版中都很常见,并且可以通过抽象的包管理器模块进行安装。无论如何都需要处理特殊情况,并且已经需要额外的工作来减少干燥 如果有疑问,请查看pkgs.org。
xdd*_*dsg 14
您可以通过事实抽象出包管理器
- name: Install packages
with_items: package_list
action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"
Run Code Online (Sandbox Code Playgroud)
您所需要的只是一些设置ansible_pkg_mgr为apt或yum等的逻辑。
Ansible也在努力在未来的模块中做你想做的事。
从 Ansible 2.0 开始,有新的Package-modul。
http://docs.ansible.com/ansible/package_module.html
然后你可以像你的提议一样使用它:
- name: install the latest version of Apache
package: name=httpd state=latest
Run Code Online (Sandbox Code Playgroud)
您仍然必须考虑名称差异。
| 归档时间: |
|
| 查看次数: |
49787 次 |
| 最近记录: |