如何测试ansible角色?
How to test ansible roles?
场景
我想开发ansible角色。这些角色应该通过 CI/CD 分子过程进行验证,并利用 docker 作为驱动程序。此验证步骤应包括多个 Linux 口味(例如 centos/ubuntu/debian)乘以受支持的 ansible 版本。
然后应执行测试,以便通过
验证角色
centos:7 + ansible:2.5
centos:7 + ansible:2.6
centos:7 + ansible:2.7
...
ubuntu:1604 + ansible:2.5
ubuntu:1604 + ansible:2.6
ubuntu:1604 + ansible:2.7
...
手头的问题
- 没有可用的官方 ansible 镜像
- 如何最好地测试角色的 ansible 版本兼容性?
问题 1:没有官方 ansible 图像
ansible 团队的官方镜像已经被弃用大约 3 年了:
- https://hub.docker.com/r/ansible/ubuntu14.04-ansible
- https://hub.docker.com/r/ansible/centos7-ansible
此外,link 为了找到支持 ansible 的新图像而引用的已弃用图像由于结果数量巨大而变得毫无用处
https://hub.docker.com/search/?q=ansible&page=1&isAutomated=0&isOfficial=0&pullCount=1&starCount=0
社区(或 ansible)是否有维护良好的 ansible docker 图像来填补空白?
最好使用可以拉取的多个版本和一个 CI 定期构建和验证创建的图像的过程。
我为什么要寻找 ansible 图像? 我不想重新发明轮子(如果可能的话)。我想使用图像通过分子测试 ansible 角色的版本不兼容。
我搜索过但没有找到任何真正有用的东西。在 container/orchestrator 中 运行 ansible 使用什么图像?您自己构建和维护图像吗?
例如https://hub.docker.com/r/ansibleplaybookbundle/apb-base/tags
看起来很有希望,但是,那里的图像也有超过 7 个月的历史(至少)。
问题 2:如何最好地测试角色的 ansible 版本兼容性?
是否为 OS 和 ansible 版本的每个组合创建 docker 图像是通过分子和 docker 作为驱动程序进行测试的最佳方式?或者有没有更聪明的方法来测试 ansible 角色与多个 OS 倍不同的 ansible 版本的向后兼容性?
我已经用 molecule 和 docker 作为驱动程序测试了我的 ansible 角色。这些测试目前只测试角色在各种 Linux 发行版上的功能,而不是通过 运行 将角色与旧的 ansible 版本结合起来的 ansible 向后兼容性。
这里是基于 geerlingguy 的 ntp 角色的 centos7/ubuntu1604/ubuntu1804 travis 测试的示例角色:https://github.com/Gepardec/ansible-role-ntp
这里没有真正的答案,但有一些想法:
Ansible Silo 可能已经安装,但一年没有提交。
这并不是您要找的东西,但 Ansible Runner 适合 "run ansible" 用例。而且它是 Ansible Tower / AWS 的一部分,所以它应该会持续下去。
Runner is intended to be most useful as part of automation and tooling that needs to invoke Ansible and consume its results.
他们确实提到从容器中执行 here
The design of Ansible Runner makes it especially suitable for controlling the execution of Ansible from within a container for single-purpose automation workflows
但你的问题是官方 ansible/ansible-runner 容器是在 ansible-runner 版本之后标记的,而 ansible 本身是在容器构建时通过 pip install ansible
安装的。
解决方案
为了使用多个版本的 ansible、python 和各种 Linux 风格测试 ansible 角色,我们可以使用
- 分子 用于我们的 ansible 角色功能
- docker 作为我们的抽象层 运行 ansible 角色的目标系统
- tox 设置通用 virtualenvs 并测试我们的各种组合而没有副作用
- travis 全部自动化
这将是一个很好的 long/detailed 答案。您可以在此处查看整个设置的示例 ansible 角色
- https://github.com/ckaserer/ansible-role-example
- https://travis-ci.com/ckaserer/ansible-role-example
第 1 步:使用分子测试 ansible 角色
分子文档:https://molecule.readthedocs.io/en/stable/
修复问题:1) 没有官方 ansible 图像
正如 jeff geerling 在他的博客文章中所描述的那样,我可以为我想测试的每个发行版创建 ansible 图像。
这种方法的明显缺点:图像需要维护(最终)
但是,使用 molecule,我们可以将基础镜像与 Dockerfile.j2(Jinja2 模板)结合起来,以创建对 运行 ansible 具有最低要求的镜像。通过这种方法,我们现在可以使用来自 docker hub 的官方 linux 发行版映像,而无需为每个 linux 发行版和各种版本。
这里是 molecule.yml
中的重要部分
platforms:
- name: instance-${TOX_ENVNAME}
image: ${MOLECULE_DISTRO:-'centos:7'}
command: /sbin/init
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
molecule 的默认 dockerfile.j2 已经很好了,但我还有一些补充
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; \
elif [ $(command -v swupd) ]; then swupd bundle-add python3-basic sudo iproute2; \
elif [ $(command -v dnf) ] && cat /etc/os-release | grep -q '^NAME=Fedora'; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \
elif [ $(command -v dnf) ] && cat /etc/os-release | grep -q '^NAME="CentOS Linux"' ; then dnf makecache && dnf --assumeyes install python36 sudo platform-python-devel python*-dnf bash iproute && dnf clean all && ln -s /usr/bin/python3 /usr/bin/python; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
fi
# Centos:8 + ansible 2.7 failed with error: "The module failed to execute correctly, you probably need to set the interpreter"
# Solution: ln -s /usr/bin/python3 /usr/bin/python
默认情况下,这将使用 centos:7 测试角色。但是,我们可以将环境变量 MOLECULE_DISTRO 设置为我们想要测试的任何图像,并通过
运行 它
MOLECULE_DISTRO=ubuntu:18.04 molecule test
总结
我们使用来自 docker hub 的官方发行版镜像来通过 molecule 测试我们的 ansible 角色。
这一步用到的文件
- molecule.ymlhttps://github.com/ckaserer/ansible-role-example/blob/master/molecule/default/molecule.yml
- Dockerfile.j2 https://github.com/ckaserer/ansible-role-example/blob/master/molecule/default/Dockerfile.j2
来源
- https://molecule.readthedocs.io/en/stable/examples.html#systemd-container
- https://www.jeffgeerling.com/blog/2019/how-i-test-ansible-configuration-on-7-different-oses-docker
- https://www.jeffgeerling.com/blog/2018/testing-your-ansible-roles-molecule
第 2 步:检查您的角色的兼容性(python 版本 X ansible 版本 X linux 发行版)
修复问题 2:如何最好地测试角色的 ansible 版本兼容性?
让我们使用 tox 创建虚拟环境,以避免在测试各种兼容性方案时产生副作用。
这里是 tox.ini
中的重要部分
[tox]
minversion = 3.7
envlist = py{3}-ansible{latest,29,28}-{ alpinelatest,alpine310,alpine39,alpine38, centoslatest,centos8,centos7, debianlatest,debian10,debian9,debian8, fedoralatest,fedora30,fedora29,fedora28, ubuntulatest,ubuntu2004,ubuntu1904,ubuntu1804,ubuntu1604 }
# only test currently supported ansible versions
# https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#release-status
skipsdist = true
[base]
passenv = *
deps =
-rrequirements.txt
ansible25: ansible==2.5
...
ansiblelatest: ansible
commands =
molecule test
setenv =
TOX_ENVNAME={envname}
MOLECULE_EPHEMERAL_DIRECTORY=/tmp/{envname}
[testenv]
passenv =
{[base]passenv}
deps =
{[base]deps}
commands =
{[base]commands}
setenv =
...
centoslatest: MOLECULE_DISTRO="centos:latest"
centos8: MOLECULE_DISTRO="centos:8"
centos7: MOLECULE_DISTRO="centos:7"
...
{[base]setenv}
整个requirements.txt
docker
molecule
只需执行
tox
它将为 tox.ini 中定义的每个兼容性组合创建虚拟环境
envlist = py{3}-ansible{latest,29,28}-{ alpinelatest,alpine310,alpine39,alpine38, centoslatest,centos8,centos7, debianlatest,debian10,debian9,debian8, fedoralatest,fedora30,fedora29,fedora28, ubuntulatest,ubuntu2004,ubuntu1904,ubuntu1804,ubuntu1604 }
在这种特殊情况下转换为:python3 x ansible version x linux distro
太棒了!我们已经创建了兼容性检查测试,其额外好处是始终使用 ansible latest 进行测试,以便及早发现重大更改。
这一步用到的文件
- tox.inihttps://github.com/ckaserer/ansible-role-example/blob/master/tox.ini
- requirements.txthttps://github.com/ckaserer/ansible-role-example/blob/master/requirements.txt
来源
第 3 步:CI 使用 travis
运行 本地检查很好,运行ning 在 CI 工具中很棒。所以让我们这样做吧。
为此,.travis.yml 中的以下位很重要
---
version: ~> 1.0
os: linux
language: python
python:
- "3.8"
- "3.7"
- "3.6"
- "3.5"
services: docker
cache:
pip: true
directories:
- .tox
install:
- pip install tox-travis
env:
jobs:
# ansible:latest - check for breaking changes
...
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="latest"
- TOX_DISTRO="centos8" TOX_ANSIBLE="latest"
- TOX_DISTRO="centos7" TOX_ANSIBLE="latest"
...
# ansible: check version compatibility
# only test currently supported ansible versions
#
https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#release-status
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="{29,28}"
- TOX_DISTRO="centos8" TOX_ANSIBLE="{29,28}"
- TOX_DISTRO="centos7" TOX_ANSIBLE="{29,28}"
...
script:
- tox -e $(echo py${TRAVIS_PYTHON_VERSION} | tr -d .)-ansible${TOX_ANSIBLE}-${TOX_DISTRO}
# remove logs/pycache before caching .tox folder
- |
rm -r .tox/py*/log/*
find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
首先,我们指定了 language: python
到 运行 构建,使用 python:
列表中定义的 python 的多个版本。
我们需要docker,所以我们通过services: docker
添加它。
测试会花费一些时间,让我们缓存pip和tox创建的virtenv with
cache:
pip: true
directories:
- .tox
我们需要毒素...
install:
- pip install tox-travis
最后,我们定义所有测试用例
env:
jobs:
# ansible:latest - check for breaking changes
...
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="latest"
...
请注意,我有针对最新版本和不同版本的不同作业。那是故意的。我想很容易地看到什么坏了。是版本兼容性还是 ansible 最新版本中即将发生的变化。
这一步用到的文件
来源
奖金:运行 并行毒物
您可以 运行 通过执行
并行测试(例如同时进行 3 个测试)
tox -p 3
但是,这不会给出 molecule 的输出。您可以使用
启用它
tox -p 3 -o true
这种方法的明显缺点是在并行执行中很难确定哪一行属于哪个进程。
来源
场景
我想开发ansible角色。这些角色应该通过 CI/CD 分子过程进行验证,并利用 docker 作为驱动程序。此验证步骤应包括多个 Linux 口味(例如 centos/ubuntu/debian)乘以受支持的 ansible 版本。
然后应执行测试,以便通过
验证角色centos:7 + ansible:2.5
centos:7 + ansible:2.6
centos:7 + ansible:2.7
...
ubuntu:1604 + ansible:2.5
ubuntu:1604 + ansible:2.6
ubuntu:1604 + ansible:2.7
...
手头的问题
- 没有可用的官方 ansible 镜像
- 如何最好地测试角色的 ansible 版本兼容性?
问题 1:没有官方 ansible 图像
ansible 团队的官方镜像已经被弃用大约 3 年了:
- https://hub.docker.com/r/ansible/ubuntu14.04-ansible
- https://hub.docker.com/r/ansible/centos7-ansible
此外,link 为了找到支持 ansible 的新图像而引用的已弃用图像由于结果数量巨大而变得毫无用处
https://hub.docker.com/search/?q=ansible&page=1&isAutomated=0&isOfficial=0&pullCount=1&starCount=0
社区(或 ansible)是否有维护良好的 ansible docker 图像来填补空白?
最好使用可以拉取的多个版本和一个 CI 定期构建和验证创建的图像的过程。
我为什么要寻找 ansible 图像? 我不想重新发明轮子(如果可能的话)。我想使用图像通过分子测试 ansible 角色的版本不兼容。
我搜索过但没有找到任何真正有用的东西。在 container/orchestrator 中 运行 ansible 使用什么图像?您自己构建和维护图像吗?
例如https://hub.docker.com/r/ansibleplaybookbundle/apb-base/tags
看起来很有希望,但是,那里的图像也有超过 7 个月的历史(至少)。
问题 2:如何最好地测试角色的 ansible 版本兼容性?
是否为 OS 和 ansible 版本的每个组合创建 docker 图像是通过分子和 docker 作为驱动程序进行测试的最佳方式?或者有没有更聪明的方法来测试 ansible 角色与多个 OS 倍不同的 ansible 版本的向后兼容性?
我已经用 molecule 和 docker 作为驱动程序测试了我的 ansible 角色。这些测试目前只测试角色在各种 Linux 发行版上的功能,而不是通过 运行 将角色与旧的 ansible 版本结合起来的 ansible 向后兼容性。
这里是基于 geerlingguy 的 ntp 角色的 centos7/ubuntu1604/ubuntu1804 travis 测试的示例角色:https://github.com/Gepardec/ansible-role-ntp
这里没有真正的答案,但有一些想法:
Ansible Silo 可能已经安装,但一年没有提交。
这并不是您要找的东西,但 Ansible Runner 适合 "run ansible" 用例。而且它是 Ansible Tower / AWS 的一部分,所以它应该会持续下去。
Runner is intended to be most useful as part of automation and tooling that needs to invoke Ansible and consume its results.
他们确实提到从容器中执行 here
The design of Ansible Runner makes it especially suitable for controlling the execution of Ansible from within a container for single-purpose automation workflows
但你的问题是官方 ansible/ansible-runner 容器是在 ansible-runner 版本之后标记的,而 ansible 本身是在容器构建时通过 pip install ansible
安装的。
解决方案
为了使用多个版本的 ansible、python 和各种 Linux 风格测试 ansible 角色,我们可以使用
- 分子 用于我们的 ansible 角色功能
- docker 作为我们的抽象层 运行 ansible 角色的目标系统
- tox 设置通用 virtualenvs 并测试我们的各种组合而没有副作用
- travis 全部自动化
这将是一个很好的 long/detailed 答案。您可以在此处查看整个设置的示例 ansible 角色
- https://github.com/ckaserer/ansible-role-example
- https://travis-ci.com/ckaserer/ansible-role-example
第 1 步:使用分子测试 ansible 角色
分子文档:https://molecule.readthedocs.io/en/stable/
修复问题:1) 没有官方 ansible 图像
正如 jeff geerling 在他的博客文章中所描述的那样,我可以为我想测试的每个发行版创建 ansible 图像。
这种方法的明显缺点:图像需要维护(最终)
但是,使用 molecule,我们可以将基础镜像与 Dockerfile.j2(Jinja2 模板)结合起来,以创建对 运行 ansible 具有最低要求的镜像。通过这种方法,我们现在可以使用来自 docker hub 的官方 linux 发行版映像,而无需为每个 linux 发行版和各种版本。
这里是 molecule.yml
中的重要部分platforms:
- name: instance-${TOX_ENVNAME}
image: ${MOLECULE_DISTRO:-'centos:7'}
command: /sbin/init
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
molecule 的默认 dockerfile.j2 已经很好了,但我还有一些补充
# Molecule managed
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
{% if item.env is defined %}
{% for var, value in item.env.items() %}
{% if value %}
ENV {{ var }} {{ value }}
{% endif %}
{% endfor %}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; \
elif [ $(command -v swupd) ]; then swupd bundle-add python3-basic sudo iproute2; \
elif [ $(command -v dnf) ] && cat /etc/os-release | grep -q '^NAME=Fedora'; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \
elif [ $(command -v dnf) ] && cat /etc/os-release | grep -q '^NAME="CentOS Linux"' ; then dnf makecache && dnf --assumeyes install python36 sudo platform-python-devel python*-dnf bash iproute && dnf clean all && ln -s /usr/bin/python3 /usr/bin/python; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
fi
# Centos:8 + ansible 2.7 failed with error: "The module failed to execute correctly, you probably need to set the interpreter"
# Solution: ln -s /usr/bin/python3 /usr/bin/python
默认情况下,这将使用 centos:7 测试角色。但是,我们可以将环境变量 MOLECULE_DISTRO 设置为我们想要测试的任何图像,并通过
运行 它MOLECULE_DISTRO=ubuntu:18.04 molecule test
总结
我们使用来自 docker hub 的官方发行版镜像来通过 molecule 测试我们的 ansible 角色。
这一步用到的文件
- molecule.ymlhttps://github.com/ckaserer/ansible-role-example/blob/master/molecule/default/molecule.yml
- Dockerfile.j2 https://github.com/ckaserer/ansible-role-example/blob/master/molecule/default/Dockerfile.j2
来源
- https://molecule.readthedocs.io/en/stable/examples.html#systemd-container
- https://www.jeffgeerling.com/blog/2019/how-i-test-ansible-configuration-on-7-different-oses-docker
- https://www.jeffgeerling.com/blog/2018/testing-your-ansible-roles-molecule
第 2 步:检查您的角色的兼容性(python 版本 X ansible 版本 X linux 发行版)
修复问题 2:如何最好地测试角色的 ansible 版本兼容性?
让我们使用 tox 创建虚拟环境,以避免在测试各种兼容性方案时产生副作用。
这里是 tox.ini
中的重要部分[tox]
minversion = 3.7
envlist = py{3}-ansible{latest,29,28}-{ alpinelatest,alpine310,alpine39,alpine38, centoslatest,centos8,centos7, debianlatest,debian10,debian9,debian8, fedoralatest,fedora30,fedora29,fedora28, ubuntulatest,ubuntu2004,ubuntu1904,ubuntu1804,ubuntu1604 }
# only test currently supported ansible versions
# https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#release-status
skipsdist = true
[base]
passenv = *
deps =
-rrequirements.txt
ansible25: ansible==2.5
...
ansiblelatest: ansible
commands =
molecule test
setenv =
TOX_ENVNAME={envname}
MOLECULE_EPHEMERAL_DIRECTORY=/tmp/{envname}
[testenv]
passenv =
{[base]passenv}
deps =
{[base]deps}
commands =
{[base]commands}
setenv =
...
centoslatest: MOLECULE_DISTRO="centos:latest"
centos8: MOLECULE_DISTRO="centos:8"
centos7: MOLECULE_DISTRO="centos:7"
...
{[base]setenv}
整个requirements.txt
docker
molecule
只需执行
tox
它将为 tox.ini 中定义的每个兼容性组合创建虚拟环境
envlist = py{3}-ansible{latest,29,28}-{ alpinelatest,alpine310,alpine39,alpine38, centoslatest,centos8,centos7, debianlatest,debian10,debian9,debian8, fedoralatest,fedora30,fedora29,fedora28, ubuntulatest,ubuntu2004,ubuntu1904,ubuntu1804,ubuntu1604 }
在这种特殊情况下转换为:python3 x ansible version x linux distro
太棒了!我们已经创建了兼容性检查测试,其额外好处是始终使用 ansible latest 进行测试,以便及早发现重大更改。
这一步用到的文件
- tox.inihttps://github.com/ckaserer/ansible-role-example/blob/master/tox.ini
- requirements.txthttps://github.com/ckaserer/ansible-role-example/blob/master/requirements.txt
来源
第 3 步:CI 使用 travis
运行 本地检查很好,运行ning 在 CI 工具中很棒。所以让我们这样做吧。
为此,.travis.yml 中的以下位很重要
---
version: ~> 1.0
os: linux
language: python
python:
- "3.8"
- "3.7"
- "3.6"
- "3.5"
services: docker
cache:
pip: true
directories:
- .tox
install:
- pip install tox-travis
env:
jobs:
# ansible:latest - check for breaking changes
...
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="latest"
- TOX_DISTRO="centos8" TOX_ANSIBLE="latest"
- TOX_DISTRO="centos7" TOX_ANSIBLE="latest"
...
# ansible: check version compatibility
# only test currently supported ansible versions
#
https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#release-status
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="{29,28}"
- TOX_DISTRO="centos8" TOX_ANSIBLE="{29,28}"
- TOX_DISTRO="centos7" TOX_ANSIBLE="{29,28}"
...
script:
- tox -e $(echo py${TRAVIS_PYTHON_VERSION} | tr -d .)-ansible${TOX_ANSIBLE}-${TOX_DISTRO}
# remove logs/pycache before caching .tox folder
- |
rm -r .tox/py*/log/*
find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete
首先,我们指定了 language: python
到 运行 构建,使用 python:
列表中定义的 python 的多个版本。
我们需要docker,所以我们通过services: docker
添加它。
测试会花费一些时间,让我们缓存pip和tox创建的virtenv with
cache:
pip: true
directories:
- .tox
我们需要毒素...
install:
- pip install tox-travis
最后,我们定义所有测试用例
env:
jobs:
# ansible:latest - check for breaking changes
...
- TOX_DISTRO="centoslatest" TOX_ANSIBLE="latest"
...
请注意,我有针对最新版本和不同版本的不同作业。那是故意的。我想很容易地看到什么坏了。是版本兼容性还是 ansible 最新版本中即将发生的变化。
这一步用到的文件
来源
奖金:运行 并行毒物
您可以 运行 通过执行
并行测试(例如同时进行 3 个测试)tox -p 3
但是,这不会给出 molecule 的输出。您可以使用
启用它tox -p 3 -o true
这种方法的明显缺点是在并行执行中很难确定哪一行属于哪个进程。
来源