Ansible Galaxy NG を Docker や Kubernetes で気軽に試す方法いろいろ

はじめに

前回前々回 のエントリでは、Ansible AWX 周辺の最近の機能として、Execution Environment や、さらにその周辺の Ansible Runner、Ansible Builder の OSS 版での動きを追いかけました。今回は、Private Automation Hub のアップストリーム版である Ansible Galaxy NG の周辺を見ていきます。

が、現時点でサポートされている構成はホスト OS への直接のインストールのみで、開発用には Docker Compose ベースの手順もあるものの、いずれにせよ総じて取り回しが少々不自由です。そんなわけで本エントリでは、現時点で気軽に Galaxy NG を試せる方法 として、次の 3 パタンでの実装手順 と、簡単な動作確認 を取り扱います。

なお、いずれも Galaxy NG のドキュメントには記載がない 方法であり、当然ながら 正式にサポートされる手順ではない 点は注意が必要です。このエントリは 実験レポート程度 に捉え、検証や勉強やテスト など 試用を目的としたユースケースに限定 して遊ぶとよいでしょう。

  • Docker で全部入りコンテナを使うパタン
    • おそらくもっとも手軽な Galaxy NG の入手方法
    • すべてが一つに詰め込まれた既成コンテナイメージを動かすだけ
  • Kubernetes で全部入りコンテナを使うパタン
    • 前述の Docker パタンを愚直に Kubernetes 上に移植したもの
    • プラットフォームを Kubernetes に揃えたいならいちばん気軽
  • Kubernetes で Pulp Operator を使うパタン
    • おそらく将来的に正式な Kubernetes 上へのデプロイ方法になる気がしているパタン
    • マイクロサービス化されてスケールもできる状態できちんとしたモノができあがる
    • まだまだ開発途上の様子(動かせはする)

とはいえ、自製の Collection の表示のテスト など特定用途ではなかなか便利そうです。最初の Docker パタンなら、慣れれば 10 秒で完成 します。

今回も、必要なファイルは GitHub に置いています

前提: Pulp とそのプラグインとしての Galaxy NG

Galaxy NG は、それ単体で独立したプロダクトではなく、実際には Pulp と呼ばれる パッケージ配布用プラットフォームプラグインのひとつ のようです。

Pulp is a platform for managing repositories of software packages and making them available to a large number of consumers. Pulp can locally mirror all or part of a repository, host your own software packages in repositories, and manage many types of content from multiple sources in one place.

Pulp | software repository management

ドキュメントには プラグインの一覧 が掲載されており、例えば次のようなものが提供されていることがわかります。

つまり Galaxy NG は、言い換えるとざっくりとは Ansible プラグインや Container プラグインと連携しながらそれらをまとめて管理するための機能を Pulp に追加するプラグイン、とも言えそうです。たぶん。

前提: 公式の Galaxy NG の構築手順

公式には、Galaxy NG には現時点で二種類の構築手段がありそうです。

ホスト OS に直接インストールするパタン

標準的なインストール手順は、次のドキュメントで案内されている、ホスト OS に直接 Ansible でインストールするパタンです。今日現在では、これが オンプレミスできちんと使いたい場合に採用できる唯一の手段 でしょう。

見かけ上はとても簡単そうですが、現段階でこれに従って作業すると、pulp_installer が新しすぎる、pulp-container も新しすぎる、firewalld 用のモジュールが古い、などなどのアレで依存関係の諸々が厄介で、意外と素直には進められません。

また、ホスト OS に直接インストールするため、当然ですが /etc/var にいろいろ置かれたり、systemd にサービスが追加されたり、ファイアウォールルールがいじられたりして、ホスト OS に深く入り込んでしまい、現実的にはそのホストを Galaxy NG 用として専有させる運用になりそうです。

本気で自前運用をする場合はそれでよいですが、気軽に試したいだけの場合には、フットワークは軽いとはなかなか言い難いですね。

コンテナイメージをビルドして動作させるパタン(開発用)

開発環境用として、コンテナ下で動作させる方法も用意されています。

あくまで開発用ではありますが、ホスト OS に直接インストールするよりはだいぶ気軽です。手順に従うと次のようなコンテナ群が動作し、Web UI もコンテナレジストリも利用できる状態ができあがります。

$ ./compose ps
INFO: Using compose profile standalone
INFO: galaxy_ng packages installed from source
INFO: Image suffix is unset
INFO: Volume suffix is unset
            Name                          Command               State                       Ports                    
