September 19, 2023

コンテナ(Docker|Podman)を使ってAnsibleを実行する

AnsibleのコントローラーノードはPython 3.11 + Ansible Core 2.15の組み合わせが、サポート期間も長いしサポートしているターゲットノードも多い。

VersionSupportEnd Of LifeController PythonTarget Python / PowerShell
2.15GA: 22 May 2023
Critical: 06 Nov 2023
Security: 20 May 2024
Nov 2024Python 3.9 - 3.11Python 2.7
Python 3.5 - 3.11
PowerShell 3 - 5.1

ansible-core support matrix

Debian 12のようにOS標準でPython 3.11をインストールできるならいいけれど、様々な事情でPython 3.11をインストールできない場合、Docker|Podmanを動かせるなら、コンテナでPython 3.11 + Ansible Core 2.15を動かせばいいじゃない!

手順

Debian 12(非コンテナ)

まずは普通にコンテナを使わずに使ってみる。
python3パッケージは入っていると思うので、python3-venvを追加。

nissy@deb12:~$ sudo apt install python3-venv

Ansibleを複数バージョン入れて切り替えられるようvenvで仮想環境作成
Ansible Coreに変わる前の2.9も試してみる

nissy@de12:~$ python3.11 -m venv ~/venv/ansible2.9
nissy@de12:~$ python3.11 -m venv ~/venv/ansible2.15

仮想環境に最初から入っているパッケージを更新

