見出し画像

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

★公式ブロガー水谷の執筆記事一覧


執筆者プロフィール:水谷 裕一
大手外資系IT企業で15年間テストエンジニアとして、多数のプロジェクトでテストの自動化作業を経験。その後画像処理系ベンチャーを経てSHIFTに入社。
SHIFTグループ会社「RGA」および「システムアイ」に出向し、インフラ構築の自動化やCI/CD、コンテナ関連の業務に従事した後、2024年3月よりSHIFTのインフラサービスGに配属。
LinuxよりWindowsの方が好き。


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/

PHOTO:UnsplashVisax