zaki work log

作業ログやら生活ログやらなんやら

Ansible BuilderをGitLab RunnerのCIで起動してEEコンテナイメージの自動ビルド(Red Hat認証込み)

本エントリは「Ansible Advent Calendar 2025」の18日目のエントリです。
今回はおそろしく速いシリーズじゃないです。

EEカスタムイメージのビルドについては、GitHub Actionsを使った自動ビルドと、AWSのCodeDeployを使った自動ビルドは以前試してみてたけど、せっかくなので(当時周りがGitLabで試してたのもあってため自分はスルーしてたけど、最近別件の仕事でGitLabのGit機能だけを少し触ったんで)GitLab Runnerを使った自動ビルドについて、手元で試してみた。
環境はローカルに立てているDocker版GitLab + GitLab Runner構成で、executorもDockerを使用。

zaki-hmkc.hatenablog.com

ちなみに以前の自動ビルドは、ベースイメージの取得でのみRed Hatアカウントの認証が必要なビルドを試しているが、今回はAnsibleコレクションインストールでAutomation Hubへログインする処理も追加。

あと、これでなければならない、というわけではないが、buildahを使ってイメージビルドしている。

内容についてはAnsible EEイメージのビルドが焦点なので、GitLab Runnerの仕組みや.gitlab-ci.ymlのカスタマイズ関連は割愛。(最小限の構成)(というか全然詳しくない)(何もわからん)

docs.gitlab.com

追加認証が必要ないplainなEEイメージのビルド

まずは基本構成。
ベースイメージは認証が必要なRHELのイメージでなく、素でpullできるQuayにあるAlmaLinuxを使用(このイメージである理由は単に認証不要のサンプル、というだけで、以前作成したものがあるのでそれを再利用(+α)しただけなので深い意味はない)

zaki-hmkc.hatenablog.com

.gitlab-ci.yml

処理の流れは以下の通り

  • Docker executorで起動するBuildahコンテナを指定
  • tagを作成した時にCI起動
  • pipx経由でansible-builderをインストール、createでDockerfileのみ生成し、buildahでビルドしてpush
---
image: quay.io/buildah/stable:latest

build-alma-ee:
  rules:
  - if: $CI_COMMIT_TAG

  variables:
    IMAGE_NAME: "${CI_REGISTRY_IMAGE}/alma-ee"
    TAG_NAME: "${CI_COMMIT_TAG}"
  before_script:
  - buildah login --tls-verify=false --username "${CI_REGISTRY_USER}" --password "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}"

  script:
  - dnf install -y pipx
  - pipx install ansible-builder
  - $HOME/.local/bin/ansible-builder create

  - buildah build -f Dockerfile -t ${IMAGE_NAME}:${TAG_NAME} context/
  - buildah push --tls-verify=false "${IMAGE_NAME}:${TAG_NAME}"
  - buildah push --tls-verify=false "${IMAGE_NAME}:${TAG_NAME}" "${IMAGE_NAME}:latest"

まずbefore_script内で、ビルドされたイメージをpushするためにbuildah loginでログイン情報を作成しておく。
GitLabのコンテナレジストリログインに必要な認証情報は、定義済み変数として自動で与えられるのでそれを使用する。(CI_REGISTRY_で始まる各変数)

docs.gitlab.com

variablesによる変数定義では、CI_REGISTRY_IMAGEにはGitLab上の"ユーザー名/プロジェクト名"がセットされるので、手元の環境ではこのプロジェクトで複数のコンテナイメージを保持するために、パスを追加している。
プロジェクト内で1コンテナイメージのみ扱うのであればそのまま使ってOK
イメージのタグには、Gitリポジトリのtag名を使用している
(GitLab Runnerにもタグの概念があるのでそっちを使っても良さそうだけど、これは仕組みをよくわかってないので今回は未使用)

実際の処理はscript配下で定義。コマンドの羅列なので、これ以上ないくらい書いた通りの内容。
ansible-builderbuildahでビルドするために、GHAの場合と同様Dockerfileを生成するのみ。
生成されるDockerfilecontextディレクトリ以下に作成されるので、buildah buildでビルドする時の引数にコンテキスト情報として指定する。
イメージのpushについては、latestと指定tag名の両方で実施している。(latestが常に最新…というか最後にpushされた名前付きイメージと同じものを指す、というオーソドックスな運用)

また、GitLabは自己署名証明書で構築しているためpushloginの際は--tls-verify=falseSSL検証を無視する。

トリガーである「tagを作成した場合」についてはrulesで定義。

docs.gitlab.com

execution-environment.yml

前述の通り、AlmaLinuxをベースに認証不要のパッケージ類のみインストールする構成。
補足としてAlmaLinux10を使わなかったのは実行環境のx86-64-v2だとCPU制限で動作しなかったためで、VMの設定を見直せば動くはず。(以前もRHEL9系で同様のことがあったけど、今回はコンテナイメージの自動ビルドという本編には関係しないので回避)

AlmaLinux9の場合、デフォルトのPythonは3.9で結構古いため、python_interpreter定義で別途python3.12パッケージをインストールしている。またこのパッケージでインストールされるPythonインタプリタ/usr/bin/python3ではないため、python_pathでパスを明示。
(Python3.9だと、Ansible Core 2.20が入らないという事情。サンプルなのでバージョン指定しなくてもよかったけどね)

---
version: 3

images:
  base_image:
    name: quay.io/almalinuxorg/9-minimal:9

options:
  package_manager_path: /usr/bin/microdnf

dependencies:
  python_interpreter:
    package_system: python3.12
    python_path: /usr/bin/python3.12
  ansible_core:
    package_pip: ansible-core==2.20
  ansible_runner:
    package_pip: ansible-runner==2.4.2
  galaxy:
    collections:
      - ansible.posix
      - community.general
      - community.proxmox
  python:
    - jsonpath
  system:
    - git

