3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ArgoCDのアカウントにロールを割り当てて権限設定する

Last updated at Posted at 2022-07-25

ArgoCDを複数ユーザで使う場合に権限を分けたい。
具体的には参照可能なApplicationリソースを以下のように分離したい。

Projectが同一 Projectが異なる
ゲスト Read Read
開発者 CRUD+Sync なし
管理者 CRUD+Sync CRUD+Sync

※CRUD: Create, Read(Get), Update, Delete

これを実現する方法を検討した時のメモ。
なお、確認に利用したArgoCDのバージョンはv2.4.7であり、異なるバージョンで試す場合は方法が変わる可能性が有る点には注意すること。

やること

以下の仮想ユーザを用意し、それぞれ権限が適切に分けて付与できるかを確認する。
1658741598885.png

確認手順は以下となる。

  1. 前準備(Applicationが管理するManifestの準備)
  2. ArgoCD用ユーザアカウントの作成
  3. ArgoCDのProjectとRoleの作成
  4. kind: Applicationの適用
  5. 検証

前準備

ArgoCDのアプリケーション(game_appbook_app)が監視するManifestを作成してGitにpushする。

空のリポジトリを作成してcloneする。

export $MYREPO=https://mygitlab.info/myapp/apps.git
git clone $MYREPO

各プロジェクトで利用するManifestを格納するディレクトリを作成する。

mkdir -p apps/{game,book}

今回はアプリケーションそのものには価値を求めないため、ダミーでnginxが起動するManifestを作成する。
それぞれのディレクトリにダミーのManifestを作成してpushする。

NAME=game
kubectl run --image nginx nginx-$NAME -o yaml --dry-run=client  | kubectl neat -f - > apps/$NAME/nginx-$NAME.yaml
NAME=book
kubectl run --image nginx nginx-$NAME -o yaml --dry-run=client  | kubectl neat -f - > apps/$NAME/nginx-$NAME.yaml
git add *
git commit -m "nocomment"
git push

構成としては以下のようになる。

apps
├── README.md
├── book
│   └── nginx-book.yaml
└── game
    └── nginx-game.yaml

ユーザアカウントの作成

ArgoCDはv2.4時点ではアカウントの作成がCLI/GUIから作成できず、ConfigMapで指定することでのみ作成できる。
作成するConfigMapも指定があり、argocd-cmというConfigMapを必ず使うことになっているので、こちらを使用する。
なお、デフォルトでインストールされているargocd-cmは初期状態では空なので、上書きしてもらって問題ない。

ArgoCDのユーザ管理のオフィシャルページを見つつ、アカウントの元となるyamlを作成し、applyする。

cat << EOF > ./argocd-account-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  accounts.alice: apiKey, login
  accounts.bob: apiKey, login
  accounts.mike: apiKey, login
EOF
kubectl apply -f argocd-account-cm.yaml

ユーザアカウント名はdataフィールドにaccounts.<ユーザアカウント名>で記載することで作成される。apiKeyはTokenによるアクセスを許可するかどうかであり、不要であれば外してもらって構わない。

反映されたことを確認する。

$ argocd account list
NAME   ENABLED  CAPABILITIES
admin  true     login
alice  true     apiKey, login
bob    true     apiKey, login
mike   true     apiKey, login

パスワードは設定されていないので、コマンドで変更する。なお、--current-passwordにはadminのパスワードを指定する。

export ADMIN_PASSWORD='admin-password'
export PASSWORD='argocd-password'
argocd account update-password --account alice --current-password $ADMIN_PASSWORD  --new-password $PASSWORD
argocd account update-password --account bob --current-password $ADMIN_PASSWORD  --new-password $PASSWORD
argocd account update-password --account mike --current-password $ADMIN_PASSWORD  --new-password $PASSWORD

ProjectとRoleの作成

次にProjectの作成とroleの作成をセットで行う。なおコマンドでProjectやroleも作成可能だが、Manifestで設定した方が全体を見渡せやすいので、今回はManifestにて作成する。
なお、Built-inのroleが存在するが、今回は利用しない(書き方の参考にはした)。
その他書き方を参考にしたページはこれこれになる。

以下、Project:gameのManifest適用手順となる。bookに対しても同様に適用する(環境変数をbookに変えて再実行する)。

export APP_PROJECT=game
cat <<EOF > ./${APP_PROJECT}-project.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: ${APP_PROJECT}
  namespace: argocd
spec:
  clusterResourceWhitelist:
  - group: '*'
    kind: '*'
  destinations:
  - namespace: '*'
    server: '*'
  sourceRepos:
  - '*'
  roles:
  - name: guest
    description: "guest role"
    policies:
    - p, proj:${APP_PROJECT}:guest, applications, get, */*, allow
  - name: developer
    description: "developer role"
    policies:
    - p, proj:${APP_PROJECT}:developer, applications, create, ${APP_PROJECT}/*, allow
    - p, proj:${APP_PROJECT}:developer, applications, get, ${APP_PROJECT}/*, allow
    - p, proj:${APP_PROJECT}:developer, applications, update, ${APP_PROJECT}/*, allow
    - p, proj:${APP_PROJECT}:developer, applications, delete, ${APP_PROJECT}/*, allow
    - p, proj:${APP_PROJECT}:developer, applications, sync, ${APP_PROJECT}/*, allow
  - name: operator
    description: "operator role"
    policies:
    - p, proj:${APP_PROJECT}:operator, applications, create, */*, allow
    - p, proj:${APP_PROJECT}:operator, applications, get, */*, allow
    - p, proj:${APP_PROJECT}:operator, applications, update, */*, allow
    - p, proj:${APP_PROJECT}:operator, applications, delete, */*, allow
    - p, proj:${APP_PROJECT}:operator, applications, sync, */*, allow
