WSL Ubuntu上にK3sを入れてAWXをインストールするPlaybookを作る
はじめに
こんにちは、株式会社SHIFT ITソリューション部の水谷です。
構成管理ツールであるAnsibleは、コマンドラインで実行するツールとして作られているのですが、Ansibleを実行するためのWeb UIもあります。Red Hatが提供するAnsible Automation Platform(AAP)と、そのアップストリーム版のAWXがそれに該当します。
AAPはサブスクリプション契約が必要ではありますが、Red Hatからサポートが得られるので、本格的な運用に向いており、一方のAWXはオープンソースで開発が進められているもので、トラブルが発生しても自分で解決していく必要がありますが、無料で使用できます。
本ブログは、後者AWXのインストールに関する話になります。
さて、ご存じの方もいらっしゃるかと思いますが、少し前のバージョンのAWXはDocker Composeを使ってコンテナで動かしていたのですが、最近のAWXは、Kubernetes上のオペレーターとしてインストールすることが基本となっています。
私はこの変更に気づいてはいたものの、「ちょっと大変そうだなぁ」という思い込み(?)から、Kubernetes環境に対するAWXのインストールは試したことがありませんでした。
最近少し時間に余裕ができたので、「いっちょ試してみようか」と思い立ち、WSL上のUbuntuでも使用できる軽量版Kubernetesの1つであるK3sを使ってAWXをインストールするPlaybookを作ってみました。本ブログではその様子を書いてみたいと思います。
また、まっさらのWindows(あるいはWindows Server)に、Ubuntuをインストールするところから、AWXに外部PCからアクセスできるにようにするまで、一括で実行するPlaybookも合わせて作ってみましたので、合わせて紹介したいと思います。
※Playbookは https://github.com/yumizu11/k3s_awx に置いてありますので、ご参照ください。
WSL Ubuntu上にk3sとAWXをインストールするPlaybook
まずは、WSL上にUbuntuがすでにインストールされている状況で、その中で実行することを想定した(localhostをマネージドホストとする)、K3sとAWXをインストールするPlyabookを作ります。
今回Kubernetes環境として使うK3sは、インストールがとても簡単なことが1つの特徴ですね。具体的には、インストールスクリプトファイルをダウンロードして、それを実行するだけです。
コマンドラインでは以下のようになります。
curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
これをこのままcommandモジュールで実行しても良いのですが、エラーが起きた時にダウンロードで失敗したのか、インストールに失敗したのかわかりにくくなるので、別タスクにしようと思います。
- name: Create a work directory
ansible.builtin.tempfile:
state: directory
suffix: awx
register: workdir
- name: Download K3s install script
ansible.builtin.uri:
url: https://get.k3s.io
dest: "{{ workdir.path }}/k3s.sh"
mode: 0766
- name: Install k3s
ansible.builtin.shell:
"{{ workdir.path }}/k3s.sh --write-kubeconfig-mode 644"
become: true
これで、kubenetesのノード1つが作られ、kubectlコマンドも使える状態になります(超便利!)。
なお、作業用ディレクトリをtempfileモジュールで作っていますが、これはこのまま消さずにAWXのインストールにも使用することにします。
続いて、AWXのインストールですが、その手順はオフィシャルのドキュメント に書かれてますし、インターネットを検索すれば日本語で書かれた手順も見つかります。それらを参考にさせていただき、実装していきます。
まずはAWX Operatorのデプロイを行うのですが、これは小さな kustomization.yaml を作成してapplyすることで簡単にできるようになっていました。
ここではAWX Operatorのバージョンとデプロイ先の namespace が指定できるよう、下のようなjinja2 templateを作成し、templatesディレクトリに保存しておきます。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# Find the latest tag here: https://github.com/ansible/awx-operator/releases
- github.com/ansible/awx-operator/config/default?ref={{ awx_version }}
# Set the image tags to match the git version from above
images:
- name: quay.io/ansible/awx-operator
newTag: {{ awx_version }}
# Specify a custom namespace in which to install AWX
namespace: {{ awx_namespace }}
あとはこれを kubectl apply -k コマンドでApplyすればよいのですが、ここでもcommandモジュールは使わず、(学習もかねて)kubernetes.coreコレクションにあるモジュールを使うことにしました。
なお、コレクションのインストールは以下のコマンドでできます。
ansible-galaxy collection install kubernetes.core
また、このコレクション内のモジュールは python3-kubernetes を使用しますので、これをインストールするタスクも書いておきます。
- name: Install python3-kubernetes
ansible.builtin.apt:
name: python3-kubernetes
become: true
あとは、以下の2つのタスクでAWX Operatorのデプロイができてしまいます!
- name: Copy kustomization template file
ansible.builtin.template:
src: templates/kustomization.j2
dest: "{{ workdir.path }}/kustomization.yaml"
mode: 0666
- name: Apply manifest with kustomization
kubernetes.core.k8s:
definition: "{{ lookup('kubernetes.core.kustomize', binary_path='/usr/local/bin/kubectl', dir=workdir.path) }}"
kubeconfig: /etc/rancher/k3s/k3s.yaml
wait: true
具体的には、1つ目のタスクでjinja2 templateを適用してワークディレクトリに kustomization.yaml を配置し、2つ目のタスクでApplyしています。
この際、kubernetes.core.kustomize というlookupプラグインを使うとkustomizeの実行ができるようです(これはかなり便利!)。あと、K3sでは、~/.kube/configファイルは作られない(?)ようなので、kubeconfigパラメーターに、config情報が書かれている/etc/rancher/k3s/k3s.yamlを指定しています。
次は、AWXカスタムリソースをデプロイなのですが、こちらもjinja2 templateを使って、下のように書きました(ファイル名はawx.j2)。
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: {{ awx_metadata_name }}
spec:
service_type: nodeport
nodeport_port: {{ awx_http_port }}
サービスタイプはnodeportにして、ポートは変数で指定できるようにしました。
またmetadataのnameも変数で指定できるようにしました。こちらの値がPod名のプレフィックスとしても使われます。
- name: Copy AWX custom resource template file
ansible.builtin.template:
src: templates/awx.j2
dest: "{{ workdir.path }}/awx.yaml"
mode: 0666
- name: Apply AWX custom resource
kubernetes.core.k8s:
definition: "{{ lookup('file', workdir.path + '/awx.yaml') | from_yaml }}"
namespace: "{{ awx_namespace }}"
kubeconfig: /etc/rancher/k3s/k3s.yaml
wait: true
これでAWXの各Podが立ち上がるはずです。
あとは、Adminユーザーのパスワードの取得を行って終了なのですが、AdminパスワードはSecretリソースの中にあるので、それを取り出します。kubernetes.coreコレクションには、kubernetes.core.k8s_infoというモジュールがあり、これを使うと各種リソースの情報を取ってきてくれるようです。
nameが<metadata.name>-admin-passwordのSecretを取ってくるのですが、パスワード自体は .data.password にBase64でエンコードされた形で存在しますので、これをデコードして取得します。
今回は、IPアドレスやポート番号などの情報も合わせて1つのYAMLファイルの形で保存することにしました。
- name: Get admin password
kubernetes.core.k8s_info:
kind: Secret
name: "{{ awx_metadata_name }}-admin-password"
namespace: "{{ awx_namespace }}"
kubeconfig: /etc/rancher/k3s/k3s.yaml
wait: true
register: secret_object
- name: Create AWX Info param
ansible.builtin.set_fact:
awx_info:
ip_address: "{{ ansible_eth0.ipv4.address }}"
port: "{{ awx_http_port }}"
url: "http://{{ ansible_eth0.ipv4.address }}:{{ awx_http_port }}"
admin_user: admin
admin_password: "{{ secret_object.resources[0].data.password | b64decode }}"
- name: Write AWX Info to a file
ansible.builtin.copy:
content: "---\n{{ awx_info | to_nice_yaml }}"
dest: ~/awxinfo.yml
mode: 0444
ブラウザからこのファイルに書かれているURLにアクセスしてみると、AWXのログイン画面が表示されました。
※PCの性能に寄りますが、すべてのPodが立ち上がるまでに5~10分程度かかりますので、表示されなかった場合はしばらくしてからアクセスしてください(Podの状態はkubectl get pod -n awxで確認)。
Ubuntuのインストールから外部公開までを自動化するPlaybook
少し前の記事 で、WSLにUbuntuなどのディストリビューションをインストールするコレクションを作ったので、これと組み合わせて、まっさらのWindowsにUbuntu 24.04をインストールし、先ほどのPlaybookでAWXをインストールし、さらにポートフォワーディングの設定を行って、外部からアクセスできるようにしてみます。
※WSLを操作するコレクションのインストールは以下のコマンドでできます。
ansible-galaxy collection install yumizu11.wsl
まず、Ubuntuのインストールですが、以下の2タスクでできます。
- name: Update WSL
yumizu11.wsl.wsl:
state: updated
become: true
- name: Install Ubuntu-24.04
yumizu11.wsl.distribution:
name: Ubuntu-24.04
is_default: true
default_user: "{{ ubuntu_default_user }}"
run_cmd:
- add-apt-repository ppa:ansible/ansible -y
- apt update
- apt upgrade -y
- apt install ansible -y
state: installed
register: install_result
1つめのタスクで、WSLを最新のものアップデートし、2つ目でUbuntu 24.04をインストールしています。
この際、ubuntu_default_userで指定したユーザーを作成し、これをデフォルトユーザーとします。また、最新のAnsibleをUbuntu上にインストールしています。
続いて、tempディレクトリを作成し(欲を言えば win_tempfile モジュールを使った方が良いのですが、簡単のため)、上で作ったPlaybookとtemplateファイルをコピーします。
- name: Create temp directory
ansible.windows.win_file:
path: C:\temp
state: directory
- name: Copy awx install playbook
ansible.windows.win_copy:
src: awx.yml
dest: C:\temp\awx.yml
- name: Copy template files
ansible.windows.win_copy:
src: templates
dest: C:\temp\
そして、wslコマンドを使い、Ubuntu 24.04上でそのPlaybookを実行します(PlaybookからPlaybookを実行する形で、ややトリッキーですが)。
- name: Install AWX on Ubuntu-24.04
ansible.windows.win_command:
'wsl -d Ubuntu-24.04 -- ansible-playbook /mnt/c/temp/awx.yml'
Playbookの実行が完了すると、~/awxinfo.yml が生成されているはずなので、これを回収します。
- name: Get AWX Info
ansible.windows.win_command:
"wsl -d Ubuntu-24.04 -- cat ~/awxinfo.yml"
register: cat_result
- name: Set awx_info param
ansible.builtin.set_fact:
awx_info: "{{ cat_result.stdout | from_yaml |
combine({'external_url': 'http://' + ansible_host + ':' + (awx_listen_port | string) }) }}"
- name: Show awx_info
ansible.builtin.debug:
var: awx_info
あとは、netshコマンドでポートフォワーディングし、そのポートに外からアクセスできるようFirewallのルールを追加して完了です。
- name: Set up port forwarding
ansible.windows.win_command:
"netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport={{ awx_listen_port }} connectaddress={{ awx_info.ip_address }} connectport={{ awx_info.port }}"
- name: Add firewall rule to allow access to AWX Web UI
community.windows.win_firewall_rule:
name: AWX Web UI
localport: "{{ awx_listen_port }}"
action: allow
direction: in
protocol: tcp
state: present
enabled: yes
★公式ブロガー水谷の執筆記事一覧
IaC支援サービスのご紹介
SHIFTではTerraformやCDKを使ったクラウドインフラ構築の自動化や、Ansibleを使ったサーバOSの設定自動化や構成管理のご支援も行っております。ご依頼・ご相談は下記リンクからお願いします。
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/