目次
はじめに
前回のエントリ “Ansible Runner と Ansible Builder で Execution Environment を作って使う” では、AWX で Execution Environment を使うための前段として、Ansible Runner と Ansible Builder の動作を確認しました。
このエントリでは、その続きとして、作成した Execution Environment を実際に AWX から利用する流れを確認します。また、Container Group を作成して、Pod の構成をカスタマイズします。
前提とする環境
本エントリでは、次の環境を前提に書いています。
- CentOS 8.2
- Python 3.9.2
- Docker 20.10.7
- Kubernetes (K3s) 1.21.2+k3s1
- AWX 19.2.2
なお、AWX を K3s 上でホストする方法は、別エントリ “AWX を AWX Operator でシングルノード K3s にホストする” で紹介しています。
また、本エントリの再現に必要な諸々の資材は、手順込みで GitHub に配置済み です。
事前準備
諸々の動作を確かめるため、AWX を触り始める前に、次のモノを用意しました。
- Execution Environment
- プライベートコンテナレジストリ
- プライベート Git リポジトリ
- プレイブック(プライベート Git リポジトリ上)
AWX から自前の Execution Environment を使いたい場合は、当然ながら事前に準備が必要です。今回は 前回のエントリ に従って、Ansible Builder で自分でビルドして用意します。なお、後述しますが、そもそも最近の AWX は、デフォルトで Execution Environment として quay.io/ansible/awx-ee
が組み込まれている(というか何もしなくても勝手に使われる)ため、自前での用意は必須ではありません。デフォルトの Execution Environment では要件を満たせない(Ansible のバージョンが違う、モジュールが足りないなど)ときにのみ、自前での用意が必要です。
また、AWX は、Execution Environment を コンテナレジストリ からプルして利用します。今回のように自分でビルドした Execution Environment を使いたい場合は、つまり、事前にそれをどこかのコンテナレジストリにプッシュしておく必要があります。この目的では、Docker Hub や Quai.io などインタネット上のサービスも利用できますが、インタネット上にコンテナイメージを配置したくない場合を想定し、本エントリでは K3s 上にプライベートコンテナレジストリをデプロイ して利用しています。
Execution Environment で動作させるプレイブック(≒AWX に追加するプロジェクトの実体)は、ローカルのプロジェクトディレクトリ(実体は Kubernetes の PV)に配置してもよいですが、少し本格的な利用を想定して、SCM から取得させます。この目的で、本エントリでは K3s 上にプライベート Git リポジトリ をデプロイしています。そして、動作させる プレイブック を実際に Git リポジトリ上に用意します。
上記それぞれのもう一歩踏み込んだ詳細は、本筋ではないのでここでは割愛して、本エントリの末尾で 補足: 事前準備の作業内容 としてまとめています。
AWX での Execution Environment の利用
事前準備ができて環境が整ったら、AWX で実際に Execution Environment を利用してプレイブックを実行します。
今回の環境固有の準備
AWX 上で、次の二つの Credential を登録しておきます。
Container Registry
の Credential(registry.example.com
用)Source Control
の Credential(git.example.com
用)
また、今回は Git リポジトリが自己署名証明書を利用した HTTPS 接続のため、Settings
> Jobs
> Jobs settings
の Extra Environment Variables
で、次の値を設定しておきます。
{
"GIT_SSL_NO_VERIFY": "True"
}
Execution Environment の登録
コンテナレジストリに配置した自前の Execution Environment は、明示的に Execution Environment として AWX に登録が必要です。メニュの Administration
> Execution Environment
から、名前やイメージのタグ、プルするタイミング、認証情報などを指定して登録します。
自前の Execution Environment は、今回は事前準備段階で二つ用意してあったので、二つとも登録しました。
なお、一覧を見ると、デフォルトで AWX EE と Control Plane Execution Environment が登録されていることがわかります。これらは、Execution Environment を明示しなかったジョブや、SCM の Sync ジョブ、管理系のジョブなどで透過的に利用されています。
プロジェクトの登録
メニュの Resources
> Projects
から、通常通りにプロジェクトを追加します。ここでは、事前準備で Gitea 上に作成した gitea/ee-demo
プロジェクト(中身は GitHub の kurokobo/awx-on-k3s
を丸ごとコピーしただけ)を指定しています。
画面の通り、プロジェクトの登録の段階でも Execution Environment を指定できます。今回は空欄にしましたが、プロジェクトレベルでデフォルトを指定しておき、後続のジョブテンプレートレベルでオーバライドするような使い方も可能です。また、Settings
の Miscellaneous System settings
から、さらに上位のインスタンスレベルでのデフォルトの Execution Environment も指定できるようです。
登録したら、Sync しておきます。
ジョブテンプレートの登録
最後に、メニュの Resources
> Templates
から、通常通りジョブテンプレートを登録します。
先の手順で登録したプロジェクトを選択して、プレイブックにはテスト用の runner/project/demo.yml
を指定しました。これは 前回のエントリ で使ったプレイブックそのもので、自ホスト名や実行ユーザ名、Ansible のバージョン、パッケージやコレクションの一覧を表示してくれるものです。
画面の通り、ジョブテンプレートでも Execution Environment を指定できます。画面では、自前の Custom EE (2.10)
を指定しています。
ここを空欄にすると、インスタンスやプロジェクトのデフォルトが設定されていればそれが、設定されていなければ組み込みの AWX EE 0.5.0
が自動で設定されます。AWX では、プレイブックの実行には何らかの Execution Environment が必須です。
プレイブックの実行と結果の確認
ジョブテンプレートを保存して実行すると、設定された Execution Environment を利用してプレイブックが実行されます。
今回の例では、出力からは、Ansible のバージョンが 2.10 で、Ansible Builder でのビルド時に指定した追加パッケージが導入された環境であることが確認できます。意図した通りの環境でプレイブックが実行できたようです。
ジョブテンプレートを修正して、今度は Custom EE (2.9)
を指定して再度実行すると、バージョンの変化が見て取れます。
また、ジョブテンプレートで Execution Environment を 空 にして保存すると、AWX 19.2.2 では自動で AWX EE 0.5.0
が指定されます。
そのまま実行すると、結果から、デフォルトの AWX EE 0.5.0
にはあらかじめパブリッククラウド環境などを操作するためのコレクション群やパッケージ群が追加済みであることがわかります。Execution Environment の存在を意識しなくても、ある程度の汎用性がある環境はいつでも使えそうですね。
Kubernetes 上での Execution Environment と Pod の中身
ジョブを実行すると、実行の都度、Execution Environment が Pod として起動し、終了後には削除されます。このため、前回のエントリ でプレイブックを Ansible Runner からコンテナ下で動作させたときと同様、localhost
は Pod それ自体 であり、localhost
に対する作用は揮発的 で、永続化されません。
Pod の作られっぷり
前回 同様、プレイブックの最後に ansible.builtin.pause
を追加して AWX からジョブテンプレートを実行します。
- name: Simply pause for a while
ansible.builtin.pause:
minutes: 10
待ち時間中に Kubernetes の Pod の状態を確認すると、AWX が存在するネームスペースに、ジョブ実行用の Pod が作られていることがわかります。次の例では、automation-job-43-77fgq
です。
$ kubectl -n awx get pod
NAME READY STATUS RESTARTS AGE
awx-postgres-0 1/1 Running 0 2d7h
awx-d85c677df-85wvm 4/4 Running 0 2d7h
automation-job-43-77fgq 1/1 Running 0 81s
定義を確認すると、コンテナのイメージとして AWX から指定した Execution Environment が利用されていることがわかります。また、Credential で登録した認証情報が imagePullSecrets
として渡されていることも確認できます。
$ kubectl -n awx get pod automation-job-43-77fgq -o json | jq .spec
{
"containers": [
{
"args": [
"ansible-runner",
"worker",
"--private-data-dir=/runner"
],
"image": "registry.example.com/ansible/ee:2.10-custom",
...
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "kube-api-access-bxqh5",
"readOnly": true
}
]
}
],
"imagePullSecrets": [
{
"name": "automation-8f2b6-image-pull-secret-4"
}
],
...
}
プレイブックの配置っぷり
ところで、前回 の Docker での実行時は、コンテナの /runner
にホストのディレクトリが直接マウントされていましたが、Kubernetes 上で動作しているこの Pod には、上記出力例のとおりそのようなマウントの定義はありません。
しかしながら、Pod の中でコマンドを実行してみると、確かにプレイブックは存在しています。用意したデモプロジェクトのディレクトリ構造のせいでわかりくいですが、Pod の /runner/project
下に、AWX で指定したプロジェクトの中身が配置されています。
$ kubectl -n awx exec -it automation-job-43-77fgq -- ls -l /runner/project/runner/project
total 4
-rw-r--r--. 1 root root 1058 Jul 20 15:07 demo.yml
Pod の /runner/project
下のプレイブックは、Docker のときとは異なり、永続ボリュームのマウント ではない 方法で Pod 内に配置されていることになります。
Receptor と Ansible Runner の Transmit、Worker、Process
Pod へのプレイブックの配置とその後の実行は、ざっくり次の二つの仕組みやツールにより実現されているようです。
- Ansible Runner のリモートジョブ実行機能
ansible-runner transmit
で、指定されたプレイブックやコマンドライン引数を ZIP で固めて Base64 でエンコードし、標準出力に吐くansible-runner worker
で、transmit
から受け取ったデータを展開し、プレイブックを実行して、結果を標準出力に吐くansible-runner process
で、worker
から結果を受け取って、コールバック(画面出力やログの保存など)を実行する
- Receptor
- 複数のワーカ間でオーバレイネットワークを構成して、データストリームが授受できるようにする
Ansible Runner のリモートジョブ実行機能 は、ドキュメントにも例があるとおり、動作は気軽に確認できます。例えば、transmit
を実行すると、標準出力に JSON で引数やエンコードされた ZIP ファイルが吐かれる動きが観察できます。
$ ansible-runner transmit runner -p demo.yml
{"kwargs": {..."playbook": "demo.yml", ..."container_image": "quay.io/ansible/ansible-runner:devel", ...}
{"zipfile": 2039}
UEsDBBQAAAAIAM9V...AE8BAACSBgAAAAA={"eof": true}
さらにこれにパイプで worker
を加えると、プレイブックの実行結果の生データ(改行区切りの JSON)が流れてきます。
$ ansible-runner transmit runner -p demo.yml | ansible-runner worker
{"status": "starting", ...}
{"status": "running", ...}
...
{..., "stdout": "\r\nTASK [Gathering Facts] *********************************************************", ...}
{..., "stdout": "", ...}
...
大事なのは、worker
はオリジナルのファイルには触れることなくプレイブックを実行 しているということです。オリジナルのファイルを読んだのは transmit
だけ で、worker
との間はただの標準入出力のデータのやりとりです。
さらにこれをパイプして process
で終端すると、見慣れたいつもの出力になります。
$ ansible-runner transmit runner -p demo.yml | ansible-runner worker | ansible-runner process runner
...
TASK [Gathering Facts] *********************************************************
...
AWX でのジョブ実行時も、AWX のインスタンス側とジョブを実行する実際の Pod(Execution Environment)側との間で、ansible-runner
同士のプレイブック一式や結果の授受が行われます。つまり大枠は、
- AWX のインスタンス側でオリジナルのプレイブックを取得(Sync)して、
ansible-runner transmit
(実際はこれに相当する API)を実行(プレイブック一式を ZIP 化してパラメータとともに配信)し - 新しく作られたジョブ用の Pod 側で、
ansible-runner worker
がインスタンス側のtransmit
からプレイブック一式とパラメータを受け取り、Pod 上に展開して実行し worker
の実行結果は AWX のインスタンス側のansible-runner process
(実際は API)が受け取る- AWX のインスタンスとジョブ用の Pod の間のデータは、Receptor のネットワークで流す
な動きで実現されていることになりそうです。実際、前述の Pod の定義の args
からは、ansible-runner
にサブコマンド worker
が渡されていることが観察できます。Pod で動く worker
はオリジナルのファイルを直接読む必要がないので、ボリュームマウントもされていない(実行の都度 transmit
から受け取っているだけ)ということですね。
Container Group による Pod のカスタマイズ
ジョブ用の Pod の定義は、Container Group でカスタマイズできます。Container Group はジョブ用の Pod の動作環境を定義するもので、特に意識しなくてもジョブの実行時にはデフォルトの Container Group である default
が透過的に利用されています。
Container Group は、ユーザが任意で追加できます。Pod 用のマニフェストを直接編集 できるほか、他の Kubernetes や OpenShift のクラスタの認証情報も渡せます。利用する Container Group は ジョブテンプレート単位で指定 できるので、うまく使うと、
- データを永続化する
connection: local
で完結できるプレイブックで、処理したデータを永続ボリューム上に永続化する
- Pod のスケジューリングを制御する
nodeSelector
やaffinity
などを指定して、Pod を特定のノードで起動させる
- Pod のリソースを制限する
resources
のlimits
やrequests
を指定して、CPU やメモリなどの消費を制限する- 別の
namespace
で動作するようにして、ResourceQuota
で制限する
- Pod の動作をモニタリングする
- 別の
namespace
で動作させたり、任意のlabels
を追加したりして、モニタリングのクエリやフィルタに使う
- 別の
- ジョブの処理を別のクラスタにオフロードする
- ジョブ用の Pod を外部のクラスタに作成させ、処理をオフロードする
などなど、いろいろできそうです。
準備
動作をざっくり確認したいので、まずは準備です。
今回は、AWX が動作しているネームスペース awx
とは別に新しいネームスペース ee-demo
を作って、PVC demo-clam
も作成しました。PVC には PV demo-volume
が割り当てられていて、実体には hostPath
で /data/demo
を指定しています。
$ kubectl get ns ee-demo
NAME STATUS AGE
ee-demo Active 4m19s
$ kubectl -n ee-demo get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
demo-claim Bound demo-volume 5Gi RWO demo-volume 4m26s
また、この環境がシングルノードなので実際には無意味ですが、nodeSelector
の定義が活きることも確認したいので、ノードにラベル awx-node-type=demo
も付与しています。
$ kubectl label nodes kuro-awx01.kuro.lab awx-node-type=demo
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
kuro-awx01.kuro.lab Ready control-plane,master 3d7h v1.21.2+k3s1 awx-node-type=demo,...
ネームスペース周りも試したいので、AWX が Pod の実行時に利用するサービスアカウント awx
が、新しいネームスペース ee-demo
も触れるようにしました。ここでは、雑な方法ですが、awx
用に定義されているロールとロールバインディングを、ほぼそのまま新しいネームスペース ee-demo
用に流用して作成しています。kubectl get -o json
して jq
で整形して kubectl create -f
です。
$ kubectl -n awx get role awx -o json | jq '.metadata.namespace="ee-demo" | del(.metadata.ownerReferences)' | kubectl create -f -
$ kubectl -n ee-demo get role
NAME CREATED AT
awx 2021-07-21T15:59:45Z
$ kubectl -n awx get rolebinding awx -o json | jq '.metadata.namespace="ee-demo" | del(.metadata.ownerReferences) | .subjects[0].namespace="awx"' | kubectl create -f -
$ kubectl -n ee-demo describe rolebinding awx
Name: awx
Labels: <none>
Annotations: <none>
Role:
Kind: Role
Name: awx
Subjects:
Kind Name Namespace
---- ---- ---------
ServiceAccount awx awx
Container Group の作成
準備ができたら実践です。Container Group は、メニュの Administration
> Instance Group
から作成できます。
作成画面の Customize pod specification
にチェックを入れると、Pod のマニフェストを編集できるようになるので、今回は、次の点を構成しました。
- ネームスペースを
ee-demo
に変更 - ラベル
app: ee-demo-pod
を追加 - CPU とメモリの
requests
とlimits
を追加 - ボリュームの
/etc/demo
へのマウントを追加 - 動作ノードとして
awx-node-type: demo
を指定
具体的には、以下のマニフェストを指定しています。
apiVersion: v1
kind: Pod
metadata:
namespace: ee-demo
labels:
app: ee-demo-pod
spec:
containers:
- image: 'quay.io/ansible/awx-ee:0.5.0'
name: worker
args:
- ansible-runner
- worker
- '--private-data-dir=/runner'
resources:
requests:
cpu: 500m
memory: 100Mi
limits:
cpu: 1000m
memory: 200Mi
volumeMounts:
- name: demo-volume
mountPath: /etc/demo
nodeSelector:
awx-node-type: demo
volumes:
- name: demo-volume
persistentVolumeClaim:
claimName: demo-claim
image
は変えてもよいですが、プロジェクトやジョブテンプレートの Execution Environment を指定するとオーバライドされるので、ここではデフォルトのままにしています。
なお、この画面の Credential
には、タイプが OpenShift or Kubernetes API Bearer Token
の認証情報を追加できます。今回は空欄にしていますが、外部のクラスタにジョブ用の Pod を作成させたい場合は、ここで指定すると機能するようです(試していません)。
ジョブの実行と結果の確認
ジョブテンプレートの Instance Group
欄で、利用する Container Group を指定できます。
設定を変更してジョブを実行すると、Container Group で定義した通り、ネームスペース ee-demo
に Pod が作成されました。
$ kubectl -n ee-demo get pod
NAME READY STATUS RESTARTS AGE
automation-job-50-qsjbp 1/1 Running 0 17s
定義を確認すると、Container Group に含めたもろもろがきちんと反映されていることがわかります。
$ kubectl -n ee-demo get pod automation-job-50-qsjbp -o yaml
...
metadata:
...
labels:
...
app: ee-demo-pod
...
spec:
containers:
...
image: registry.example.com/ansible/ee:2.10-custom
...
resources:
limits:
cpu: "1"
memory: 200Mi
requests:
cpu: 500m
memory: 100Mi
...
volumeMounts:
- mountPath: /etc/demo
name: demo-volume
...
nodeSelector:
awx-node-type: demo
...
volumes:
- name: demo-volume
persistentVolumeClaim:
claimName: demo-claim
...
Pod の中で /etc/demo
下にファイルを作成させると、実体の PV 内(今回は hostPath
の /data/demo
)でもファイルが確認できました。ジョブが終了、つまり Pod が停止しても、ファイルが残る状態ができています。
$ kubectl -n ee-demo exec -it automation-job-50-qsjbp -- touch /etc/demo/test
$ ls -l /data/demo
total 0
-rw-r--r--. 1 root root 0 Jul 21 12:17 test
楽しいですね。
補足: 事前準備の作業内容
事前準備として紹介した以下のそれぞれを用意する作業のもうちょっと踏み込んだ紹介です。
- Execution Environment
- プライベートコンテナレジストリ
- プライベート Git リポジトリ
- プレイブック(プライベート Git リポジトリ上)
プライベートコンテナレジストリの用意
プライベートコンテナレジストリとして、本来は Private Automation Hub(Galaxy NG)を立てたいところですが、今回はもっと気軽に Docker が提供している registry
で代替しています。素の状態では認証なしかつ HTTP での利用になるため、今回は、次の構成にしました。
- ホスト名は
registry.example.com
- Kubernetes の Ingress で HTTPS を終端(自己署名証明書を利用)
- アクセスには
htpasswd
ベースの認証が必要 - ストレージは PVC で永続化
具体的な構築手順は割愛しますが、デプロイに必要なマニフェスト群と具体的な手順は、GitHub に配置 しています。
なお、紹介した通り、Execution Environment は、AWX 経由で実行すると Kubernetes の Pod として実行されます。つまり、コンテナレジストリに実際にアクセスしてイメージをプルするのは Kubernetes です。
したがって、イメージのプルに認証が必要な場合は、その認証を Kubernetes 側で行えるようにする必要があるわけですが、AWX 側でレジストリの Credential を作って Execution Environment の設定画面で指定しておくと、あとは勝手にやってくれます。具体的には、その Credential をもとに AWX によって Kubernetes 側(の Execution Environment が起動するネームスペース)に .docerconfigjson
を含むシークレットが作成され、Pod に imagePullSecrets
として追加されます。
ただし、レジストリのエンドポイントが自己署名証明書の HTTPS の場合は、SSL の検証を無効にする必要があり、この目的で、前述の手順の末尾では、/etc/rancher/k3s/registries.yaml
を編集しています。
最終的には以下の状態になっています。
$ sudo /usr/local/bin/crictl info | jq .config.registry.configs
{
"registry.example.com": {
"tls": {
"insecure_skip_verify": true,
...
自製 Execution Environment の用意
コンテナレジストリが用意できて動作が確認できたら、利用したい Execution Environment をビルドしてプッシュします。具体的な手順は 前回のエントリ と完全に重複するので、まるっと割愛します。必要な資材と手順は GitHub に配置 しています。
今回は、ベースイメージとして quay.io/ansible/ansible-runner
の stable-2.10-devel
と stable-2.9-devel
を利用し、次の二つの自製 Execution Environment をビルドしてコンテナレジストリに配置しました。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.example.com/ansible/ee 2.10-custom 6fb343319a80 24 hours ago 740MB
registry.example.com/ansible/ee 2.9-custom 050cf7076379 25 hours ago 871MB
$ reg tags -k registry.example.com/ansible/ee
2.10-custom
2.9-custom
reg
コマンドは、コンテナレジストリのコマンドラインクライアント です。前述の コンテナレジストリの構築手順中 に登場しています。今回利用したコンテナレジストリ registry
は Web GUI や CLI がないため、プッシュされたことの確認にこの reg
を使っています。気軽に使えて便利です。
プライベート Git リポジトリの用意
AWX で SCM をプロジェクトのソースにできるように、Git リポジトリを用意します。GitHub や Backlog などのプライベートリポジトリでももちろん構いませんが、今回は、コンテナレジストリ同様、インタネット上に配置したくない場合を想定して、プライベート Git リポジトリとして Gitea を K3s 上に用意しています。必要な資材と手順は GitHub に配置 しています。
今回は、次の構成で用意しました。
- ホスト名は
git.example.com
- Kubernetes の Ingress で HTTPS を終端(自己署名証明書を利用)
- ストレージは PVC で永続化
- RDBMS は SQLite3
用意が面倒であれば、さんざん紹介している GitHub のリポジトリ kurokobo/awx-on-k3s
をそのまま SCM として突っ込んでも大丈夫です。
プレイブックの用意
最後に、AWX から Execution Environment で動かしたいプレイブックを用意します。
この目的では、前回のエントリ で Ansible Runner の動作確認に使ったプレイブックが流用できるので、今回はこのエントリで使っている GitHub のリポジトリ kurokobo/awx-on-k3s
の中身を丸ごとそのまま、Gitea 上に作成した gitea/ee-demo
リポジトリにプッシュしました。
これも用意が面倒であれば、さんざん紹介している GitHub のリポジトリ kurokobo/awx-on-k3s
をそのまま使っても大丈夫です。
Pod からの名前解決の確認
DNS が構成済み(この例では上流で *.example.com
を解決できる)の場合は特に気にしなくてよいですが、/etc/hosts
でがんばっている場合は、AWX、つまり K3s の Pod の中 から K3s ホストの /etc/hosts
を使った名前解決 ができる必要があります。例えば、AWX に SCM として git.example.com
のリポジトリを追加しても、名前解決ができなければ当然 Sync ができません。
この対策の簡単な実装例として、GitHub に dnsmasq
と K3s 用の resolv.conf
を使った設定例 を載せています。最終的には、次のように Pod の中から *.example.com
の名前解決ができる必要があります。
$ cat /etc/hosts
...
192.168.0.100 awx.example.com
192.168.0.100 registry.example.com
192.168.0.100 git.example.com
$ kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup git.example.com
Server: 10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local
Name: git.example.com
Address 1: 192.168.0.100
pod "busybox" deleted
おわりに
AWX 上で自前の Execution Environment が利用できる状態を構成して、実際に動きを確認しました。また、ジョブを実行する Pod を Container Group でカスタマイズできることも併せて確認しました。
AWX の画面からは、かつて存在していた Python の仮想環境に関する設定が消え、Execution Environment に置き換えられている ことも見て取れます。大きなアーキテクチャの変更であり、ユースケースによっては従来通りの使い方ができなくて困る場合も出てくるかもしれませんが、どちらかといえば新しいアーキテクチャに合わせて使い方自体を変えていく方が理想なのだろうとは思います。
個人的には、Kubernetes 上での動作も含め、Ansible のコンテナ化はとてもうれしい流れです。もりもり使っていきたいですね。
Hello Kurokobo, thanks for your blog. I got latest version on AWX installed using awx-on-k3s repo and everything is fine. But I am unable to use custom EE’s I built using your instructions.
The jobs are failing with this error:
Traceback (most recent call last):
File “/usr/local/bin/ansible-runner”, line 5, in
from ansible_runner.__main__ import main
File “/usr/local/lib/python3.8/site-packages/ansible_runner/__main__.py”, line 48, in
VERSION = pkg_resources.require(“ansible_runner”)[0].version
File “/usr/local/lib/python3.8/site-packages/pkg_resources/__init__.py”, line 909, in require
needed = self.resolve(parse_requirements(requirements))
File “/usr/local/lib/python3.8/site-packages/pkg_resources/__init__.py”, line 800, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (pyOpenSSL 22.0.0 (/usr/local/lib/python3.8/site-packages), Requirement.parse(‘pyOpenSSL<20.0.0'), {'ansible-runner'})
Can you let me know what I need to do to fix it?
Thanks
Hi, according to your traceback, the required version for pyOpenSSL is conflicted.
Ansible Builder tries to merge and solve all dependencies from user-defined requirements.txt and requirements.txt from all Collections specified in requirements.yml. If there is a version conflict, an error will result; e.g. in case that Collection A requires latest pyOpenSSL 22.0.0, but Collection B requires pyOpenSSL older than 20.0.0.
If you’ve specified pyOpenSSL in your requirements.txt, this might be cause. I guess you should review your requirements.txt and Collections in requirements.yml.
If you want further investigation, please provide your files to be used to build EE, and full logs. Thanks.
Thanks for your quick response. I did not specify pyOpenSSL in the requirements.txt file.
Here is what I have used to build EE:
root@lxanslab01:~/awx-on-k3s/builder# cat execution-environment.yml
—
version: 1
build_arg_defaults:
EE_BASE_IMAGE: quay.io/ansible/ansible-runner:stable-2.12-latest
ansible_config: ansible.cfg
dependencies:
galaxy: requirements.yml
python: requirements.txt
system: bindep.txt
additional_build_steps:
prepend:
– RUN whoami
– RUN cat /etc/os-release
append:
– RUN echo This is a post-install command!
– RUN ls -la /etc
root@lxanslab01:~/awx-on-k3s/builder# cat requirements.yml
—
collections:
– name: community.general
version: 3.3.2
source: https://galaxy.ansible.com
– name: netapp.ontap
– name: dellemc.openmanage
– name: community.vmware
root@lxanslab01:~/awx-on-k3s/builder# cat requirements.txt
example-pypi-package
omsdk
netapp-lib
python-hpilo
pyvmomi
git+https://github.com/vmware/vsphere-automation-sdk-python.git
root@lxanslab01:~/awx-on-k3s/builder# cat bindep.txt
bind-utils
If you want to check I have it on this repo:
quay.io/mumohamm/new-awx-ee:latest
I just tested and the EE works on Tower but throwing that error on AWX I setup using your awx-on-k3s. So do I need to add something for Custom EE’s to work? Btw I have this setup on Ubuntu 20.04.
Ah sorry for my misunderstanding that the error occurs during build process. Now I understand that the error occurs during runtime of the Job on AWX.
So the same issue is already reported on ansible-runner repository, but there is no solution yet; see https://github.com/ansible/ansible-runner/issues/1138
I’ve made quick investigation, it seems a bit complicated. The root cause is the recent update of vsphere-automation-sdk-python. Similar issue has been occured in GitHub Actions in awx-ee repository, so I’ve made new issue and dirty workaround there: https://github.com/ansible/awx-ee/issues/137#issuecomment-1264596725
Therefore, your choices are:
– Just wait for the issue to be resolved in upstream
– Instead of running `ansible-builder build`, run `ansible-builder create` first, modify `Dockerfile` as described in my comment on GitHub, and then run `docker build`
If you have further information to patch Dockerfile, please let me know.
Thanks Kurokobo, I was able to follow your steps in https://github.com/ansible/awx-ee/issues/137 and was able to fix the issue.