🛴

SSOを利用してArgo Serverにログインする

2024/05/29に公開

概要

Argo Workflowsに対して、Googleアカウントを使ったssoを使用してみました。
今回はGKE上にArgo Serverを構築したいと思います。

GitHub: https://github.com/hosimesi/code-for-techblogs/tree/main/argo_server_sso

Argo Serverの認証方法

Argo Serverの認証方法にはいくつか方法があります。

  • server
  • client
  • sso

開発時等はserver認証でも問題ないですが、実運用上ではclientかssoの認証を入れる必要があると思います。
今回はより柔軟な権限管理ができるssoでArgo Serverにログインできるように設定したいと思います。

https://argo-workflows.readthedocs.io/en/stable/argo-server-auth-mode/

もしArgo CDを使っている場合、Dexとの連携も可能ですが、それについては別記事にまとめたいと思います。

Google Cloudの設定

まずはGKEのクラスター作成やサービスアカウントの作成をします。今回は検証用なので、1ノードで小さいインスタンスを動かしてみます。DNS ZoneをGoogle Cloud上で管理している前提で作成していますが、自身の状況に合わせて修正してください。

provider "google" {
  project = var.project
  region  = var.region
}

# GKEのservice account
resource "google_service_account" "gke_sa" {
  account_id   = "gke-sa"
  display_name = "gke用のservice account"
}

# GKE Cluster
resource "google_container_cluster" "gke_cluster" {
  name                = "gke-cluster"
  location            = "asia-northeast1-a"
  project             = var.project
  deletion_protection = false

  remove_default_node_pool = true
  initial_node_count       = 1

}

# GKE Node Pool
resource "google_container_node_pool" "argo_nodes" {
  name     = "argo-node-pool"
  location = "asia-northeast1-a"

  cluster    = google_container_cluster.gke_cluster.name
  project    = var.project
  node_count = 1

  autoscaling {
    max_node_count = 1
    min_node_count = 1
  }

  node_config {
    preemptible  = true
    machine_type = "e2-medium"

    service_account = google_service_account.gke_sa.email

    metadata = {
      disable-legacy-endpoints = "true"
    }

    oauth_scopes = [
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]

    labels = {
      preemptible = "true"
    }

    tags = ["argo-node-pool"]
  }
}

# Argo Workflows用の外部IP
resource "google_compute_global_address" "argo_workflows_external_ip" {
  name         = "argo-workflows-server-ip"
  address_type = "EXTERNAL"
  ip_version   = "IPV4"
  project      = var.project
}

# DNSゾーン
data "google_dns_managed_zone" "dns_zone" {
  name    = "your-dns-zone"
  project = var.project
}

# Argo Workflows用のDNSレコード
resource "google_dns_record_set" "argo_workflows" {
  project      = var.project
  name         = "argo-workflows.${data.google_dns_managed_zone.dns_zone.dns_name}"
  type         = "A"
  ttl          = 300
  managed_zone = data.google_dns_managed_zone.dns_zone.name
  rrdatas      = [google_compute_global_address.argo_workflows_external_ip.address]
  lifecycle {
    ignore_changes = [rrdatas]
  }
}

# Argo Workflowsのservice account
resource "google_service_account" "argo_workflows_sa" {
  account_id   = "argo-workflows-sa"
  display_name = "argo workflows用のservice account"
}

上記作成後、をterraform applyしてリソースを作成します。

ssoの設定

次にssoに必要なID Providerや認証情報の設定をしていきます。

認証情報の作成

認証情報を作成します。OAuthクライアントIDの作成を選択します。

アプリケーションの種類をウェブアプリケーション、名前をargo ssoとして作成します。
この時、承認済みのJavaScript生成元や承認済みのリダイレクトURIには自身のドメインを設定します。
承認済みのJavaScript生成元: https://<your-domain>
承認済みのリダイレクトURI: https://<your-domain>/oauth2/callback

ここで得られたクライアントIDとクライアントシークレットを保存しておきます。

OAuth 同意画面の設定

先ほど認証情報の作成によって自動で以下のようにargo ssoが作成されています。
これを編集していきます。

スコープとしてemailとprofileを選択して保存します。

また、テストユーザとしてGoogleのメールアドレスを2つ用意しておきます。この2つはこの後、Admin権限をもつユーザとRead Only権限をもつユーザとしてログインする用途で使用します。
これで設定は完了です。

ID Providerの作成

次にID Providerを作成していきます。

先ほど得られたクライアントIDとクライアントシークレットを入力し、保存します。

Argo Workflowsの構築

今回はargo-workflowsというnamespaceにリソースを作成するため、まず必要なnamespaceを作成していきます。

apiVersion: v1
kind: Namespace
metadata:
  name: argo-workflows
  labels:
    name: argo-workflows
$ kubectl apply -f argoworkflows/base/namespace.yaml
namespace/argo-workflows created

