はじめに
インフラエンジニアの長田です。これまでマイクロアドのインフラ環境ではCentOS7を使っていましたが、現在はUbuntu20.04への乗り換えを順次進めています。
それに伴い、CentOS用に作ってきたAnsibleロールのUbuntu対応やGitHubリポジトリの構成見直し、新しいバージョンのAnsibleへの追随など様々なリファクタリングを進めています。
また、複数のansible-core、Moleculeバージョンで同時にテストするために、Pythonのテスト用仮想環境を管理するtoxというツールを活用しています。
Ubuntuへの対応
これまでマイクロアドのインフラ環境ではCentOS7を使っていましたが、現在はUbuntuへの乗り換えを順次進めています。 それにあたり、これまでCentOS用に作り込んでいたAnsibleロールをUbuntuでも動作するように作り替える必要があり、以下のような修正をしています。
vars
ディレクトリ配下に、OS毎に異なるファイルパスなどを定義する変数ファイルを作成するtasks
ディレクトリ配下に、OS別のタスクファイルを作成するtasks/main.yml
に、上記のファイルをincludeするタスクを記述する
以下は、PostgreSQLをインストールするロールからOS毎に異なる内容の抜粋です。OSのディストリビューション名を取得する変数 ansible_distribution
によって、includeする変数ファイルとタスクファイルを分岐させています。
- defaults/main.yml (OS共通のデフォルト変数)
--- postgresql_version: 14
- vars/CentOS.yml
--- postgresql_datadir: "/var/lib/pgsql/data"
- vars/Ubuntu.yml
--- postgresql_datadir: "/var/lib/postgresql/{{ postgresql_version }}/main"
- tasks/package-CentOS.yml
--- - name: PostgreSQLをインストール ansible.builtin.package: name: - "postgresql{{ postgresql_version }}" - "postgresql{{ postgresql_version }}-devel" - "postgresql{{ postgresql_version }}-server" - "postgresql{{ postgresql_version }}-libs" - "postgresql{{ postgresql_version }}-contrib"
- tasks/package-Ubuntu.yml
--- - name: PostgreSQLをインストール ansible.builtin.apt: name: - "postgresql-{{ postgresql_version }}" - "postgresql-client-{{ postgresql_version }}" - "postgresql-client-common" - "postgresql-common" state: present update_cache: true
- tasks/main.yml
--- - name: OS毎の変数を取得 ansible.builtin.include_vars: "{{ ansible_distribution }}.yml" - name: OS毎のインストールタスクを実行 ansible.builtin.include_tasks: "package-{{ ansible_distribution }}.yml"
ロールのリポジトリ分離
これまで、マイクロアドのインフラチームで管理しているAnsibleのリソースはgroup_varsやロール、プレイブックを含め、全て単一のリポジトリで管理していました。
しかし、CIによるテストの動作制御や、後述する複数バージョンのansible-core、Moleculeでのテストが行いずらいといった問題が生じてきました。そこで、ロールについては1ロール1リポジトリの形式に分離することとしました。
これにより、ロール毎に異なるバージョンでのCI実行が容易になり、移植性が向上しました。
- 既存のリソース構成(抜粋)
. ├── group_vars │ └── some_host ├── roles │ └── some_role └── playbook.yml
- リポジトリ分離後のリソース構成
# ansibleリポジトリ . ├── group_vars │ └── some_host ├── roles │ └── requirements.yml └── playbook.yml
- 分離したロールのリポジトリ(抜粋)
. ├── README.md ├── defaults │ └── main.yml ├── meta │ └── main.yml ├── molecule ├── tasks │ ├── main.yml │ ├── package-CentOS.yml │ └── package-Ubuntu.yml ├── tox.ini └── vars ├── CentOS.yml └── Ubuntu.yml
roles/requirements.ymlには、リポジトリ分離したロールをインストールするための情報を記載しています。ロール名の先頭には ma_ansible
というnamespaceを付与し、次に説明する meta/main.yml
の記述と一致させてロールをインストールできるようにします。
--- roles: - name: "ma_ansible.some_role" src: "git+<ロールリポジトリのURL>"
また、リポジトリ分離したロール側には meta/main.yml
を作成し、元のリポジトリからCollectionとしてインストールできるようにしています。この中の namespace
に、上述した ma_ansible
を指定します。
--- galaxy_info: role_name: "some_role" namespace: ma_ansible company: MicroAd, Inc. author: "Yasuhiro Nagata" description: "〇〇〇をインストールするロール" license: "MicroAd, Inc." platforms: - name: EL versions: - '7' - name: Ubuntu versions: - focal min_ansible_version: 2.9.27
ansible-coreおよびMoleculeのアップグレード、複数バージョンでの同時テスト
現在、マイクロアドでは主にansible-core 2.9を使っていますが、すでにEOLを迎えているため、アップグレードを進めています。
理想的には最新バージョンを使用したいですが、Python3.9以上のバージョンが必要です。テスト環境で複数バージョンのPythonを使用する方法が定まっていないため、ひとまず現環境で使用しているPython3.8で動作するansible-core 2.12へアップグレードしています。
マイクロアドでは全てのAnsibleロールにMoleculeでのテストを実装しており、こちらについても新しいバージョンへの追従を進めています。
Moleculeの最新バージョンは直近2つのメジャーバージョンしかサポートしないため、一旦はansible-core 2.12に合わせたもので動作する内容に作り替えています。
この際、上述したtoxを使って molecule test
を実行しています。toxの仮想環境設定は以下のようなiniファイルで行っています。
- tox.ini
[tox] envlist = py38-ansible{209,212} skipsdist = true [testenv] parallel_show_output = true deps = #ansible-core 2.9 ansible209: ansible==2.9.27 ansible209: rich<11.0.0 ansible209: ansible-lint==4.3.7 ansible209: jmespath==0.9.5 ansible209: molecule==3.2.4 # ansible-core 2.12 ansible212: ansible==5.10 ansible212: ansible-lint==6.12.2 ansible212: jmespath ansible212: molecule==3.6 -r {toxinidir}/requirements_tox.txt setenv = PATH = {toxworkdir}/bin{:}{env:PATH} ANSIBLE_FORCE_COLOR = True ROLE_CURDIR={env:ROLE_CURDIR} TEST_ENVNAME={envname} MOLECULE_EPHEMERAL_DIRECTORY={toxworkdir}/tmp/{envname} PY_COLORS={env:color} commands = molecule test
CIでのテストは、Makefileのタスクを呼び出してtoxを実行しています。また、ローカルでテストする場合、テストが失敗した場合にMolecule実行環境のコンテナ内がどうなっているかを確認したいケースがあるため、venvで仮想環境を構築する方法も併用しています。Makefileのタスクでvenv環境の構築と、 molecule test --destroy=never
相当のコマンドを実行できるようにしています。
- Makefile
# CIで実行するタスク .PHONY: test test: @tox --parallel --quiet --parallel-live true auto # ローカル実行用venv環境の構築 .PHONY: venv-init venv-init: ifeq ($(shell uname),Linux) # Ubuntu ifeq ($(shell source /etc/os-release && echo "$$ID"),ubuntu) @python3 -m venv .venv && \ source .venv/bin/activate && \ .venv/bin/pip install --upgrade pip && \ .venv/bin/pip install -r requirements_venv.txt ; endif # macOSの場合 else ifeq ($(shell uname),Darwin) @python3 -m venv .venv && \ source .venv/bin/activate && \ .venv/bin/pip install --upgrade pip && \ .venv/bin/pip install -r requirements_venv.txt ; endif # テスト実行用コマンド(moleculeコンテナを削除しない) .PHONY: test-destroy-never test-destroy-never: @TEST_ENVNAME=py38-ansible209 molecule test --destroy=never
おわりに
今後、Ubuntu22.04への対応や更に先のansible-coreのバージョンへのアップグレードも進めたいと考えています。
インフラのコードも放置すれば技術的負債となりかねないため、これからも改善を進めていきます。