nissy@deb12:~$ source ~/venv/ansible2.9/bin/activate
(ansible2.9) nissy@deb12:~$ python3.11 -m pip list
Package    Version
---------- -------
pip        23.0.1
setuptools 66.1.1
(ansible2.9) nissy@deb12:~$ python3.11 -m pip install pip setuptools --upgrade
Requirement already satisfied: pip in ./venv/ansible2.9/lib/python3.11/site-packages (23.0.1)
Collecting pip
  Downloading pip-23.2.1-py3-none-any.whl (2.1 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 3.8 MB/s eta 0:00:00
Requirement already satisfied: setuptools in ./venv/ansible2.9/lib/python3.11/site-packages (66.1.1)
Collecting setuptools
  Downloading setuptools-68.2.2-py3-none-any.whl (807 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 807.9/807.9 kB 2.5 MB/s eta 0:00:00
Installing collected packages: setuptools, pip
  Attempting uninstall: setuptools
    Found existing installation: setuptools 66.1.1
    Uninstalling setuptools-66.1.1:
      Successfully uninstalled setuptools-66.1.1
  Attempting uninstall: pip
    Found existing installation: pip 23.0.1
    Uninstalling pip-23.0.1:
      Successfully uninstalled pip-23.0.1
Successfully installed pip-23.2.1 setuptools-68.2.2
(ansible2.9) nissy@deb12:~$ python3.11 -m pip list
Package    Version
---------- -------
pip        23.2.1
setuptools 68.2.2

Ansible 2.9のパッチバージョン最新をインストール

(ansible2.9) nissy@deb12:~$ python3.11 -m pip install 'ansible>=2.9.0,<2.10.0'
略
(ansible2.9) nissy@deb12:~$ python3.11 -m pip list
Package      Version
------------ -------
ansible      2.9.27
cffi         1.15.1
cryptography 41.0.3
Jinja2       3.1.2
MarkupSafe   2.1.3
pip          23.2.1
pycparser    2.21
PyYAML       6.0.1
setuptools   68.2.2

良さそう

(ansible2.9) nissy@deb12:~$ ansible --version
ansible 2.9.27
  config file = None
  configured module search path = ['/home/nissy/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/nissy/venv/ansible2.9/lib/python3.11/site-packages/ansible
  executable location = /home/nissy/venv/ansible2.9/bin/ansible
  python version = 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]

Ansible 2.9の仮想環境を抜けて

(ansible2.9) nissy@deb12:~$ deactivate

2.15用の環境に入る

nissy@deb12:~$ source ~/venv/ansible2.15/bin/activate
(ansible2.15) nissy@deb12:~$

2.15の最新版をインストール

(ansible2.11) nissy@deb12:~$ python3.11 -m pip install pip setuptools --upgrade
略
(ansible2.15) nissy@deb12:~$ python3.11 -m pip install 'ansible-core>=2.15.0,<2.16.0'
略
(ansible2.15) nissy@deb12:~$ python3.11 -m pip list
Package      Version
------------ -------
ansible-core 2.15.4
cffi         1.15.1
cryptography 41.0.3
Jinja2       3.1.2
MarkupSafe   2.1.3
packaging    23.1
pip          23.2.1
pycparser    2.21
PyYAML       6.0.1
resolvelib   1.0.1
setuptools   68.2.2

良さそう

(ansible2.15) nissy@deb12:~$ ansible --version
ansible [core 2.15.4]
  config file = None
  configured module search path = ['/home/nissy/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/nissy/venv/ansible2.15/lib/python3.11/site-packages/ansible
  ansible collection location = /home/nissy/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/nissy/venv/ansible2.15/bin/ansible
  python version = 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] (/home/nissy/venv/ansible2.15/bin/python3.11)
  jinja version = 3.1.2
  libyaml = True

CentOS 7.9 (Docker)

Dockerインストール

ここではCentOS 7.9を使うけど、Dockerをインストールできれば他のLinuxでも同じように使えるはず。
まずはDockerのインストール、手順は別記事参照。

先の記事でDockerでPython 3.11を使えるようにした手順でaliasを設定する。
~/.bashrc# User specific aliases and functions 行の下に書いておくか、全ユーザーで使えるようにしたければ /etc/profile.d/python.sh か何か任意の名前でファイルを作って書いておく。

alias python3.11='docker run --rm -it -v "${PWD}":/usr/src/app -v py311_lib:/usr/local/lib -w /usr/src/app python:3.11-slim python'

Ansibleインストール

まずはPython 3.11のalias確認、バージョンが表示されるはず

[nissy@cent7 ~]$ python3.11 --version
Python 3.11.5

pipでのインストールは非コンテナの時と同じように。
最初は入っていないけど、

[nissy@cent7 ~]$ python3.11 -m pip list
Package    Version
---------- -------
pip        23.2.1
setuptools 65.5.1
wheel      0.41.2

インストールするとこんな感じ

[nissy@cent7 ~]$ python3.11 -m pip install pip setuptools wheel --upgrade
略
[nissy@cent7 ~]$ python3.11 -m pip install 'ansible-core>=2.15.0,<2.16.0'
略
[nissy@cent7 ~]$ python3.11 -m pip list
Package      Version
------------ -------
ansible-core 2.15.4
cffi         1.15.1
cryptography 41.0.3
Jinja2       3.1.2
MarkupSafe   2.1.3
packaging    23.1
pip          23.2.1
pycparser    2.21
PyYAML       6.0.1
resolvelib   1.0.1
setuptools   68.2.2
wheel        0.41.2

インストールされたのはDockerコンテナの中なので、外で打ってもそんなものは無い、と言われる

[nissy@cent7 ~]$ ansible --version
-bash: ansible: コマンドが見つかりません

中で打てば良し

[nissy@cent7 ~]$ python3.11 -m ansible adhoc --version
ansible [core 2.15.4]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/lib/python3.11/site-packages/ansible/__main__.py
  python version = 3.11.5 (main, Sep  7 2023, 12:46:15) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.2
  libyaml = True
[nissy@cent7 ~]$ python3.11 -m ansible playbook --version
ansible-playbook [core 2.15.4]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/lib/python3.11/site-packages/ansible/__main__.py
  python version = 3.11.5 (main, Sep  7 2023, 12:46:15) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.2
  libyaml = True

コンテナ内のAnsibleを実行できるようにalias追加

alias ansible='python3.11 -m ansible adhoc'
alias ansible-playbook='python3.11 -m ansible playbook'
alias ansible-galaxy='python3.11 -m ansible galaxy'

バージョン確認

[nissy@cent7 ~]$ ansible --version
ansible [core 2.15.4]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/lib/python3.11/site-packages/ansible/__main__.py
  python version = 3.11.5 (main, Sep  7 2023, 12:46:15) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.2
  libyaml = True
[nissy@cent7 ~]$ ansible-playbook --version
ansible-playbook [core 2.15.4]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.11/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/lib/python3.11/site-packages/ansible/__main__.py
  python version = 3.11.5 (main, Sep  7 2023, 12:46:15) [GCC 12.2.0] (/usr/local/bin/python)
  jinja version = 3.1.2
  libyaml = True

Playbookの動作確認

OSはCentOS 7だけど、

[nissy@cent7 ~]$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
---
- hosts: localhost
  tasks:
    - name: Show OS Version
      debug:
        msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}"

↑のPlaybookを実行するとDockerの中のOSが表示されるのでDebian 12だと返ってくる↓

[nissy@cent7 ~]$ ansible-playbook ./test.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'

PLAY [localhost] *******************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]

