argocd 应用程序在 CI 管道中创建(GitHub 操作、Tekton、...)抛出 "PermissionDenied desc = permission denied: applications, create, default/myapp"

argocd app create in CI pipeline (GitHub Actions, Tekton, ...) throws "PermissionDenied desc = permission denied: applications, create, default/myapp"

在我们的 Tekton 管道中,我们希望使用 ArgoCD CLI 根据正在构建的应用程序动态执行 argocd app createargocd app sync。我们通过将 accounts.tekton: apiKey 添加到 argocd-cm ConfigMap 创建了一个新用户 as described in the docs

kubectl patch configmap argocd-cm -n argocd -p '{"data": {"accounts.tekton": "apiKey"}}'

然后我们为 tekton 用户创建了一个令牌:

argocd account generate-token --account tekton

使用这个标记作为 passwordusername tekton 我们做了 argocd login 就像

argocd login $(kubectl get service argocd-server -n argocd --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}') --username=tekton --password="$TOKEN";

现在,如果我们 运行 argocd app create:

$ argocd app create microservice-api-spring-boot --repo https://gitlab.com/jonashackt/microservice-api-spring-boot-config.git --path deployment --dest-server https://kubernetes.default.svc --dest-namespace default --revision argocd --sync-policy auto
error rpc error: code = PermissionDenied desc = permission denied: applications, create, default/microservice-api-spring-boot, sub: tekton, iat: 2022-02-03T16:36:48Z

Argo's useraccounts docs中提到的问题:

When you create local users, each of those users will need additional RBAC rules set up, otherwise they will fall back to the default policy specified by policy.default field of the argocd-rbac-cm ConfigMap.

但是这些额外的 RBAC 规则可以设置为最简单的 using ArgoCD Projects. And with such a AppProject you don't even need to create a user like tekton in the ConfigMap argocd-cm. ArgoCD projects have the ability to define Project roles:

Projects include a feature called roles that enable automated access to a project's applications. These can be used to give a CI pipeline a restricted set of permissions. For example, a CI system may only be able to sync a single app (but not change its source or destination).

有 2 个解决方案如何配置 AppProject、角色和权限,包括。角色标记:

  1. 使用 argocd CLI
  2. 使用清单 YAML 文件

1.) 使用 argocd CLI 创建 AppProject、角色和权限,包括。角色标记

所以让我们亲自动手,使用名为 apps2deploy:

argocd CLI 创建一个 ArgoCD AppProject
argocd proj create apps2deploy -d https://kubernetes.default.svc,default --src "*"

我们使用 --src "*" 创建它作为任何 git 存储库 (as described here) 的通配符。

现在我们创建一个名为 create-sync 的项目 role 通过:

argocd proj role create apps2deploy create-sync --description "project role to create and sync apps from a CI/CD pipeline"

您可以使用 argocd proj role list apps2deploy 查看新角色是否已创建。

然后我们需要为新的项目角色create-sync创建一个令牌,可以通过以下方式创建:

argocd proj role create-token apps2deploy create-sync

此令牌需要用于我们的 Tekton / CI 管道内的 argocd login 命令。该命令还有一个 --token-only 参数,因此我们可以通过

创建一个环境变量
ARGOCD_AUTH_TOKEN=$(argocd proj role create-token apps2deploy create-sync --token-only)

ARGOCD_AUTH_TOKEN 将被 argo login 自动使用。

现在我们需要授予该角色权限,以便它能够从 Tekton 或任何其他 CI 管道在 ArgoCD 中创建和同步我们的应用程序。 As described in the docs we therefore add policies to our roles 使用 argocd CLI:

argocd proj role add-policy apps2deploy create-sync --action get --permission allow --object "*"
argocd proj role add-policy apps2deploy create-sync --action create --permission allow --object "*"
argocd proj role add-policy apps2deploy create-sync --action sync --permission allow --object "*"
argocd proj role add-policy apps2deploy create-sync --action update --permission allow --object "*"
argocd proj role add-policy apps2deploy create-sync --action delete --permission allow --object "*"

查看 argocd proj role get apps2deploy create-sync 的角色策略,它应该看起来像这样:

$ argocd proj role get apps2deploy create-sync
Role Name:     create-sync
Description:   project role to create and sync apps from a CI/CD pipeline
Policies:
p, proj:apps2deploy:create-sync, projects, get, apps2deploy, allow
p, proj:apps2deploy:create-sync, applications, get, apps2deploy/*, allow
p, proj:apps2deploy:create-sync, applications, create, apps2deploy/*, allow
p, proj:apps2deploy:create-sync, applications, update, apps2deploy/*, allow
p, proj:apps2deploy:create-sync, applications, delete, apps2deploy/*, allow
p, proj:apps2deploy:create-sync, applications, sync, apps2deploy/*, allow
JWT Tokens:
ID          ISSUED-AT                                EXPIRES-AT
1644166189  2022-02-06T17:49:49+01:00 (2 hours ago)  <none>

最后我们应该设置好一切才能成功 argocd app create。我们需要做的就是添加--project apps2deploy参数:

argocd app create microservice-api-spring-boot --repo https://gitlab.com/jonashackt/microservice-api-spring-boot-config.git --path deployment --project apps2deploy --dest-server https://kubernetes.default.svc --dest-namespace default --revision argocd --sync-policy auto

2.) 使用清单 YAML 创建 AppProject、角色和权限,包括。角色标记

由于解决方案 1.) 中所有基于 CLI 的步骤很多,我们也可以 using a manifest YAML file。这是一个示例 argocd-appproject-apps2deploy.yml,其配置与解决方案 a) 中的完全相同):

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: apps2deploy
  namespace: argocd
spec:
  destinations:
    - namespace: default
      server: https://kubernetes.default.svc
  sourceRepos:
    - '*'
  roles:
    - description: project role to create and sync apps from a CI/CD pipeline
      name: create-sync
      policies:
      - p, proj:apps2deploy:create-sync, applications, get, apps2deploy/*, allow
      - p, proj:apps2deploy:create-sync, applications, create, apps2deploy/*, allow
      - p, proj:apps2deploy:create-sync, applications, update, apps2deploy/*, allow
      - p, proj:apps2deploy:create-sync, applications, delete, apps2deploy/*, allow
      - p, proj:apps2deploy:create-sync, applications, sync, apps2deploy/*, allow

只剩下 2 个步骤就可以在 Tekton(或其他 CI 管道)中成功完成 argocd app create。我们需要 apply 清单

kubectl apply -f argocd-appproject-apps2deploy.yml

并且我们需要创建一个角色令牌,理想情况下将其直接分配给 argocd login 命令的 ARGOCD_AUTH_TOKEN(这也需要在之后完成):

ARGOCD_AUTH_TOKEN=$(argocd proj role create-token apps2deploy create-sync --token-only)

与解决方案 1.) 中提到的相同 argocd app create 命令现在应该可以工作了:

argocd app create microservice-api-spring-boot --repo https://gitlab.com/jonashackt/microservice-api-spring-boot-config.git --path deployment --project apps2deploy --dest-server https://kubernetes.default.svc --dest-namespace default --revision argocd --sync-policy auto