---------------------------------------------------------------------------------------------------------------------
galaxy_ng__base_1              /bin/true                        Exit 0                                               
galaxy_ng_api_1                /entrypoint.sh run api-reload    Up       0.0.0.0:5001->8000/tcp,:::5001->8000/tcp    
galaxy_ng_content-app_1        /entrypoint.sh run content-app   Up       0.0.0.0:24816->24816/tcp,:::24816->24816/tcp
galaxy_ng_postgres_1           docker-entrypoint.sh postgres    Up       0.0.0.0:5432->5432/tcp,:::5432->5432/tcp    
galaxy_ng_redis_1              docker-entrypoint.sh redis ...   Up       6379/tcp                                    
galaxy_ng_resource-manager_1   /entrypoint.sh run resourc ...   Up                                                   
galaxy_ng_ui_1                 docker-entrypoint.sh /hub/ ...   Up       0.0.0.0:8002->8002/tcp,:::8002->8002/tcp    
galaxy_ng_worker_1             /entrypoint.sh run worker        Up                                   

コンテナのイメージは自前でビルドが必要で、起動と停止には専用のシェルスクリプトの利用が前提にされてはいますが、クローンしたリポジトリのタグをうまく使えば任意のバージョンの Galaxy NG を実際に動作させられます。試用環境としては充分実用的です。

Docker で全部入りコンテナを使う

ここからは、Galaxy NG のドキュメントでは記載されていない手段での構築を取り扱います。まずは Docker を使って最も手軽に動かすパタンです。

考え方

前述した通り、Galaxy NG は、実際は Pulp のプラグインのひとつです。であれば、そもそも Pulp 自体をコンテナで動かす手段 があれば、Galaxy NG もコンテナで動かせることが期待できます。

そんなこんなでドキュメントを確認していくと、Pulp in One Container なるページで、全部入りコンテナ が紹介されています。

Installing Pulp 3 and getting all the services running can be challenging. To reduce the complexity of getting started with Pulp, the Pulp team created a single container image that has all necessary services to run Pulp 3.

Pulp in One Container | software repository management

もとになっている Containerfile は、GitHub で管理されているようです。

また、この中に pulp_galaxy_ng ディレクトリ があり、Containerfile を読み解く と、Galaxy NG(現時点では 4.3.1)がバンドルされたイメージであることがわかります。このイメージは CI で Docker Hub にプッシュされているようです。

というわけで、動かしてみましょう。

構築手順

とても簡単な 3 ステップです。基本は ドキュメント の通りで、使うイメージの変更と 起動後の手順の追加 だけ配慮します。

ディレクトリを作って、設定ファイルをひとつ作成します。

mkdir settings pulp_storage pgsql containers
cat <<EOF > settings/settings.py
CONTENT_ORIGIN='http://$(hostname):8080'
ANSIBLE_API_HOSTNAME='http://$(hostname):8080'
ANSIBLE_CONTENT_HOSTNAME='http://$(hostname):8080/pulp/content'
TOKEN_AUTH_DISABLED=True
EOF

コンテナを起動させます。

docker run --detach \
             --publish 8080:80 \
             --name pulp \
             --volume "$(pwd)/settings":/etc/pulp \
             --volume "$(pwd)/pulp_storage":/var/lib/pulp \
             --volume "$(pwd)/pgsql":/var/lib/pgsql \
             --volume "$(pwd)/containers":/var/lib/containers \
             --device /dev/fuse \
             pulp/pulp-galaxy-ng:latest

あとは、初期設定ファイルを読ませれば完成です。

DATA_FIXTURE_URL="https://raw.githubusercontent.com/ansible/galaxy_ng/master/dev/automation-hub/initial_data.json"
curl $DATA_FIXTURE_URL | docker exec -i pulp bash -c "cat > /tmp/initial_data.json"
docker exec pulp bash -c "/usr/local/bin/pulpcore-manager loaddata /tmp/initial_data.json"

これで、http://<IP アドレス>:8080/ から Galaxy NG が使える状態が得られます。初期ユーザは admin で、パスワードも admin です。

永続化が必要なデータは冒頭で作成したディレクトリ下に置かれるので、停止や起動をしてもデータは消えません。簡単ですね。

Kubernetes で全部入りコンテナを使う

続いて、前述した Docker で全部入りコンテナを使うパタンを、そのまま Kubernetes 上で再現するパタンです。

