目次
はじめに
前回 と 前々回 のエントリでは、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
ドキュメントには プラグインの一覧 が掲載されており、例えば次のようなものが提供されていることがわかります。
- Ansible のロールやコレクションを管理するための Ansible プラグイン
- コンテナイメージを管理するための Container プラグイン
- Python のパッケージを管理するための Python プラグイン
- RPM を管理するための RPM プラグイン
つまり 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 に置いて いるので流れだけの紹介にとどめますが、作業は次の通りです。
- Ingress 用の自己署名証明書作って
- マニフェストのホスト名を書き換えて
- (今回はシングルノード K3s なので)PV の
hostPath
で使うディレクトリを作って - 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 に置いて います。
手順では、まずは下準備として以下を実施しています。
- Ingress 用の自己署名証明書作って
- マニフェストのホスト名を書き換えて
- (今回はシングルノード 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.py
に galaxy_require_content_approval: "False"
が入るように構成すると、承認を不要にできます)。
承認すると、Collections
> Collections
の Published
リポジトリ内で存在が確認できます。
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 Verification
を On
に変更します。
これで、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 Namespaces
は Namespace
ページのタブに替わっています。