dockerコンテナをansible実行ホストとして構成する

docker-composeで環境をカプセル化してGitでPlaybookとともに管理したい。

最終的な構成

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '3.5'

services:
tutorial:
image: python:3-slim
tty: true
working_dir: /work
entrypoint: ./entrypoint.sh
command: /bin/bash
volumes:
- .:/work
environment:
ANSIBLE_CONFIG: .
ANSIBLE_USERNAME: ${ANSIBLE_USERNAME}
ANSIBLE_PASSWORD: ${ANSIBLE_PASSWORD}
secrets:
- secret_key
- public_key

secrets:
secret_key:
file: ./.ssh/ubuntu.key
public_key:
file: ./.ssh/ubuntu.key.pub

entrypoint.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

#
# SSHキー
#
mkdir -p ~/.ssh
chown -R root:root ~/.ssh
chmod -R 0700 ~/.ssh
cp -ip /run/secrets/secret_key ~/.ssh/id_rsa
cp -ip /run/secrets/public_key ~/.ssh/id_rsa.pub
chmod -R 0600 ~/.ssh

#
# Ansibleインストール
#
apt-get install sshpass -y
pip install ansible

exec "$@"

ansible.cfg

1
2
[defaults]
host_key_checking = False

発生したエラーと対策

SecretsをつかってSSH用の公開鍵、秘密鍵を共有する

Secretsは**/run/secrets/**から参照できる
entrypoint.shでrootアカウントのキーとしてコピーし、パーミッションを設定する。

エラー「you must install the sshpass program」

ログイン時にパスワードを使用したログインを行う場合は、sshpassをインストールする必要がある。

1
fatal: [target]: FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"}

エラー「Please add this host’s fingerprint to your known_hosts file to manage this host.」

初回ログイン時などfingerprintの対話操作が含まれるのでエラーになってしまう。

1
fatal: [target]: FAILED! => {"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."}

ansible.cfgをカレントディレクトリに作成しhost_key_checking = Falseを設定する。

1
2
[defaults]
host_key_checking = False

ansible.cfgが読み込まれない

docker-composeを実行するのがWindowsの場合、パーミッションが777になり読み込まれない。
export ANSIBLE_CONFIG=.のように環境変数を定義して明示的にansible.cfgの場所を明示することで読み込ませる。

Python3環境でaptでインストールしたAnsibleが動かない

aptで以下のようにインストールでき、ansibleコマンドも実行可能だが、妙なエラーが出る。

1
2
3
4
apt-get update
apt-get install -y software-properties-common
apt-add-repository --yes --update ppa:ansible/ansible
apt-get install -y ansible
1
fatal: [xxxx.xxxxxx.xxxx]: FAILED! => {"changed": false, "module_stderr": "Shared connection to xxxx.xxxxxx.xxxx closed.\r\n", "module_stdout": "\r\n/home/ansible/.ansible/tmp/ansible-tmp-1621777634.977247-71421390121516/AnsiballZ_user.py:17: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses\r\n  import imp\r\nTraceback (most recent call last):\r\n  File \"/tmp/ansible_user_payload_frbeg21u/ansible_user_payload.zip/ansible/module_utils/basic.py\", line 279, in get_distribution\r\nAttributeError: module 'platform' has no attribute '_supported_dists'\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n  File \"/home/ansible/.ansible/tmp/ansible-tmp-1621777634.977247-71421390121516/AnsiballZ_user.py\", line 113, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/ansible/.ansible/tmp/ansible-tmp-1621777634.977247-71421390121516/AnsiballZ_user.py\", line 105, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/ansible/.ansible/tmp/ansible-tmp-1621777634.977247-71421390121516/AnsiballZ_user.py\", line 48, in invoke_module\r\n    imp.load_module('__main__', mod, module, MOD_DESC)\r\n  File \"/usr/lib/python3.8/imp.py\", line 234, in load_module\r\n    return load_source(name, filename, file)\r\n  File \"/usr/lib/python3.8/imp.py\", line 169, in load_source\r\n    module = _exec(spec, sys.modules[name])\r\n  File \"<frozen importlib._bootstrap>\", line 604, in _exec\r\n  File \"<frozen importlib._bootstrap_external>\", line 783, in exec_module\r\n  File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\r\n  File \"/tmp/ansible_user_payload_frbeg21u/__main__.py\", line 2611, in <module>\r\n  File \"/tmp/ansible_user_payload_frbeg21u/__main__.py\", line 2516, in main\r\n  File \"/tmp/ansible_user_payload_frbeg21u/__main__.py\", line 403, in __new__\r\n  File \"/tmp/ansible_user_payload_frbeg21u/ansible_user_payload.zip/ansible/module_utils/basic.py\", line 337, in load_platform_subclass\r\n  File \"/tmp/ansible_user_payload_frbeg21u/ansible_user_payload.zip/ansible/module_utils/basic.py\", line 289, in get_distribution\r\nAttributeError: module 'platform' has no attribute 'dist'\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

pipでインストールすればOK。

1
pip install ansible