🐙

マニフェストによる Argo CD のリポジトリ管理

に公開

クラウドエース 北野です。
Argo CD に連携する GitHub リポジトリをマニフェストで管理する方法を紹介します。

概要

Argo CD にマニフェストで GitHub リポジトリを接続するには、以下のようにします。

  • 接続するリポジトリ情報の Secret への定義
  • Secret Manager のパスワード情報の External Secret による Secret への連携

GitHub のリポジトリを HTTPS で接続する Secret は次のようになります。

sc-repositories.yaml
apiVersion: v1
kind: Secret
metadata:
  name: <SECRET NAME>
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/<GITHUB ORGANAIZATION>/<GITHUB REPOSITORY>
  username: <REPOSITORY USER>
  project: <PROJECT>

先の Secret にパスワード情報を連携する External Secret は次のようになります。

es-github-token.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: <EXTERNAL SECRET NAME>
  namespace: argocd
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: <ClusterSecretStore NAME>
    kind: ClusterSecretStore
  target:
    name: <SECRET NAME>
    creationPolicy: Merge
  data:
    - secretKey: password
      remoteRef:
        key: <SECRET MANAGER NAME>
        version: latest

はじめに

Argo CD は Web ブラウザからリポジトリを登録できます。
プライベートリポジトリ接続には Personal Access Token などの認証情報が必要となり、毎回の登録が煩雑です。
また、異動や退職によって連携を作成した作業者がリポジトリへの権限を失うと、Argo CD への連携も失敗します。その度に再度接続する必要が出てくるため、大変煩雑です。

そこで、この接続をマニフェストで宣言的に定義し、登録作業を自動化する方法を紹介します。

Argo CD の宣言的なリポジトリ管理

Argo CD はラベルの情報で Secret のタイプを識別しています。次のように metadata.labels.argocd.argoproj.io/secret-typerepository を設定すると、Argo CD は登録された Secret がリポジトリの情報であると認識します。

apiVersion: v1
kind: Secret
metadata:
  name: private-helm-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  url: https://my-private-chart-repo.internal
  name: private-repo
  type: helm
  password: my-password
  username: my-username

https://argo-cd.readthedocs.io/en/latest/user-guide/annotations-and-labels/#labels
https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-repositories-yaml/

宣言的な方法でもコンソールで登録する次の接続方法で登録できます。

  • SSH
  • HTTPS
  • GitHub APP
  • Google Cloud

https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repository-credentials

先の例では、HTTPS のプロトコルで、ユーザーとそのパスワードで認証させています。
例を見ても分かるようにパスワード情報が平文で入力されており、セキュリティ上の問題を有しています。
この記事では、GitHub リポジトリをこの HTTPS 接続で安全に接続する方法を紹介します。
以下で説明するコード内の <> で囲まれた値は、環境に合わせて書き替えてください。

事前準備

この記事では、次のようなシステム構成で Argo CD を構築します。

Argo CD は Google Cloud の Google Kubernetes Engine 上に構築します。インターネットへの公開は、Gateway を使っています。
また、Google アカウントで SSO するように構築しています。そのときに使う OAuth2 のクライアントとシークレット情報は、Google Cloud の Secret Manager 上に保存し、External Secret を使って、Secret に連携しています。
具体的な構築方法は、次の記事をご参照ください。

https://zenn.dev/cloud_ace/articles/argocd_on_gke
https://zenn.dev/cloud_ace/articles/argocd_google_accout_sso

今回、この External Secret を使い、GitHub のパスワード情報を Secret Manager に管理することで、パスワード情報をマニフェストから削除します。

環境構築

GitHub のリポジトリは、次のように連携します。

設定項目 設定値
接続方法 HTTPS
接続先 GitHub (github.com)
接続先プロジェクト default
認証情報 ユーザーとそのパスワード
パスワードの保存先の Secret Manager 名 github-pat

接続はリポジトリへの権限を持つユーザーとそのパスワードで認証させます。このとき、パスワードはユーザーの Personal Access Token (以降 PAT と呼びます)を使います。

PAT 情報の作成

ここでは PAT を作成して、Secret Manager に登録します。
次の Terraform コードで、github-pat の Secret Manager を作成します。

secret_manager.hcl
resource "google_secret_manager_secret" "main" {
  secret_id = "github-pat"

  project = var.project
  replication {
    user_managed {
      replicas {
        location = "asia-northeast1"
      }
    }
  }
}

GitHub へアクセスし Settings を選択し Developer settings の Personal access tokens から Tokens (classic) を作成するページへ移動します。

https://github.com/settings/tokens

そして、Generate new token の Generate new token (classic) から PAT を作成します。

Select scopes の repo を選択して、Generate token で PAT を作成します。生成された値をコピーして、Secret Manager github-pat にその値を Web ブラウザから登録します。


Argo CD へのリポジトリ連携

リポジトリを接続する Secret は次のように作成します。

sc-repositories.yaml
apiVersion: v1
kind: Secret
metadata:
  name: <SECRET NAME>
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/<GITHUB ORGANAIZATION>/<GITHUB REPOSITORY>
  username: <REPOSITORY USER>
  project: <PROJECT>

この Secret の stringData に password 情報を External Secret で代入します。次のように spec.target.creationPolicy=Merge として、値を代入します。
External Secret の creationPolicy については、次のドキュメントをご確認ください。

https://external-secrets.io/v0.5.9/guides-ownership-deletion-policy/

es-github-token.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: <EXTERNAL SECRET NAME>
  namespace: argocd
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: <ClusterSecretStore NAME>
    kind: ClusterSecretStore
  target:
    name: <SECRET NAME>
    creationPolicy: Merge
  data:
    - secretKey: password
      remoteRef:
        key: github-pat
        version: latest

最後に実際にデプロイして接続されているかを確認してみます。
Secret と External Secret が作成されていることが分かります。


Argo CD の settings の Repositories を確認すると、リポジトリが登録されていることが確認できます。

さいごに

Argo CD へのリポジトリ連携をマニフェストで管理する方法を紹介しました。リポジトリの管理が多くなってきた場合、マニフェストでの管理を検討してみてはいかがでしょうか。

Discussion