AWX(19.3.0) on ARM64(Raspberry Pi)

# はじめに
以前に書いた記事[1](https://qiita.com/ussvgr/items/f95d950bf39aa67d0189)・[2](https://qiita.com/ussvgr/items/230b1436f604ae16dddf)からかなり変化があったので、自分用メモとして。

# 環境
コンテナイメージビルド環境：Ubuntu Server 20.04 LTS (AWS EC2 m6g.xlarge 16GB汎用SSD)
実行環境：Ubuntu Server 20.04 LTS (Raspberry Pi 4B 4GB) + k3s v1.21.3+k3s1

# 依存イメージビルド
AWX, AWX EE, AWX Operatorのビルドに必要となる、依存関係のイメージを先にビルドしていきます。

ビルド用環境にログインして、必要なパッケージをインストールします。

```bash
$ sudo apt update
$ sudo apt install docker.io python3-docker ansible unzip make tox
```

Dockerサービスの起動とDockerグループへのユーザー追加をして、一度ログアウトし再ログインします。

```bash
$ sudo systemctl start docker.service
$ sudo gpasswd -a $USER docker
$ exit
```

### python-base
```bash
$ cd ~/
$ git clone https://github.com/ansible/python-base-image.git
$ cd python-base-image/
$ docker build --rm=true -t quay.io/ansible/python-base -f Containerfile .
```

### python-builder
```bash
$ cd ~/
$ git clone https://github.com/ansible/python-builder-image.git
$ cd python-builder-image/
$ docker build --rm=true -t quay.io/ansible/python-builder -f Containerfile .
```

### ansible-runner
```bash
$ cd ~/
$ git clone https://github.com/ansible/ansible-runner.git
$ cd ansible-runner/
$ make image
```

### receptor
```bash
$ cd ~/
$ git clone -b 1.0.0a2 https://github.com/ansible/receptor.git
$ cd receptor/packaging/container
$ tar --exclude-vcs-ignores -czf source.tar.gz ../../
```
必要なのはコンテナ内のバイナリのみなので、ちょっと手抜きしたDockerfileを用意。

```Dockerfile:Dockerfile
FROM fedora:32 as builder

RUN dnf -y update && dnf install -y golang make

ADD source.tar.gz /source
WORKDIR /source
RUN make
RUN cp /source/receptor /usr/bin/receptor
```
```bash
$ docker build --rm=true -t quay.io/project-receptor/receptor:1.0.0a2 .
```

### ansible-builder
```bash
$ cd ~/
$ git clone https://github.com/ansible/ansible-builder.git
$ docker build --rm=true -t quay.io/ansible/ansible-builder -f Containerfile .
```

# 実行イメージビルド
ここからがAWXの実行に必要となる本体たちのイメージビルドです。
### docker login
プッシュ先のレジストリにログインします。
今回は[Amazon Elastic Container Registry](https://aws.amazon.com/jp/ecr/)　を利用します。
あらかじめビルド用インスタンスにECR操作用のIAMロールを付与しておき、

```bash
$ cd ~/
$ wget https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip
$ unzip awscli-exe-linux-aarch64.zip 
$ sudo ./install 
$ /usr/local/bin/aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
```
で準備完了です。

### awx-ee
```bash
$ cd ~/
$ git clone -b 0.6.0 https://github.com/ansible/awx-ee.git
```
そのままだとPyNaClのビルドに失敗するのでちょっと手を加えます。

```bash
$ vi _build/bindep.txt
```

```diff
--- _build/bindep.txt.org	2021-08-15 12:00:22.552381068 +0000
+++ _build/bindep.txt	2021-08-15 12:01:20.275792752 +0000
@@ -2,3 +2,4 @@ python38-devel [platform:rpm compile]
 subversion [platform:rpm]
 subversion [platform:dpkg]
 git-lfs [platform:rpm]
+make [platform:rpm]
```
１行加えたらtoxでイメージビルドして、

```bash
$ tox -e docker -- --tag=public.ecr.aws/ussvgr/awx-ee:0.6.0
```
レジストリにPushします。

```bash
$ docker push public.ecr.aws/ussvgr/awx-ee:0.6.0
```

### awx-operator
イメージビルドとレジストリへのPushをいっぺんにやってくれるPlaybookがあるので、それを利用します。

```bash
$ cd ~/
$ git clone -b 0.13.0 https://github.com/ansible/awx-operator.git
$ cd awx-operator/
$ ansible-playbook -e operator_image=public.ecr.aws/ussvgr/awx-operator -e push_image=true ansible/build-and-push.yml
```

### awx
```bash
$ cd ~/
$ git clone -b 19.3.0 https://github.com/ansible/awx.git
$ cd awx/
```
リポジトリの情報を記載したinventoryファイルを作ります。

```text:inventory
[all:vars]
awx_image=awx
docker_registry=public.ecr.aws
docker_registry_repository=ussvgr
```
inventoryファイルを指定して以下のようにansible-playbookコマンドを実行するとイメージビルド＋Pushまで行ってくれます。

```bash
$ ansible-playbook -i inventory tools/ansible/build.yml
```
ここまで完了すれば、ビルド用のインスタンスはお役御免です。

# AWX Operatorのデプロイ
ここからの作業はRaspberry Pi上のUbuntuで行います。
k3sが既にインストールされてる状態からスタートします。

Operatorのデプロイ用ファイルをダウンロードします。

```bash
$ wget https://raw.githubusercontent.com/ansible/awx-operator/0.13.0/deploy/awx-operator.yaml
```
イメージの取得元を置き換えます。

```bash
$ sed -i -e 's/quay.io\/ansible/public.ecr.aws\/ussvgr/g' awx-operator.yaml
```
デプロイします。

```bash
$ kubectl apply -f awx-operator.yaml
customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com created
clusterrole.rbac.authorization.k8s.io/awx-operator created
clusterrolebinding.rbac.authorization.k8s.io/awx-operator created
serviceaccount/awx-operator created
deployment.apps/awx-operator created
```
しばらく待って、ステータスがRunningになってること、ログに特にエラーが出てないことを確認します。

```bash
$ kubectl get pod 
NAME                            READY   STATUS    RESTARTS   AGE
awx-operator-6d57f57987-d2w5p   1/1     Running   0          2m15s
$ kubectl logs awx-operator-6d57f57987-d2w5p
{"level":"info","ts":1629035207.96095,"logger":"cmd","msg":"Go Version: go1.13.15"}
{"level":"info","ts":1629035207.9610782,"logger":"cmd","msg":"Go OS/Arch: linux/arm64"}
{"level":"info","ts":1629035207.9611087,"logger":"cmd","msg":"Version of ansible-operator: v0.19.4"}
{"level":"info","ts":1629035207.9611773,"logger":"cmd","msg":"Git commit of ansible-operator: 125d0dfcc71fef4f9d7e2a42b1354cb79ffdee03"}
{"level":"info","ts":1629035207.96537,"logger":"cmd","msg":"Watching all namespaces.","Namespace":""}
...
```

# AWXのデプロイ
今回はAWX用のnamespaceとして「awx」を利用します。

```bash
$ kubectl create ns awx
namespace/awx created
```
デプロイ用のファイルを以下のように準備します。

```awx.yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
  namespace: awx
spec:
  service_type: NodePort
  postgres_resource_requirements:
    requests:
      cpu: 500m
      memory: 0.5Gi
    limits:
      cpu: 500m
      memory: 0.5Gi
  postgres_storage_requirements:
    requests:
      storage: 8Gi
    limits:
      storage: 16Gi
  postgres_storage_class: local-path
  image: public.ecr.aws/ussvgr/awx
  image_version: 19.3.0
  image_pull_policy: Always
  control_plane_ee_image: public.ecr.aws/ussvgr/awx-ee:0.6.0
  web_resource_requirements:
    requests:
      cpu: 200m
      memory: 0.5Gi
    limits:
      cpu: 1000m
      memory: 1Gi
  task_resource_requirements:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 1000m
      memory: 1.5Gi
```
デプロイします。

```bash
$ kubectl apply -f awx.yaml 
awx.awx.ansible.com/awx created
```
しばらくして、Podの状態がRunningになればOKです。※

```bash
$ kubectl get pod -n awx
NAME                  READY   STATUS    RESTARTS   AGE
awx-postgres-0        1/1     Running   0          99s
awx-99f6cf47d-m2zhd   4/4     Running   0          83s
```

※AWX Operator 0.13.0とk3s(local-path-provisioner)の組み合わせで、PermissionのエラーでPostgreSQLが起動しない問題がある模様。
[Managed postgres - /var/lib/postgresql/data: permission denied](https://github.com/ansible/awx-operator/issues/483)
力技で以下のように解決させたけど、良い子はマネしないように。

```bash
$ sudo chown 999:root -R /var/lib/rancher/k3s/storage/pvc-hogefuga_awx_postgres-awx-postgres-0/
```

# アクセスしてみる
今回はNodePortでデプロイしたので、ポート番号を確認します。

```bash
$ kubectl get svc -n awx
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
awx-postgres   ClusterIP   None           <none>        5432/TCP       22m
awx-service    NodePort    10.43.67.151   <none>        80:32396/TCP   21m
```
上記例だと「32396」なので、ブラウザで「http://<Raspberry PiのIPアドレス>:32396」にアクセスします。

![スクリーンショット 2021-08-16 1.22.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/01f22d8e-31b8-22ac-fe86-361d75de0978.png)

ユーザー名は「admin」、パスワードは以下のコマンドで確認します。

```bash
$ kubectl get secret awx-admin-password -n awx -o jsonpath="{.data.password}" | base64 --decode
```
ログインすると以下の画面に遷移します。

![スクリーンショット 2021-08-16 1.24.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/bcc02732-c780-e1bd-d637-5d963812ca76.png)

# 動作を試してみる
左メニューの「インベントリー」から「Demo Inventory」をクリック。
![スクリーンショット 2021-08-16 1.28.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/5c1d674f-bf9b-ac69-7a94-6ee53bb76357.png)

上の「ホスト」へ移動し「localhost」にチェックを付け「コマンドの実行」を押下。
![スクリーンショット 2021-08-16 1.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/a7414830-2707-89ab-e9fb-40ea365465e7.png)

モジュールで「ping」を選び「次へ」、
![スクリーンショット 2021-08-16 1.31.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/9ad566c2-30a4-4896-9a45-bf4db9afefe1.png)

実行環境で「Control Plane Execution Environment」を選択し「次へ」、
![スクリーンショット 2021-08-16 1.32.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/c04e41d0-3900-a087-9564-476f5006bcb1.png)

認証情報で「Demo Credential」を選択し「次へ」、
![スクリーンショット 2021-08-16 1.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/f72f6e21-a56a-5e3f-8588-90eadc62f5dd.png)

プレビュー画面から「起動」をクリックします。
![スクリーンショット 2021-08-16 1.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/fda0c44e-36dd-3351-574b-867d3bdd2c8b.png)

無事SUCCESSしてればオッケー！
![スクリーンショット 2021-08-16 1.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274613/f051a383-94b1-6ebc-af5e-1e44368243af.png)

ちなみに「実行環境」の「AWX EE (latest)」はx64環境用のものなので、これを選択すると動きません。注意。

#おわりに
余ってるラズパイあったらAnsibleで遊びましょ。