GitHub Actionsコンテナ利用時にansible-lintの実行結果がローカル環境と異なったので原因調べました

こんにちは、アドプラットフォーム事業で開発運用業務を行っているリードアプリケーションエンジニアのまっちゃん(@honyanyas)です。
最近はオンプレミスからパブリッククラウドへの移行やAnsibleのCI/CDパイプラインの見直し・改善などを行っています。

最近はさまざまな技術カンファレンスに参加しており、10月頭はYAPC::Hakodate 2024、先週の土曜日はBTCONJP 2024、明日はVue Fes Japan 2024にも参加予定です!
また登壇も機会があれば積極的に参加しており、9月末のXP祭り2024にもペアプロ・モブプロ関連のテーマで登壇しました!
今後も技術カンファレンスの参加、登壇を積極的に行いたいと思ってますのでよろしくお願いいたします!

本日の記事はAnsibleにおけるCI/CDパイプラインの見直し・改善を進める中でGitHub Actions周りで遭遇した問題と解決方法について共有します。

さきに結論

GitHub Actionsをコンテナ環境で起動するとHOMEが /root から /github/home へ書き換わる仕様があることを確認できました。
ansible-lint実行時にcollectionsのパスは /root/.ansible/collections を見て欲しいです。
シンボリックリンクを付与することで、GitHub Actions上の実行結果がローカル環境と同じになりました。

    steps:
      ...
      # NOTE: GitHub Actions でコンテナを実行するとHOMEが書き換わる
      # https://github.com/actions/runner/issues/863
      # HOMEが書き換わる影響として Ansible collection パスが無い状況になるので意図しないエラーが発生する
      # そのためシンボリックリンクを貼って collection パスを通すことにした
      - name: Make Symbolic link
        run: ln -sf /root/.ansible /github/home/
      - name: Run ansible-lint
        run: ansible-lint hogehoge.yml
      ...

※執筆時点(2024年10月)ではコンテナ利用時に $HOME が書き換わる仕様となっていますが、下記Issueもオープン状態となっており今後の動向を追いたいです。


背景

現在技術改善チーム内のクラウド移行チームとして、オンプレミスからパブリッククラウドへの移行やAnsibleのCI/CDパイプラインの見直し・改善を進めています。

数年前から運用しているリポジトリでlintが整備されていない状態だったので、まずはコードを整形するためにansible-lintを導入しました。
このリポジトリでは .ansible-lint 設定ファイルが存在していたので、一部ルールについてはwarn_listやskip_listを用いて設定をしています。
また実行環境もローカル、CI/CDで合わせたいという意図からDockerコンテナを利用して実行環境を揃えるようにしました。

ローカル環境で整備して設定した通りの挙動をするものの、GitHub Actions上だと同じ期待結果が得られず、異なるエラーとなりました。

事象

ローカルでansible-lintを実行するとこのような結果となります。

## local
ansible-lint hogehoge.yml
...
Passed: 0 failure(s), 19 warning(s) on 24 files. Last profile that met the validation criteria was 'shared'. Rating: 4/5 star

ですがGitHub Actions上でansible-lintを実行すると失敗しています。

## GitHub Actions
## Run ansible-lint
ansible-lint hogehoge.yml
...
Failed: 1 failure(s), 18 warning(s) on 24 files.

.ansible-lint でwarn_listに設定したものが無視されてそうな挙動です。
試しに設定を消してみたらローカルでも同じく 1 failure(s) となりました。

## local
ansible-lint hogehoge.yml
...
Failed: 1 failure(s), 18 warning(s) on 24 files. Last profile that met the validation criteria was 'shared'. Rating: 4/5 star

原因

デバック目的でステップにいろいろ処理を仕込んでみました。
※実際には原因調査時にステップごとに追加・削除等を行っています。

      ## Debug: ansible 周りの確認
      - name: Check ansible-galaxy --version
        run: ansible-galaxy --version
      - name: Check ansible-galaxy collection list
        run: ansible-galaxy collection list
      ## Debug: ディレクトリのファイル確認
      - name: Check Directory /root/.ansible/
        run: ls -alR /root/.ansible/
      - name: Check Directory /github/home/.ansible/
        run: ls -alR /github/home/.ansible/
      ## Debug: $HOMEの確認
      - name: Check Env HOME
        run: printenv HOME

事前にローカル環境での ansible-galaxy などで情報を見ておくとこんな感じでした。

## local
ansible-galaxy --version | egrep 'configured module search path|ansible collection location'
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections

ansible-galaxy collection list

# /root/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
amazon.aws        8.2.1
community.aws     8.0.0
community.general 9.5.0

GitHub Actionsでの確認するとこのような感じで ansible-galaxy collection list についてはエラーとなりました。

## GitHub Actions
## Check ansible-galaxy --version
ansible-galaxy --version | egrep 'configured module search path|ansible collection location'
  configured module search path = ['/github/home/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible collection location = /github/home/.ansible/collections:/usr/share/ansible/collections

## Check ansible-galaxy collection list
ansible-galaxy collection list
...
ERROR! - None of the provided paths were usable. Please specify a valid path with --collections-path
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...
...

どうやらHOMEのパスも異なっていそうです。 ローカル環境では /root となっています。

## local
printenv HOME
/root

GitHub Actionsでは /github/home となっていました。

## GitHub Actions
## Check Env HOME
printenv HOME
/github/home

どうやらGitHub Actionsでコンテナを実行すると $HOME/root から /github/home へ書き換わる仕様となっているようです。
上記仕様で期待するAnsible collectionパスが通っておらず、GitHub Actions上で実行すると結果が異なる状態となることがわかりました。

対応

正しく実行するために、以下の対応方法を考えました。

  • 1: Ansible collectionパスのシンボリックリンクを貼る
  • 2: Ansible collectionの中身をコピーする
  • 3: 提供されているサードパーティアクションを利用する

今回はシンプルで簡単なシンボリックリンクを貼る方法にしました。

GitHub Actionsの修正は下記のような感じです。

    steps:
      ...
      # NOTE: GitHub Actions でコンテナを実行するとHOMEが書き換わる
      # https://github.com/actions/runner/issues/863
      # HOMEが書き換わる影響として Ansible collection パスが無い状況になるので意図しないエラーが発生する
      # そのためシンボリックリンクを貼って collection パスを通すことにした
      - name: Make Symbolic link
        run: ln -sf /root/.ansible /github/home/
      - name: Run ansible-lint
        run: ansible-lint hogehoge.yml
      ...

今回の仕様をコードコメント上にも残しておきました。

動作確認

GitHub Actionsでの実行でも、ローカル環境と同じ結果が得られるようになりました。

下記は修正後のGitHub Actionsでの確認となります。

## GitHub Actions
## Run ansible-lint
ansible-lint hogehoge.yml
...
Passed: 0 failure(s), 19 warning(s) on 24 files. Last profile that met the validation criteria was 'shared'. Rating: 4/5 star

まとめ

実行環境をあわせる目的でコンテナを利用していましたが、まさかGitHub Actionsでコンテナ利用時に $HOME が書き換わる仕様があるとは驚きました。
Issueを見ていると同様の問題に遭遇した方が多く、この仕様だと多くの問題があるよねという声も見られました。今後の動向が気になります。

皆さまもGitHub Actionsでコンテナを利用する場合は注意してくださいね。