はじめに
Packer + Ansibleでインフラ構築中に遭遇したPythonバージョンの不一致によるエラーと、その解決方法をまとめます。
エラー内容
amazon-ebs.phase1: fatal: [default]: FAILED! => {
"changed": false,
"module_stderr": "Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for |: '_Environ' and 'dict'
原因
このエラーはリモートサーバとローカルのPythonバージョンの不一致が原因です。
-
エラーの本質:
|演算子による辞書のマージはPython 3.9+で導入された機能 - リモートサーバ: Python 3.8.10を使用
- Ansibleモジュール: Python 3.9+の構文を使用
重要なポイント
Ansibleはリモートサーバ側でモジュールを実行するため、リモート側のPythonバージョンが重要です。
ローカル(Ansibleコントローラー)
↓ SSH接続
リモートサーバ(ターゲットホスト) ← ここでモジュールが実行される
└── Python 3.8.10 ← これが問題
解決方法
方法1: リモートサーバのPythonをアップグレード(推奨)
Packerのプロビジョニングで対応
# packer.pkr.hcl
build {
sources = ["source.amazon-ebs.phase1"]
# 最初にPythonをアップグレード
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y python3.10 python3.10-venv python3.10-dev",
"sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1"
]
}
# その後Ansibleを実行
provisioner "ansible" {
playbook_file = "playbook.yml"
extra_arguments = [
"-e", "ansible_python_interpreter=/usr/bin/python3.10"
]
}
}
Ansibleプレイブックで対応
---
- hosts: all
gather_facts: no
become: yes
tasks:
- name: Install Python 3.10
raw: |
apt-get update
apt-get install -y python3.10 python3.10-venv python3.10-dev
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
args:
executable: /bin/bash
- name: Set Python interpreter for subsequent tasks
set_fact:
ansible_python_interpreter: /usr/bin/python3.10
- hosts: all
tasks:
- name: Install packages
apt:
name: your-package
state: present
方法2: ローカル(Mac)のPythonバージョンを合わせる
リモート側の変更が難しい場合、ローカル側をPython 3.8.10に合わせることも可能です。
macOS 15 (Sequoia)でのPython 3.8.10インストール
通常のpyenv install 3.8.10では失敗するため、以下のオプションが必要です:
# 環境変数を設定してビルド
CFLAGS="-I$(brew --prefix openssl@1.1)/include" \
LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" \
PYTHON_CONFIGURE_OPTS="--enable-framework" \
pyenv install 3.8.10
プロジェクトでの使用
# プロジェクトディレクトリに移動
cd /path/to/your/ansible-project
# Python 3.8.10を設定
pyenv local 3.8.10
# 確認
python3 --version
# Python 3.8.10
# 仮想環境を作成
python3 -m venv venv
# 仮想環境を有効化
source venv/bin/activate
# Ansibleをインストール
pip install --upgrade pip
pip install ansible
# 確認
ansible --version
方法3: Dockerを使用(最も推奨)
環境の一貫性を保つには、Dockerの使用が最適です。
Dockerfileの作成
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y \
python3.8 \
python3-pip \
openssh-client \
git \
&& rm -rf /var/lib/apt/lists/*
RUN pip3 install --no-cache-dir \
ansible==7.0.0 \
boto3 \
botocore
WORKDIR /workspace
ENTRYPOINT ["ansible-playbook"]
使用方法
# イメージをビルド
docker build -t my-ansible .
# Ansibleを実行
docker run --rm \
-v $(pwd):/workspace \
-v ~/.ssh:/root/.ssh:ro \
-v ~/.aws:/root/.aws:ro \
my-ansible playbook.yml
Docker Composeを使用
# docker-compose.yml
version: '3.8'
services:
ansible:
image: cytopia/ansible:latest-tools
volumes:
- .:/ansible
- ~/.ssh:/root/.ssh:ro
- ~/.aws:/root/.aws:ro
working_dir: /ansible
# 実行
docker-compose run --rm ansible ansible-playbook playbook.yml
各方法の比較
| 方法 | メリット | デメリット |
|---|---|---|
| リモートをアップグレード | ・最新の環境を使用 ・セキュリティ的に安全 ・長期的に推奨 |
・リモート環境の変更が必要 |
| ローカルをダウングレード | ・リモート環境を変更不要 | ・古いPythonを使用 ・macOS最新版でビルドが困難 ・セキュリティリスク |
| Docker使用 | ・環境の一貫性 ・チーム全体で統一可能 ・CI/CDとの統合が容易 |
・Dockerの知識が必要 ・初期セットアップが必要 |
おすすめの対応順序
- 第一選択: リモートサーバのPythonをアップグレード
- 第二選択: Dockerで環境を統一
- 最終手段: ローカルをダウングレード(非推奨)
まとめ
- Ansibleのエラーは、リモートサーバのPythonバージョンが原因
- Python 3.8は2024年10月にサポート終了済み
- 可能な限りPython 3.9以上へのアップグレードを推奨
- チーム開発ではDockerによる環境統一が最適