概要
AWX Operatorは、Ansible Towerのオープンソース版であるAWXをKubernetes環境で簡単に管理・運用できる便利なツールですが、ユーザー認証を効率化するためにはSSO(シングルサインオン)の導入が効果的です。
本記事では、Kubernetes上にデプロイしたAWX OperatorのDashboardに、Azure ADを利用してSSO(シングルサインオン)認証を設定する方法を解説します。
利用環境
- Amazon EKS:v1.29
- AWX Operator: v2.10.0
構成図
今回の設定で実現する構成の全体像を示します。
以下は筆者の担当システム構成となりますので、参考までの情報としてご参照ください。
下図では、AWX OperatorがKubernetes上にデプロイされ、Azure ADを使用してSSO認証を行う仕組みを示しています。
接続の流れ
ユーザーがSSO認証を行ってログインするまでの流れを示すと、以下の通りとなります。
- ユーザーがAWX Operator Dashboardにアクセス
- Ingressコントローラーがリクエストを受け取る
- AWX OperatorがAzure ADにリダイレクト
- 既存のセッションを確認し認証(必要に応じて再認証)
- Azure ADが認証トークンを発行
- Azure ADがAWXにリダイレクト
- AWX Operatorが認証トークンを検証
- ユーザーがAWX Operator Dashboardにログイン
事前準備
設定を進める前に、以下の準備を完了させておく必要があります。
詳細な手順は割愛しますが、必要に応じて関連資料をご参照ください。
- DNSゾーンとドメインの設定
- DNSレコードの登録
- SSL証明書の用意
AWX Operator × Azure ADのセットアップ
以下の流れで、AWX OperatorのDashboardにAzure ADを使用したSSOを設定します。
01. App Registrationsへアプリケーションの登録(Azure AD)
公式ドキュメントを参考にAzure ADのApp Registrationsへアプリケーションを登録、SSOグループの作成を行います。
02. IngressおよびExternal DNS設定追加(Kubernetes環境)
External DNS設定追加
AWX OperatorのIngress設定を構成する際には、DNSの自動登録を行うためにExternal DNSの設定も併せて行います。External DNSは、Kubernetesリソース(IngressやServiceなど)を基にDNSレコードを自動的に管理してくれるツールであり、AWS Route 53などのDNSプロバイダーと統合することが可能です。
以下はExternal DNSの設定例です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: k8s.gcr.io/external-dns/external-dns:v0.13.2 # ExternalDNSの公式イメージを指定
args:
- --source=service
- --source=ingress
- --domain-filter=<ドメイン名> # 管理対象のドメイン名を指定
- --provider=aws # 使用するDNSプロバイダー(この例ではAWS Route 53)
- --policy=upsert-only # DNSレコードの削除を防ぎ、作成と更新のみを許可
- --aws-zone-type=public # パブリックホストゾーンのみ操作
- --registry=txt # TXTレコードを使用して競合を防止
- --txt-owner-id=xxxx # DNSレコードの所有者を識別するID
- --txt-prefix=%{record_type}-record. # TXTレコードに付加するプレフィックス
resources:
limits:
cpu: 100m
memory: 300Mi
設定のポイント
-
--provider=aws
:- AWS Route 53をDNSプロバイダーとして使用する場合に指定します。
-
--policy=upsert-only
:- AWSリソースの削除を防ぐ安全設定。
-
--txt-owner-id=xxxx
:- 管理対象レコードを追跡する識別子。複数インスタンス運用時に必須
-
--txt-prefix=%{record_type}-record.
:- 命名規則をカスタマイズする場合に使用(任意)
External DNSを設定することで、Kubernetesリソースの変更に応じてDNSレコードが自動的に更新され、手動での設定が不要になります。
後述するIngressのexternal-dns.alpha.kubernetes.io/hostname
アノテーションと組み合わせて使用することで、より柔軟な運用が可能になります。
Ingressの構成
AWX Operatorが提供するCRD(Custom Resource Definition)設定の一部として、Ingressの構成を行います。公式ドキュメントによれば、ingress_annotations
を利用することで、ALB(Application Load Balancer)やExternal DNSに関連する細かい設定をCRDに組み込む形で簡潔に記述できます。
接続フローと概要
IngressとExternal DNSを組み合わせた接続フローを以下に示します。
[ユーザー] --> [Route 53] (External DNSでDNS登録) --> [ALB] --> [Ingress] --> [AWX Pod]
接続フローの詳細解説
-
External DNSによるDNS登録
KubernetesのIngressやService情報を元に、External DNSがRoute 53にDNSレコードを自動登録します。 -
Route 53で名前解決
ユーザーが指定したドメイン名でアクセスすると、Route 53がALBのエンドポイントに名前解決を行います。 -
ALBを経由してトラフィックを処理
ALBはHTTPS通信を処理し、トラフィックをKubernetesのIngressリソースにルーティングします。 -
HTTPS化の対応
HTTPS通信を有効化するためには、AWS Certificate Manager(ACM)で発行したSSL証明書をALBに関連付け、Ingressリソース内でその証明書を指定します。
AWX OperatorのIngress設定例
AWX Operatorのデプロイ時に、Ingressリソースを設定する際の記載例は以下の通りです。
ingress_type: ingress # Exposes AWX using ingress.
hostname: <ドメイン名>
ingress_annotations: |
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=86400
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-Ext2-2021-06
alb.ingress.kubernetes.io/certificate-arn: <SSL証明書ARN>
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
alb.ingress.kubernetes.io/backend-protocol: HTTP
external-dns.alpha.kubernetes.io/hostname: <ドメイン名>
ingress_path: /
ingress_path_type: Prefix
ingress_api_version: 'networking.k8s.io/v1'
設定のポイント
-
ingress_type: ingress
を設定することで、AWXがIngressを利用して外部に公開されるようにします。 -
hostname
に指定したドメイン名が外部からのアクセスポイントとなります。 -
ingress_annotations
- ALB (Application Load Balancer) に関連する設定を細かく指定します。
-
stickiness.enabled=true
: セッションの持続性を有効化。 -
certificate-arn
: HTTPS通信を有効にするためのSSL証明書を指定。 -
backend-protocol: HTTP
: バックエンドがHTTPで動作している場合に必要。
-
-
external-dns.alpha.kubernetes.io/hostname
:- 前述したExternal DNS設定との組み合わせ。
- ALB (Application Load Balancer) に関連する設定を細かく指定します。
-
ingress_path および ingress_path_type
-
ingress_path: /
により、ルートパスでアクセスできるように設定。 -
ingress_path_type: Prefix
を設定することで、指定されたパスに基づいたルーティングが可能になります。
-
-
SSLポリシーの選択
-
alb.ingress.kubernetes.io/ssl-policy
では、TLS 1.3を含む強力なセキュリティポリシーが適用されるように設定されています。
-
これらの設定により、AWX側でIngress Gatewayをデプロイ管理することができます。
設定を完了した後、Azure ADとAWX Operatorの連携にコールバックURLの確認が必要です。
このURLは、認証後にAzure ADがAWXにリダイレクトする際に使用されます。
コールバックURLを確認
AWX Operatorの管理画面から「設定 > Azure ADの設定」を開き、コールバックURLを確認します。
このコールバックURLを後続のリダイレクトURIとして設定します。
03. リダイレクトURI設定およびAPIアクセス許可(Azure AD)
リダイレクトURI設定
Azure ポータルの「SSOアプリケーション管理画面」から、「認証 > プラットフォーム構成」にてリダイレクトURI(前述で確認したコールバックURL)を追加します。
「プラットフォームを追加」ボタンをクリックし、「Web」を選択します。
リダイレクトURIを入力し、「Configure」をクリックします。
クライアントシークレットの発行
リダイレクトURIの設定後、クライアントシークレットを発行します。
アプリケーションの「証明書とシークレット」タブを開き、「新しいクライアントシークレットの追加」を選択します。
シークレットを発行し、その値を安全に保管します(後でKubernetes Secretに登録します)。
操作内容は、以下のブログが参考になりました。
APIアクセス許可の追加
APIアクセス許可としてUser.Read
、openid
、profile
を追加します。
04. Secretsリソース設定
Azure ADの認証情報(Client IDとClient Secret)をKubernetesのSecretに保存し、AWX Operatorがそれを参照するよう設定します。ExternalSecretを利用して認証情報を保存する例を以下に示します。
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: awx-azuread-oauth2-secret
namespace: awx
spec:
refreshInterval: "0"
secretStoreRef:
name: aws-secret-store
kind: SecretStore
target:
name: awx-azuread-oauth2-secret
template:
type: Opaque
data:
- secretKey: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
remoteRef:
key: common/awx
property: client-id-key
- secretKey: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
remoteRef:
key: common/awx
property: client-secret-key
前述で発行した、Azure ADのclient-idとclient-secretがKubernetesのSecretとして保存され、AWX Operatorがこれを参照して認証に使用します。
AWX Operator CRDの設定でextra_env
を利用してシークレットを参照するよう設定します。
参考Issueは以下になります。
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx
namespace: awx
spec:
task_extra_env: |
- name: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
valueFrom:
secretKeyRef:
name: awx-azuread-oauth2-secret
key: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
- name: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
valueFrom:
secretKeyRef:
name: awx-azuread-oauth2-secret
key: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
web_extra_env: |
- name: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
valueFrom:
secretKeyRef:
name: awx-azuread-oauth2-secret
key: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
- name: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
valueFrom:
secretKeyRef:
name: awx-azuread-oauth2-secret
key: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
extra_settings:
- setting: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
value: 'os.getenv("SOCIAL_AUTH_AZUREAD_OAUTH2_KEY")'
- setting: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
value: 'os.getenv("SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET")'
適用後、AWX Operatorの「設定」 > 「Azure ADの設定」
からも適用されていることを確認できます。
この設定により、AWXはAzure ADのクライアントIDとクライアントシークレットを使用して、Azure ADと連携し、ユーザー認証を行うことができます。
05. SSO認証でログイン
Azure ADのアイコンがログイン画面に表示されます。このアイコンをクリックし、SSO認証によるログインが可能かどうか確認します。
この際、必要に応じて管理者承認の依頼が必要です。今回は別部門のチームがAzure ADを管理しているため、そちらへ管理者承認依頼を行いました。
接続/ログインできない場合は、以下の点を確認してください。
- リダイレクトURIが正しいか
- APIアクセス許可が正しく設定されているか
- Azure ADのアプリケーション登録が正しく行われているか
- Azure ADのクライアントIDとクライアントシークレットが正しくKubernetesのSecretに保存されているか
参考ドキュメント
SSOログイン後、以下のようにAzure AD経由で認証されたユーザーがソーシャルユーザーとして登録されます。
登録のタイミングで、所属する組織やチームに自動的にマッピングすることも可能です。これにより、アクセス権限の割り当てやユーザー管理を効率化できます。
具体的な設定方法については、以下のドキュメントをご参照ください。
終わりに
本記事では、Kubernetes環境にデプロイしたAWX OperatorのDashboardでAzure ADを使用したSSO認証の設定方法をご紹介しました。この設定を行うことで、シングルサインオンを通じて、ユーザー体験を向上させるとともに、セキュリティの強化や管理の効率化が実現できます。
AWX Operatorに関する情報はまだ少なく、設定に苦労する場面もありましたが、基本的な構造はAnsibleと同様のため、問題が発生した際にはAnsibleの公式ドキュメントが非常に参考になります。
以下にリンクを記載しておきますので、ぜひご活用ください。
最後までお読みいただきありがとうございました。
本記事が少しでも誰かのお役に立てれば幸いです。