考え方

基本的には、Docker での構成を参考に Kubernetes のマニフェスト化するだけです。一点だけ工夫して、ここでは Galayxy NG のエンドポイントを Ingress で HTTPS 化します。

ざっくり構築手順

ボリュームの持たせ方や設定ファイルの読ませ方など、Kubernetes ならではの部分もありますが、愚直にマニフェストを書くだけなので、特に難しいことはありません。ファイルと実際の手順は GitHub に置いて いるので流れだけの紹介にとどめますが、作業は次の通りです。

  1. Ingress 用の自己署名証明書作って
  2. マニフェストのホスト名を書き換えて
  3. (今回はシングルノード K3s なので)PV の hostPath で使うディレクトリを作って
  4. Kustomize で apply する

完成すると、ネームスペース galaxy に前述の全部入りコンテナが動作する Pod ができあがります。

$ kubectl -n galaxy get all
NAME                          READY   STATUS    RESTARTS   AGE
pod/galaxy-78df96fc64-l7tbq   1/1     Running   0          53s

NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/galaxy-service   ClusterIP   10.43.201.53   <none>        80/TCP    6m14s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/galaxy   1/1     1            1           53s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/galaxy-78df96fc64   1         1         1       53s

あとは初期設定ファイルを流し込めば完成です。

POD_NAME=$(kubectl -n galaxy get pod -l app=galaxy -o name)
DATA_FIXTURE_URL="https://raw.githubusercontent.com/ansible/galaxy_ng/master/dev/automation-hub/initial_data.json"
curl $DATA_FIXTURE_URL | kubectl -n galaxy exec -i $POD_NAME -- bash -c "cat > /tmp/initial_data.json"
kubectl -n galaxy exec -i $POD_NAME -- bash -c "/usr/local/bin/pulpcore-manager loaddata /tmp/initial_data.json"

これで、https://galaxy.example.com/ から Galaxy NG が使える状態が得られます。初期ユーザは admin で、パスワードも admin です。

Kubernetes で Pulp Operator を使う

もっと本気で Kubernetes 上で Galaxy NG をホストしたいときの参考実装例です。

考え方

探すと、Pulp の Operator も存在していました。

Operator なので、以前のエントリ紹介した AWX の Operator でのデプロイ と似た使い方で、カスタムリソースとして Pulp のインスタンスを定義することになります。