その後、他のすべてのリソースを作成します。重要な部分をピックアップします。

  1. Secretを作成します。
    先ほどOAuthクライアントを作成した時のclient idとclient secretをbase 64でエンコードし、以下に指定します。また、Service Accountのトークンを保存するためのSecretも作成しておきます。ここではすべての操作ができるdeveloper-saと読み取り権限のbusiness-saを用意するため、それぞれのSecretを作成します。
    $echo -n 'client-id' | base64
    $echo -n 'client-secret' | base64
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: argo-server-sso-secret
      namespace: argo-workflows
    type: Opaque
    data:
      client-id: <base64-encoded-client-id>
      client-secret: <base64-encoded-client-secret>
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: developer-sa.service-account-token
      namespace: argo-workflows
      annotations:
        kubernetes.io/service-account.name: developer-sa
    type: kubernetes.io/service-account-token
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: business-sa.service-account-token
      namespace: argo-workflows
      annotations:
        kubernetes.io/service-account.name: business-sa
    type: kubernetes.io/service-account-token
    
  2. Service Accountの作成
    実行用に先ほどのTerraformで作成したArgo Workflows用のSAをannotationします。また、developer-saとbusiness-saを作成し、それぞれには自身が用意したgoogleのアカウントのメールアドレスをannotationします。
    # 実行用SA
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: argo-workflows-sa
      namespace: argo-workflows
      # 先ほどterraformで作成したargo workflows用のサービスアカウントのEmail
      annotations:
        iam.gke.io/gcp-service-account: "your-gcp-service-account-email"
    ---
    # DeveloperのSSO用SA
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: developer-sa
      namespace: argo-workflows
      # FIXME: Replace the following value with your own
      annotations:
        workflows.argoproj.io/rbac-rule: "email == 'your-google-email-1'"
        workflows.argoproj.io/rbac-rule-precedence: "1"
    ---
    # BusinessのSSO用SA
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: business-sa
      namespace: argo-workflows
      # FIXME: Replace the following value with your own
      annotations:
        workflows.argoproj.io/rbac-rule: "email == 'your-google-email-2'"
        workflows.argoproj.io/rbac-rule-precedence: "1"
    
  3. ConfigMap
    ConfigMapでssoの設定をします。redirectUrlには自身のドメインを設定します。
    # For workflow archive to Cloud SQL
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: workflow-controller-configmap
      namespace: argo-workflows
    data:
      namespace: argo-workflows
      sso: |
        issuer: https://accounts.google.com
        sessionExpiry: 12h
        clientId:
          name: argo-server-sso-secret
          key: client-id
        clientSecret:
          name: argo-server-sso-secret
          key: client-secret
        # FIXME Replace the following value with your own
        redirectUrl: https://<your-domain>/oauth2/callback
        scopes:
        - email
        - profile
        rbac:
          enabled: true
        insecureSkipVerify: false
    
  4. Deploymentの作成
    auth-modeをssoとして立ち上げます。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: argo-server
      namespace: argo-workflows
    spec:
      selector:
        matchLabels:
          app: argo-server
      template:
        spec:
          containers:
            - name: argo-server
            args: ["server", "--secure=false", "--auth-mode=sso"]
            resources:
              requests:
                cpu: 50m
                memory: 200Mi
              limits:
                cpu: 100m
                memory: 400Mi
    

上記の設定以外も含めて、適用していきます。今回はKustomizeを使用します。

$ kubectl apply -k argoworkflows/overlays/dev                           

namespace: argo-workflowsに2つのpodが立っており、Terraformで作成した自身のドメインでArgo UIにアクセスできたらOKです。

$ kubectl get pods -n argo-workflows
NAME                                READY   STATUS    RESTARTS   AGE
argo-server-xxxxxxxxx-xxx           1/1     Running   0          113s
workflow-controller-xxxxxxxxx-xxx   1/1     Running   0          26m

それでは左側のSSOをクリックしてみます。
まずは、すべての操作ができるdeveloper-saに紐付けたアカウントでログインしてみます。

以下のようにdeveloper-saとしてログインできていれば成功です。

すべての操作が許可されているので、ワークフローテンプレートを作ることもできます。

次に、読み取り権限のみを付与したbusiness-saに紐付けたアカウントでログインしてみます。
先ほどど違い、business-saでログインできていることが確認できました。

権限が変わっているか確認するためにワークフローテンプレートを作ってみます。

意図通りワークフローテンプレートは作成できませんでした。

最後に

Argo Workflowsに対して、Googleアカウントを使ったssoを使用してみました。今回はEmailでの権限の付与でしたが、Groupsなども対応しているため、チームごとなどもう少し広い範囲の管理も可能です。
簡単に導入できるので、ssoを検討してみてもいいかもしれません。
またドメインを持っていない場合でもローカル環境でkind上でArgo Serverを立て、ngrokなどを使ってトンネルすることで同様の検証が可能です。

参考文献

https://qiita.com/momotaro98/items/1edb189f1a627a367d48
https://argo-workflows.readthedocs.io/en/stable/argo-server-sso/

Discussion