これらのファイルがGitリポジトリにある状態でtagを作成すれば、CIが動いて定義した内容でイメージがビルドされコンテナレジストリへpushされる。

Red Hat RegistryとAutomation Hubへの認証情報付き

上の内容をベースに、下記を組み込み

  • ベースイメージをAAPのデフォルト実行環境にも設定されているregistry.redhat.ioRHELイメージを使用
  • Automation HubのAnsibleコレクションを追加
  • 上記に必要な認証情報はハードコードせずにGitLabのCI/CDの変数設定から注入

3つ目は特に重要というか頑張って先月まとめたところ。

.gitlab-ci.yml

前述AlmaLinux版からの変更点は2か所

  1. before_scriptに記述しているコンテナレジストリへのlogin処理に、Red Hatのコンテナレジストリの分を追加
    • ユーザー名、パスワード、レジストリURLはCI/CD変数にセットしたものを参照
    • RH_PASSWORDについてはVisibilityを「Masked and hidden」に設定してCI/CDのログに流れないようにする
  2. buildah buildの引数に--build-argを追加し、Automation Hubの認証トークンを設定
---
image: quay.io/buildah/stable:latest

build-rhel-ee:
  rules:
  - if: $CI_COMMIT_TAG

  variables:
    IMAGE_NAME: "${CI_REGISTRY_IMAGE}/rhel-ee"
    TAG_NAME: "${CI_COMMIT_TAG}"
  before_script:
  - buildah login --tls-verify=false --username "${CI_REGISTRY_USER}" --password "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}"
  - buildah login --username "${RH_USERNAME}" --password "${RH_PASSWORD}" "${RH_REGISTRY}"

  script:
  - dnf install -y pipx
  - pipx install ansible-builder
  - $HOME/.local/bin/ansible-builder create

  - buildah build -f Dockerfile -t ${IMAGE_NAME}:${TAG_NAME} --build-arg=ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN="${RH_AUTOMATION_HUB_TOKEN}" context/
  - buildah push --tls-verify=false "${IMAGE_NAME}:${TAG_NAME}"
  - buildah push --tls-verify=false "${IMAGE_NAME}:${TAG_NAME}" "${IMAGE_NAME}:latest"

execution-environment.yml

前述AlmaLinux版からの変更点は以下の通り。

  • ベースイメージはregistry.redhat.ioにあるRHEL系イメージのminimal版
    • これもPythonバージョンは3.11でAnsible Coreが2.19までしか入らないため、AlmaLinuxと同様別途Python3.12を追加
  • AnsibleコレクションにAutomation Hubからインストールするansible.platformansible.controllerを追加
  • Automation HubとAnsible Galaxyの両方を見るための設定をprepend_galaxyに追加
    • Automation Hubの認証トークンはANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKENにセットするがこのファイルへのハードコードではなくビルドコマンド(前述.gitlab-ci.ymlコマンドライン)の引数で指定する

prepend_galaxyの記述とAutomation Hubの認証が必要なイメージビルドについては、詳しくは下記参照。

zaki-hmkc.hatenablog.com

---
version: 3

images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform-25/ee-minimal-rhel9:latest

options:
  package_manager_path: /usr/bin/microdnf

dependencies:
  python_interpreter:
    package_system: python3.12
    python_path: /usr/bin/python3.12
  ansible_core:
    package_pip: ansible-core==2.20
  ansible_runner:
    package_pip: ansible-runner==2.4.2
  galaxy:
    collections:
      - ansible.posix
      - community.general
      - community.proxmox
      - ansible.platform
      - ansible.controller
  python:
    - jsonpath
  system:
    - git

additional_build_steps:
  prepend_galaxy:
    - ARG ANSIBLE_GALAXY_SERVER_LIST=automation_hub,release_galaxy
    - ARG ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_URL=https://console.redhat.com/api/automation-hub/content/published/
    - ARG ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_AUTH_URL=https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token
    - ARG ANSIBLE_GALAXY_SERVER_AUTOMATION_HUB_TOKEN
    - ARG ANSIBLE_GALAXY_SERVER_RELEASE_GALAXY_URL=https://galaxy.ansible.com/

この内容でGitリポジトリ上でtagを作成すれば、CIが動いて上記で定義した内容でイメージビルドされコンテナレジストリへpushされる。

Buildahコンテナ補足

Python系のパッケージは入っていないので、CIの中でインストールしている。
速度等を重視するのであればansible-builderをインストール済みのカスタムイメージをビルドしておき、それをCIで使うのがより良い。

構成を簡易なものにするため、pipxをOSパッケージマネージャでインストールし、pipxansible-builderをインストール、という構成にしている。
インストール先は$HOME/.local/binになるため、実行時はフルパス指定。

dnf install pipx
pipx install ansible-builder
$HOME/.local/bin/ansible-builder --version
3.1.1

今回は扱わなかったけどマルチプラットフォームビルドするならこの辺りを参考。

docs.gitlab.com

Docker in Docker情報

docs.gitlab.com

docs.gitlab.com

docs.gitlab.com

環境

  • GitLab v18.0.1
  • GitLab Runner v16.6.1 (古い)

参考情報

最近過去の記事を組み合わせたパターン増えてきたな。

zaki-hmkc.hatenablog.com

zaki-hmkc.hatenablog.com

zaki-hmkc.hatenablog.com

zaki-hmkc.hatenablog.com

zaki-hmkc.hatenablog.com

Buildahを使う選択肢とログイン処理をbefore_scriptで定義することについては、GitLab実践ガイド第2版の「6-4 コンテナイメージへのパッケージ化」を参考にしました。