絶賛開発中のようで、ドキュメントは多くないですが、今回はリポジトリ内のコード群と併せて読み解いていき、次の点あたりを考慮しながらマニフェストを作ってデプロイします。

  • Ingress で HTTPS 化する
  • Operator のバージョンを、現時点で最新のタグである 0.3.0 に固定する(デフォルトは latest
  • コンテナレジストリ機能を有効化する
  • ストレージは指定の PV にバインドさせる
  • 各 Pod のレプリカ数は 1 にする

ざっくり構築手順

こちらも、 ファイルと実際の手順は GitHub に置いて います。

手順では、まずは下準備として以下を実施しています。

  1. Ingress 用の自己署名証明書作って
  2. マニフェストのホスト名を書き換えて
  3. (今回はシングルノード K3s なので)PV の hostPath で使うディレクトリを作る

この後、最初に Pulp Operator をまず動作させます。この段階で一緒にカスタムリソース定義(CRD)も読ませています。

kubectl apply -k galaxy/operator

これで、galaxy ネームスペースで Pulp Operator が動作しはじめます。

$ kubectl -n galaxy get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/pulp-operator-75668bb8c-gcj2t   1/1     Running   0          61s

NAME                            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
service/pulp-operator-metrics   ClusterIP   10.43.205.91   <none>        8383/TCP,8686/TCP   55s

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/pulp-operator   1/1     1            1           61s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/pulp-operator-75668bb8c   1         1         1       61s

最後に、同じネームスペースに Pulp リソースを定義します。

kubectl apply -k galaxy/galaxy

プレイブックが走りだして、しばらく待つとデプロイが完了します。

$ kubectl -n galaxy logs -f deployment/pulp-operator
...
--------------------------- Ansible Task Status Event StdOut  -----------------
PLAY RECAP *********************************************************************
localhost                  : ok=51   changed=0    unreachable=0    failed=0    skipped=47   rescued=0    ignored=0
-------------------------------------------------------------------------------

できあがりの構成をみると、だいぶ重厚です。

今回は各 Pod のレプリカ数をすべて 1 に明示的に指定(Pulp リソースの構成を定義した galaxy.yml の中で)していますが、デフォルトが 2 になっているものもあり、本格的かつ大規模な利用を見越した開発が行われていることが伺えます。

$ kubectl -n galaxy get all,pulp
NAME                                          READY   STATUS    RESTARTS   AGE
pod/pulp-operator-75668bb8c-kcwzc             1/1     Running   0          3m53s
pod/galaxy-postgres-0                         1/1     Running   0          3m14s
pod/galaxy-redis-6fd7f7dd44-5l7gw             1/1     Running   0          3m10s
pod/galaxy-content-77d89f4c46-5f7s7           1/1     Running   0          2m55s
pod/galaxy-resource-manager-74895b7b5-hfq6w   1/1     Running   0          2m54s
pod/galaxy-worker-7c8ff54785-9twwg            1/1     Running   0          2m53s
pod/galaxy-api-7845d86d77-gwt84               1/1     Running   0          2m57s
pod/galaxy-web-776cccc64-hxp4f                1/1     Running   2          3m8s

NAME                            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/pulp-operator-metrics   ClusterIP   10.43.64.53     <none>        8383/TCP,8686/TCP   3m48s
service/galaxy-postgres         ClusterIP   None            <none>        5432/TCP            3m14s
service/galaxy-redis            ClusterIP   10.43.193.92    <none>        6379/TCP            3m11s
service/galaxy-web-svc          ClusterIP   10.43.21.92     <none>        24880/TCP           3m7s
service/galaxy-api-svc          ClusterIP   10.43.148.168   <none>        24817/TCP           2m58s
service/galaxy-content-svc      ClusterIP   10.43.151.55    <none>        24816/TCP           2m56s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/pulp-operator             1/1     1            1           3m53s
deployment.apps/galaxy-redis              1/1     1            1           3m10s
deployment.apps/galaxy-content            1/1     1            1           2m55s
deployment.apps/galaxy-resource-manager   1/1     1            1           2m54s
deployment.apps/galaxy-worker             1/1     1            1           2m53s
deployment.apps/galaxy-api                1/1     1            1           2m57s
deployment.apps/galaxy-web                1/1     1            1           3m8s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/pulp-operator-75668bb8c             1         1         1       3m53s
replicaset.apps/galaxy-redis-6fd7f7dd44             1         1         1       3m10s
replicaset.apps/galaxy-content-77d89f4c46           1         1         1       2m55s
replicaset.apps/galaxy-resource-manager-74895b7b5   1         1         1       2m54s
replicaset.apps/galaxy-worker-7c8ff54785            1         1         1       2m53s
replicaset.apps/galaxy-api-7845d86d77               1         1         1       2m57s
replicaset.apps/galaxy-web-776cccc64                1         1         1       3m8s

NAME                               READY   AGE
statefulset.apps/galaxy-postgres   1/1     3m14s

NAME                               AGE
pulp.pulp.pulpproject.org/galaxy   3m22s

他の手順と同様に、https://galaxy.example.com/ から Galaxy NG にアクセスできます。

Galaxy NG の動作確認

できあがった Galaxy NG が正しく Galaxy NG として使えることを、簡単な操作方法の紹介もかねて確認していきます。

コレクションの同期

公開 Galaxy サーバである https://galaxy.ansible.com/ から、いくつかのコレクションを Galaxy NG に同期させます。

同期対象を Galaxy の requirements.yml と同じ書式の YAML ファイルで手元で作成します。

---
collections:
  - name: community.general
    source: https://galaxy.ansible.com
    version: ">=3.2.0"
  - name: community.kubernetes
    source: https://galaxy.ansible.com
    version: "2.0.0"
  - name: community.vmware
    source: https://galaxy.ansible.com
    version: ">=1.10.0,<1.12.0"
  - name: awx.awx
    source: https://galaxy.ansible.com
    version: ">=19.0.0"
  - name: ansible.utils
    source: https://galaxy.ansible.com
    version: ">=2.1.0"

この後、Galaxy NG の Collections > Repository Management > Remote で community の Configure から作成した YAML ファイルをアップロードして、Save して Sync すると同期が開始されます。

同期が完了したら、 Collections > Collections や Collections > Namespaces などで Community リポジトリに切り替えれば、同期されたコレクションの存在が確認できます。

ただし、サムネイルやドキュメントはうまく表示されないようです。

自製コレクションの登録

ミニマムなコレクションを作って登録してみます。せっかくなので、プラグイン、モジュール、ロールをひとつずつ含めます。

# 空っぽのガワの作成
ansible-galaxy collection init demo.collection

# プラグインの作成
mkdir -p demo/collection/plugins/vars
cat <<EOF > demo/collection/plugins/vars/sample_vars.py
DOCUMENTATION = '''
---
vars: sample_vars
short_description: Add a fixed variable named sample_var
version_added: "1.0.0"
description: Just add a fixed variable with name sample_var.
'''
from ansible.plugins.vars import BaseVarsPlugin
class VarsModule(BaseVarsPlugin):
    def get_vars(self, loader, path, entities):
        return {"sample_var": "This is sample variable"}
EOF

# モジュールの作成
mkdir -p demo/collection/plugins/modules
cat <<EOF > demo/collection/plugins/modules/sample_module.py
DOCUMENTATION = '''
---
module: sample_module
short_description: This is my test module
version_added: "1.0.0"
description: This is my longer description explaining my test module.
'''
from ansible.module_utils.basic import AnsibleModule
if __name__ == '__main__':
    result = dict(changed=False, message='Hello from Module')
    module = AnsibleModule(argument_spec={})
    module.exit_json(**result)
EOF

# ロールの作成
cd demo/collection/roles
ansible-galaxy init sample_role
cat <<EOF > sample_role/tasks/main.yml
---
- name: Hello
  debug:
    msg: "World"
EOF

# tarball のビルド
cd ../
ansible-galaxy collection build

これでカレントディレクトリにコレクションの実体である demo-collection-1.0.0.tar.gz ができあがります。

あとはこれを Galaxy NG に送れば完了です。Galaxy NG 上でコレクションの格納先になる新しいネームスペースを作成(今回は demo)して、GUI またはコマンドでアップロードします。

GUI からは何も気にせずに Upload collection すればよいですが、コマンドで行う場合は、次の二つの情報を準備しておきます。

  • 作成したネームスペースの URL を Collections > Namespaces > View collections > CLI Configuration から確認
  • API のトークンを Collections > API Token から取得

あとは、それらの値を使って ansible-galaxy collection publish コマンドを実行します。サーバ側が自己署名証明書の HTTPS なので -c を付けています。

ansible-galaxy collection publish \
  demo-collection-1.0.0.tar.gz \
  --server https://galaxy.example.com/api/galaxy/content/inbound-demo/ \
  --token d926e******************************3e996 \
  -c

アップロードが完了すると、まずは staging リポジトリに登録されます。管理者が Approve しない限り公開されないので、Collections > Approval から承認します(詳細は割愛しますが、デプロイ時に settings.pygalaxy_require_content_approval: "False" が入るように構成すると、承認を不要にできます)。

承認すると、Collections > CollectionsPublished リポジトリ内で存在が確認できます。

Documentation タブでは、コレクション自体のものだけでなく、ロールやモジュール、プラグインのドキュメントも確認できるようです。

ドキュメント情報は、コレクションとロールは README.md から、モジュールとプラグインはソースコード中の文字列(DOCUMENTATION など)から Ansible 版 pydoc 的なノリで、それぞれ生成されています。細かなドキュメントが同じ画面から見られるようになったのは、現行の Galaxy よりもわかりやすくてよいですね。

Galaxy NG からのコレクションのインストール

この Galaxy NG を ansible.cfg や環境変数で Galaxy サーバとして指定すると、ansible-galaxy コマンドのインストールソースとして利用できます。

設定ファイルのひな型は Repository Management の画面からコピーできるので、ここを使うのがラクそうです。トークンは API Token から取得できます。

[galaxy]
server_list = published_repo, community_repo

[galaxy_server.published_repo]
url=https://galaxy.example.com/api/galaxy/content/published/
token=d926e******************************3e996

[galaxy_server.community_repo]
url=https://galaxy.example.com/api/galaxy/content/community/
token=d926e******************************3e996

あとは通常通り collection install をするだけです。試しに、前項の手順で公開 Galaxy サーバから同期したコレクションと、自製したコレクションを指定してインストールします。 サーバ側が自己署名証明書の HTTPS なので -c を付けています。

$ ansible-galaxy collection install community.vmware -c
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.example.com/api/galaxy/v3/artifacts/collections/community/community-vmware-1.11.0.tar.gz to /home/kuro/.ansible/tmp/ansible-local-2778028ny7vtjq5/tmpxhmwondd/community-vmware-1.11.0-__wjvlah
Installing 'community.vmware:1.11.0' to '/home/kuro/.ansible/collections/ansible_collections/community/vmware'
community.vmware:1.11.0 was installed successfully

$ ansible-galaxy collection install demo.collection -c
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Downloading https://galaxy.example.com/api/galaxy/v3/artifacts/collections/published/demo-collection-1.0.0.tar.gz to /home/kuro/.ansible/tmp/ansible-local-2778121plxlh68p/tmpgqo218ts/demo-collection-1.0.0-z35yilz_
Installing 'demo.collection:1.0.0' to '/home/kuro/.ansible/collections/ansible_collections/demo/collection'
demo.collection:1.0.0 was installed successfully

出力から、自前の Galaxy NG からダウンロードされていることがわかります。

さらに、適当なプレイブックを作って動かしてみます。

cat <<EOF > site.yml
- hosts: localhost
  roles:
    - demo.collection.sample_role
  tasks:
    - demo.collection.sample_module:
      register: result
    - debug:
        var: result
EOF

ansible-playbook site.yml

自製コレクションのロールとモジュールの正常な動作が確認できました。

$ ansible-playbook site.yml
...
TASK [demo.collection.sample_role : Hello] ******************************************************************
ok: [localhost] => {
    "msg": "World"
}

TASK [demo.collection.sample_module] ************************************************************************
...
ok: [localhost] => {
    "result": {
        "changed": false,
        "failed": false,
        "message": "Hello from Module"
    }
}

コンテナレジストリとしての利用

Galaxy NG は、紹介した手順でデプロイすると、コンテナレジストリとしても使えます。Execution Environment の置き場所として便利そうですね。

エンドポイントが自己署名証明書を使った HTTPS なので、Insecure Registry としての登録は必要ですが、あとは通常のコンテナレジストリとまったく一緒です。

sudo tee /etc/docker/daemon.json <<EOF
{
  "insecure-registries" : ["galaxy.example.com"]
}
EOF
sudo systemctl restart docker

ここでは、前回のエントリ で使った Execution Environment をプッシュしてみます。タグ付けして、ログインしてプッシュするだけです。

docker tag registry.example.com/ansible/ee:2.10-custom galaxy.example.com/demo/ee:2.10-custom
docker login galaxy.example.com
docker push galaxy.example.com/demo/ee:2.10-custom

結果は Galaxy NG 側の Container Registry で確認できます。

あまりリッチな見た目ではないですが、README も書けるようです。

プルも無事にできそうです。

docker image rm galaxy.example.com/demo/ee:2.10-custom registry.example.com/ansible/ee:2.10-custom
docker pull galaxy.example.com/demo/ee:2.10-custom

Galaxy NG を AWX から使う

最後に、実際に AWX と組み合わせて使ってみます。

Galaxy NG に配置したコレクションを AWX のプロジェクトから使う

プロジェクトの collections/requirements.yml にコレクションの情報を記載しておくと、AWX から同期するときにコレクションの取得とインストールも AWX が勝手に行ってくれます。

公開 Galaxy サーバであれば特に設定なく使えますが、今回の Galaxy NG はプライベートサーバなので、若干の構成が必要です。プロジェクトが利用する Galaxy サーバAWX 上の Organization 単位で指定する ため、設定はOrganization を意識しながら行います。

まずは Galaxy NG の認証情報の登録です。前述した ansible.cfg の中身に相当する情報を、タイプ Ansible Galaxy/Automation Hub API Token の Credential として登録します。この時に、最終的にプロジェクトが紐づく Organization を明示 します。ここでは Default です。

リポジトリの URL は Galaxy NG の Repository Management の画面から、トークンは API Token からそれぞれ取得できます。

続けて、Access > Organizations から、利用する Organization の設定画面 を開き、Galaxy Credentials を編集します。ここで、

  • その Organization が利用する Galaxy サーバ
  • 複数の Galaxy サーバを利用する場合、その優先順位

を指定します。

既定で公開 Galaxy サーバが指定済みです。今回はここに先の手順で登録した自前の Galaxy NG の情報を追加し、優先順位をいちばん高くしました。

最後に、これは今回の環境固有ですが、Galaxy サーバのエンドポイントが自己署名証明書の HTTPS なので、Settings > Jobs > Jobs settings で、Ignore Ansible Galaxy SSL Certificate VerificationOn に変更します。

これで、AWX から Galaxy NG を利用できる状態が整いました。実験のため、次のコマンドで最小限のファイルを作成し、collection-demo ディレクトリの中身を Git リポジトリにプッシュします。

mkdir collection-demo
cd collection-demo

mkdir collections
cat <<EOF > collections/requirements.yml
---
collections:
  - name: demo.collection
EOF

cat <<EOF > site.yml
---
- hosts: localhost
  roles:
    - demo.collection.sample_role
  tasks:
    - demo.collection.sample_module:
      register: result
    - debug:
        var: result
EOF

これを AWX 側にプロジェクトとして登録して Sync すると、正しく設定できていれば、登録した認証情報を使って、プライベート Galaxy NG からコレクション demo.collection がインストールされます。

ジョブテンプレートを作って実行すると、実際に自製のモジュールが利用できていることがわかります。

Galaxy NG に配置した Execution Environment を使う

AWX 側からは、コンテナレジストリとしての Galaxy NG はもはや何の特別なものではないので、Galaxy NG に配置した Execution Environment を AWX から使うときに必要な操作も、ほかのコンテナレジストリの場合と何ら変わりはありません。

前回のエントリ と重複しますが、イメージを Kubernetes がプルすることになるので、Galaxy NG を自己署名証明書の HTTPS でホストした場合は、下回りの K3s に対してそこだけ手当をします。

sudo tee /etc/rancher/k3s/registries.yaml <<EOF
configs:
  galaxy.example.com:
    tls:
      insecure_skip_verify: true
EOF

sudo systemctl restart k3s

あとは AWX で Credential を作成してイメージを Execution Environment として登録し、インスタンスレベルかプロジェクトレベルかジョブテンプレートレベルで利用を指定するだけです。具体的な例は 前回のエントリ で取り扱っています。

トラブルシュート

自前 Galaxy NG を作ったり消したりコレクションを作ったり作り直したり登録したりインストールしたり、などなどがちゃがちゃ繰り返していると、

  • ansible-galaxy collection install した際
  • AWX でプロジェクトを同期(Sync した際)

に、次のエラーで失敗することがあります。

ERROR! Mismatch artifact hash with downloaded file

これは、初回操作時にローカルにキャッシュされたハッシュ値と、実際にダウンロードされたファイルのハッシュ値が一致しないために発生する問題です。キャッシュをクリアすれば、ハッシュ値の情報がサーバから再取得されるため、正常に戻ります。

ローカルでの操作で失敗している場合は、操作しているユーザの ~/.ansible/galaxy_cache/api.json を削除します。

rm ~/.ansible/galaxy_cache/api.json

AWX からの同期に失敗している場合は、AWX のインスタンスの Pod のうち、awx-ee コンテナの ~/.ansible/galaxy_cache/api.json を削除します。ここの ~ の実体は、awx-ee の実行ユーザ runner のホームディレクトリ /home/runner です。

kubectl -n awx exec -i $(kubectl -n awx get pod -l app.kubernetes.io/name=awx -o name) -c awx-ee -- bash -c "rm ~/.ansible/galaxy_cache/api.json"

おわりに

自前で Galaxy NG をホストする比較的手軽な方法として、Docker や Kubernetes を用いた手順をいくつか紹介しました。

繰り返しにはなりますが、いずれも Galaxy NG のドキュメントには記載がない 方法であり、当然ながら 正式にサポートされる手順ではない 点は注意が必要です。

しかしながら、Galaxy NG の動きをさくっと確認できる意味では、わりとおもしろいのではないでしょうか。自己責任前提ではありますが、最悪壊れてもどうにかなる気持ちでいられるのであれば、公式の手順での導入をがんばるよりは、だいぶ気軽に便利に使えるようになりそうです。

あと、本文で取り上げるほどでもない小ネタとして、左ペインのメニュ構成も Galaxy NG の少し前のバージョンとは変わっているようで、例えば My NamespacesNamespace ページのタブに替わっています。

@kurokobo

くろいです。ギターアンサンブルやら音響やらがフィールドの IT やさんなアルトギター弾き。たまこう 48 期ぎたさん、SFC '07 おんぞう、新日本ギターアンサンブル、Rubinetto。今は野良気味。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です