はじめに
AWX(Ansible TowerのOSS版)を運用している現場で、docker-compose構成からKubernetesネイティブ構成へのアップグレードを行いました。
AWX 18以降、公式のインストール方法がdocker-composeからAWX Operator(Kubernetes)に完全移行しています。しかし「K8sの知見がないチームでどうやって移行するか」という情報は意外と少ないです。
本記事では、K3s(軽量K8s)+ Kustomize + Argo CDによるGitOps基盤を構築し、AWXのバージョンアップを「Gitのタグ書き換え→push」で完結させる運用を実現した事例を紹介します。
こんな方に刺さる記事です
- AWXをdocker-composeで運用しているが、公式がK8s移行を推奨していて困っている
- EKSは大げさだが、AWXのためだけにK8sを導入する最小構成を知りたい
- Ansible Playbookの実行基盤をGitOps化して、バージョンアップや設定変更をコード管理したい
- AWX Operatorの導入事例を探している
移行前の課題
旧AWX(docker-compose構成)には以下の課題がありました。
- Redisの不安定さ: コンテナ内のRedisが長時間ジョブ(30分超)で不安定にクラッシュし、ジョブが失敗。手動再実行が常態化
- セキュリティ: DBのユーザ/パスがdocker-compose.ymlにベタ書き
- バージョンアップの困難さ: docker-compose→K8sへのアーキテクチャ変更を含むため、手順が複雑で着手できない状態が続いていた
アーキテクチャ設計
なぜK3sか(EKSではなく)
| 選択肢 | メリット | デメリット | 判断 |
|---|---|---|---|
| EKS | マネージド、スケーラブル | コスト高(月$70〜)、AWXの利用規模に対してオーバースペック | ❌ |
| K3s | 単一EC2で完結、軽量、コスト最小 | 自前管理が必要 | ✅ |
AWXの利用状況(同時2〜3ジョブ程度)を考慮し、t4g.large(2vCPU/8GiB)1台にK3sを載せる最小構成を選択しました。
失敗談: 当初はzRAMでメモリスパイクを吸収する設計を試みましたが、実際にはzRAMが効く前にOOM Killerが発動してPodが死ぬため実用性がありませんでした。K8sのリソースリミットとzRAMの相性は悪く、素直にインスタンスタイプを上げる方が確実です。
全体構成
┌───────────────────────────────────────────────┐
│ EC2 (t4g.large) │
│ │
│ ┌─────────────── K3s ──────────────────────┐ │
│ │ │ │
│ │ ┌───────────┐ ┌──────────────────┐ │ │
│ │ │ Argo CD │────▶│ Kustomize │ │ │
│ │ │ (管理Pod) │ │ base/ + overlays│ │ │
│ │ └───────────┘ └────────┬─────────┘ │ │
│ │ │ │ │
│ │ ┌────────▼─────────┐ │ │
│ │ │ AWX Operator │ │ │
│ │ │ + AWX Pods │ │ │
│ │ │ (web/task/ee) │ │ │
│ │ └──────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────┘
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ RDS │ │ Secrets │
│(Postgres)│ │ Manager │
└──────────┘ └──────────┘
Argo CDがGitリポジトリを監視し、Kustomize overlayを適用してAWX Operator + AWX Podsをデプロイします。Argo CD自体はK3sに直接インストールされた管理Podです。
Kustomize overlay構成
awx-platform/
├── base/
│ ├── kustomization.yaml # AWX Operatorの参照
│ ├── cluster-secret-store.yaml
│ └── headlamp.yaml
├── overlays/
│ ├── dev/
│ │ ├── kustomization.yaml
│ │ ├── awx.yaml # AWXカスタムリソース(環境固有)
│ │ └── external-secret.yaml
│ ├── stg/
│ └── prd/
└── argocd/
├── app-dev.yaml
├── app-stg.yaml
├── app-prd.yaml
└── notifications.yaml
base/kustomization.yaml でAWX Operatorのバージョンを一元管理:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- github.com/ansible/awx-operator/config/default?ref=2.19.1
images:
- name: quay.io/ansible/awx-operator
newTag: 2.19.1
バージョンアップ時は ref=2.19.1 と newTag: 2.19.1 を書き換えてpushするだけ。Argo CDが差分を検知して自動的にSyncします。
実装のポイント
1. Argo CDによるGitOpsデプロイ
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: awx-dev
namespace: argocd
spec:
source:
repoURL: git@bitbucket.org:your-org/awx-platform.git
targetRevision: main
path: overlays/dev
destination:
server: https://kubernetes.default.svc
namespace: awx
syncPolicy:
automated:
prune: true
selfHeal: true
syncPolicy.automated により、Gitにpushされた変更が自動的にクラスタに反映されます。手動でのkubectl applyは不要。
2. External Secrets Operatorによるシークレット管理
旧構成ではDBパスワードがdocker-compose.ymlにベタ書きでしたが、AWS Secrets Managerに移行し、External Secrets Operatorで自動同期しています。
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: awx-postgres-configuration
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: awx-postgres-configuration
data:
- secretKey: host
remoteRef:
key: awx/postgres
property: host
- secretKey: password
remoteRef:
key: awx/postgres
property: password
# ... 他のフィールド
これにより、シークレットがGitリポジトリに一切含まれない構成を実現。
3. Argo CD Notificationsによる監視
Sync失敗やHealth Degradedを即座にSlackに通知:
trigger.on-health-degraded: |
- when: app.status.health.status == 'Degraded'
send: [app-health-degraded]
trigger.on-sync-failed: |
- when: app.status.operationState.phase in ['Error', 'Failed']
send: [app-sync-failed]
旧AWXは「構築して放置」されていたため、新基盤では「インフラチームのプロダクト」として死活監視を組み込みました。
4. DevContainer + Ansible-lintによる品質担保
// .devcontainer/devcontainer.json
{
"name": "AWX Platform Dev",
// ... DevContainer設定
}
- DevContainerにより「ローカルでは動くがリモートでは動かない」問題を根絶
- PRベースでAnsible-lintが自動実行され、Playbook品質を担保
バージョンアップの運用フロー
Before(旧docker-compose構成):
実質的にアップデート不可能な状態でした。
- docker-compose.ymlで全ての設定が静的に管理されているわけではなく、コンテナ起動後に手動でGUI/APIから設定変更が必要な部分が多数存在
- 「どの設定を手動で変えたか」の記録がなく、再現性がゼロ
- アップデートすると手動設定が消えるため、事実上バージョン固定で塩漬け運用
つまり「バージョンアップの手順が複雑」以前に、現状の構成を再現する手段がないという根本的な問題がありました。
After(GitOps構成):
-
base/kustomization.yamlのタグを書き換える - PRを出す → Ansible-lintが自動チェック
- マージする → Argo CDが自動Sync
- Slack通知で成功/失敗を確認
SSHログイン不要、手順書不要、切り戻しはgit revert。
全ての設定がKustomize manifests + AWXカスタムリソース + External Secretsとしてコード化されているため、環境の完全な再現が保証されています。
成果
- ジョブ成功率の劇的向上: Redis不安定によるジョブ失敗を撲滅
- バージョンアップの工数: 数時間の手作業 → Gitのタグ書き換え(数分)
- 属人化の解消: ブラックボックスだった構成を全てコード管理下に
- 3環境の再現性: dev/stg/prdをKustomize overlayで管理。1環境あたり半日で構築可能
まとめ
- AWXのdocker-compose→K8s移行は、K3sを使えば単一EC2で完結する
- Argo CD + Kustomize overlayにより、バージョンアップがGit操作で完結するGitOps運用を実現
- External Secrets OperatorでシークレットをGitから排除し、セキュリティを担保
- Argo CD Notificationsで監視を組み込み、「構築して放置」を防止
AWXをdocker-composeで運用していて移行に悩んでいる方の参考になれば幸いです。