TASK [Show OS Version] *************************************************************************************************
ok: [localhost] => {
    "msg": "Debian 12.1"
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

AlmaLinux 9 (Podman)

Podmanの場合はPython 3.11のaliasの書き方が少し変わるくらいで他はDockerと同じ。

Podmanインストール

[nissy@alma9 ~]$ sudo dnf install podman

alias設定、~/.bashrc に書いておくか、全ユーザーで使えるようにしたければ /etc/profile.d/python.sh か何か任意の名前でファイルを作って書いておく。

alias python3.11='podman run --rm -it  -v "${PWD}":/usr/src/app:Z -v py311_lib:/usr/local/lib -w /usr/src/app docker.io/python:3.11-slim python'

-vオプションに:Zを付けないとSELinuxが原因で Permission denied になるので注意

[nissy@alma9 ansible-test]$ podman run --rm -it  -v "${PWD}":/usr/src/app -v py311_lib:/usr/local/lib -w /usr/src/app docker.io/python:3.11-slim python -m ansible playbook ./test.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'
ERROR! an error occurred while trying to read the file '/usr/src/app/test.yml': [Errno 13] Permission denied: b'/usr/src/app/test.yml'. [Errno 13] Permission denied: b'/usr/src/app/test.yml'

bashで入って確認、SELinuxのラベルが異なっていてrootと言えどもアクセスさせてもらえない

[nissy@alma9 ansible-test]$ podman run --rm -it  -v "${PWD}":/usr/src/app -v py311_lib:/usr/local/lib -w /usr/src/app docker.io/python:3.11-slim /bin/bash
root@b4e9db746838:/usr/src/app# ls
ls: cannot open directory '.': Permission denied
root@b4e9db746838:/usr/src/app# ls -ldZ /usr/src/app
drwxr-xr-x. 2 root root system_u:object_r:container_file_t:s0:c99,c487 38 Sep 19 11:40 /usr/src/app
root@b4e9db746838:/usr/src/app# ls -ldZ /usr/src
drwxr-xr-x. 1 root root system_u:object_r:container_file_t:s0:c186,c822 17 Sep 19 11:50 /usr/src
root@b4e9db746838:/usr/src/app# ls -ldZ /usr
drwxr-xr-x. 1 root root system_u:object_r:container_file_t:s0:c186,c822 17 Sep  4 00:00 /usr
root@b4e9db746838:/usr/src/app# ls -ldZ /root
drwx------. 1 root root system_u:object_r:container_file_t:s0:c186,c822 24 Sep  7 12:39 /root
root@b4e9db746838:/usr/src/app# touch /root/test.txt
root@b4e9db746838:/usr/src/app# touch /usr/src/app/test.txt
touch: cannot touch '/usr/src/app/test.txt': Permission denied

参考:

Ansibleインストール

Python 3.11のalias確認、バージョンが表示されるはず

[nissy@alma9 ~]$ python3.11 --version
Python 3.11.5

pipでのAnsibleインストールはDockerの時と同じように。

コンテナ内のAnsibleを実行できるようにalias追加するのもDockerの時と同じ。

Playbookの動作確認

OSはAlmaLinux 9だけど、

[nissy@alma9 ~]$ cat /etc/redhat-release
AlmaLinux release 9.2 (Turquoise Kodkod)
---
- hosts: localhost
  tasks:
    - name: Show OS Version
      debug:
        msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}"

CentOS 7 + Dockerの時と同じく、↑のPlaybookを実行するとDockerの中のOSが表示されるのでDebian 12だと返ってくる↓

[nissy@alma9 ~]$ cd ~/ansible-test/
[nissy@alma9 ansible-test]$ ansible-playbook ./test.yml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'

PLAY [localhost] *******************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]

TASK [Show OS Version] *************************************************************************************************
ok: [localhost] => {
    "msg": "Debian 12.1"
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

${HOME}/tmp 直下はリラベリングが禁止されているから、何かディレクトリを作ってymlを置く

[nissy@alma9 ~]$ ansible-playbook ./test.yml
Error: SELinux relabeling of /home/nissy is not allowed
[nissy@alma9 ~]$ cd /tmp
[nissy@alma9 tmp]$ ansible-playbook ./test.yml
Error: SELinux relabeling of /tmp is not allowed

© 2020 nissy-lab.com