EOF
kubectl apply -f ./${APP_PROJECT}-project.yaml

clusterResourceWhitelistdestinationssourceReposは今回チェックの対象外としている。必要な場合(クラスタやデプロイ先、利用するリポジトリに制限をかけたい場合)は
こちらを参照するとよい。

なお、policiesで指定しているポリシーの意味は以下となる。

  • ポリシールールを定義:
p, subject, resource, action, object, effect

例)

p, my-org:team-alpha, applications, sync, my-project/*, allow
  • ユーザとロールをbinding:
g, subject, inherited-subject

例)

g, my-org:team-beta, role:admin

ここではbindingまでは含めておらず、ロールの定義のみ実施しているため、g, xxxxは記載していない。

適用後、argocd cliからProjectとRoleは以下のように見える。

$ argocd proj list
NAME         DESCRIPTION  DESTINATIONS  SOURCES  CLUSTER-RESOURCE-WHITELIST  NAMESPACE-RESOURCE-BLACKLIST  SIGNATURE-KEYS  ORPHANED-RESOURCES
book                      *,*           *        */*                         <none>                        <none>          disabled
default                   *,*           *        */*                         <none>                        <none>          disabled
game                      *,*           *        */*                         <none>                        <none>          disabled
$ argocd proj role list game
ROLE-NAME  DESCRIPTION
guest      guest role
developer  developer role
operator   operator role
$ argocd proj role get game developer
Role Name:     developer
Description:   developer role
Policies:
p, proj:game:guest, projects, get, game, allow
p, proj:game:guest, applications, get, */*, allow
p, proj:game:developer, projects, get, game, allow
p, proj:game:developer, applications, create, game/*, allow
p, proj:game:developer, applications, get, game/*, allow
p, proj:game:developer, applications, update, game/*, allow
p, proj:game:developer, applications, delete, game/*, allow
p, proj:game:developer, applications, sync, game/*, allow
p, proj:game:operator, projects, get, game, allow
p, proj:game:operator, applications, create, */*, allow
p, proj:game:operator, applications, get, */*, allow
p, proj:game:operator, applications, update, */*, allow
p, proj:game:operator, applications, delete, */*, allow
p, proj:game:operator, applications, sync, */*, allow
JWT Tokens:
ID  ISSUED-AT  EXPIRES-AT

次にオフィシャルサイトの記述を参考にユーザとロールをConfigMapを使ってbindingする。
こちらもアカウント作成時と同様にConfigMapに指定があり、argocd-rbac-cmというConfigMapにpolicy.csvというdataフィールドに追加することでbindingする。
適用したManifestは以下となる。

cat <<EOF > ./argocd-rbac-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  #policy.default: role:readonly
  policy.csv: |
    g, alice, proj:game:guest
    g, alice, proj:book:guest
    g, bob, proj:game:developer
    g, mike, proj:game:operator
    g, mike, proj:book:operator
EOF
kubectl apply -f ./argocd-rbac-cm.yaml

今回はroleは作成済みなので、policyの記載ではbindingに関するルールのg, xxxxの方のみ記載した。
また、defaultのpolicyは検証の邪魔になるためコメントアウトした。

kind: Applicationの適用

先程作成したManifestをデプロイするkind: Applicationを作成する。
以下、Project:gameで動くアプリケーションとなる。Project:bookについては環境変数を変更して流し直す。

export APP_PROJECT=game
cat <<EOF > ./${APP_PROJECT}-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: ${APP_PROJECT}-app
  namespace: argocd
spec:
  destination:
    namespace: nginx-${APP_PROJECT}
    server: https://kubernetes.default.svc
  project: ${APP_PROJECT}
  source:
    path: ${APP_PROJECT}/
    repoURL: https://mygitlab.info/myapp/apps.git
    targetRevision: HEAD
  syncPolicy:
    syncOptions:
    - CreateNamespace=true
EOF
kubectl apply -f ./${APP_PROJECT}-app.yaml

AutoSyncを書き忘れていたので、手動でsyncする。

argocd app sync game-app
argocd app sync book-app

実行後は以下となる。

$ argocd app list
NAME      CLUSTER                         NAMESPACE   PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO                                  PATH   TARGET
book-app  https://kubernetes.default.svc  nginx-book  book     Synced  Healthy  <none>      <none>      https://mygitlab.info/myapp/apps.git  book/  HEAD
game-app  https://kubernetes.default.svc  nginx-game  game     Synced  Healthy  <none>      <none>      https://mygitlab.info/myapp/apps.git  game/  HEAD

検証

作成したアカウントに適切に権限が設定されるかを確認する。
冒頭に載せた表をアカウント名に置き換えたものを再掲する。

Projectが同一 Projectが異なる
alice Read Read
bob CRUD+Sync なし
mike CRUD+Sync CRUD+Sync

それぞれのアカウントでGUIからログインし、権限が適切に割り当たっていることを確認する。

alice(ゲスト)

それぞれのApplicationは表示される。
1658740889288.png
Syncしようとすると"permission denied"のエラーが表示される。
1658740924869.png

bob(開発者)

画面上にはgameのProjectのApplicationしか表示されず、リストも取得できない。
1658740731873.png

Syncは成功する。

mike(管理者)

画面上にはそれぞれのApplicationが表示される。
1658741007472.png
Syncはそれぞれ成功する。

まとめ

設定がCLIから出来ないところがあるのと、設定ルールを学習する必要があること、またドキュメントが散らばっていて分かりづらいところがあるのがやや難ではあるが、最低限のアクセスコントロールが出来ることは確認できた。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?