kubectl create ns argocd
kubectl create -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.14.8/manifests/install.yaml -n argocd
kubectl create ns kyverno
kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.13.0/install.yaml -n kyverno
Each tenant gets their own namespace where they will be able to create their Argo Application. Have a fixed pattern that all tenant namespace would follow. eg: have all namespaces have suffix -tenant-ns
, so that you can have the glob pattern *-tenant-ns
specified in Argo CD configuration.
kubectl patch cm argocd-cmd-params-cm -n argocd -p '{"data":{"application.namespaces": "*-tenant-ns"}}'
kubectl apply -k "https://github.com/argoproj/argo-cd/examples/k8s-rbac/argocd-server-applications/?ref=v2.14.8"
kubectl patch cm argocd-cm -n argocd -p '{"data":{"application.sync.impersonation.enabled": "true"}}'
kubectl patch cm argocd-cm -n argocd -p '{"data":{"application.sync.impersonation.enabled": "false"}}'
kubectl create ns anandf-tenant-ns
kubectl create ns jfischer-tenant-ns
Note: Ensure that the namespace matches the pattern used when enabling apps in any namespace feature
PASSWORD=$(kubectl get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d)
argocd login <instance_host> --username admin --password ${PASSWORD}
argocd proj create anandf-tenant
argocd proj create jfischer-tenant
Allow only destination namespace with tenant prefix matching their ID.
argocd proj add-destination anandf-tenant https://kubernetes.default.svc 'anandf-*'
argocd proj add-destination jfischer-tenant https://kubernetes.default.svc 'jfischer-*'
Allow only applications defined in their namespace to be used for each project
argocd proj add-source-namespace anandf-tenant anandf-tenant-ns
argocd proj add-source-namespace jfischer-tenant jfischer-tenant-ns
argocd proj add-source anandf-tenant 'https://github.com/anandf/*.git'
argocd proj add-source jfischer-tenant 'https://github.com/jfischer/*.git'
For tenant admins to be able to create namespaces as part of their application sync, allow users to create namespace.
argocd proj allow-cluster-resource anandf-tenant "" "Namespace"
argocd proj allow-cluster-resource jfischer-tenant "" "Namespace"
argocd proj add-destination-service-account anandf-tenant https://kubernetes.default.svc 'anandf-*' 'anandf-admin-sa'
argocd proj add-destination-service-account jfischer-tenant https://kubernetes.default.svc 'jfischer-*' 'jfischer-admin-sa'
Create roles in the AppProject - read-only, admin, user, pipeline
spec:
roles:
- description: Read Only
name: read-only
policies:
- p, proj:anandf-tenant:read-only, applications, get, anandf-tenant-ns/*, allow
- description: tenant admins
name: admin
policies:
- p, proj:anandf-tenant:admin, applications, *, anandf-tenant-ns/*, allow
- description: tenant users
name: user
policies:
- p, proj:anandf-tenant:user, applications, get, anandf-tenant-ns/*, allow
- p, proj:anandf-tenant:user, applications, sync, anandf-tenant-ns/*, allow
- description: pipeline accounts
name: pipeline
policies:
- p, proj:anandf-tenant:pipeline, applications, get, anandf-tenant-ns/*, allow
- p, proj:anandf-tenant:pipeline, applications, sync, anandf-tenant-ns/*, allow
kubectl create -f kyverno/disable-default-appproject.yaml
Try creating an application as below and ensure that the creation fails with error message from kyverno admission controller.
kubectl apply -n anandf-tenant-ns -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
spec:
destination:
namespace: anandf-guestbook
server: https://kubernetes.default.svc
project: default
source:
directory:
recurse: true
path: guestbook
repoURL: https://github.com/argoproj/argocd-example-apps.git
syncPolicy:
automated: {}
syncOptions:
- CreateNamespace=true
EOF
kubectl create -f kyverno/restrict-application-project-reference.yaml
Try creating an application as below and ensure that the creation fails with error message from kyverno admission controller.
kubectl apply -n anandf-tenant-ns -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
spec:
destination:
namespace: jfischer-guestbook
server: https://kubernetes.default.svc
project: anandf-tenant
source:
directory:
recurse: true
path: guestbook
repoURL: https://github.com/argoproj/argocd-example-apps.git
syncPolicy:
automated: {}
syncOptions:
- CreateNamespace=true
EOF
Error from server: error when applying patch:
{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"argoproj.io/v1alpha1\",\"kind\":\"Application\",\"metadata\":{\"annotations\":{},\"name\":\"guestbook\",\"namespace\":\"anandf-tenant-ns\"},\"spec\":{\"destination\":{\"namespace\":\"anandf-guestbook\",\"server\":\"https://kubernetes.default.svc\"},\"project\":\"jfischer-tenant\",\"source\":{\"directory\":{\"recurse\":true},\"path\":\"guestbook\",\"repoURL\":\"https://github.com/argoproj/argocd-example-apps.git\"},\"syncPolicy\":{\"automated\":{},\"syncOptions\":[\"CreateNamespace=true\"]}}}\n"}},"spec":{"project":"jfischer-tenant"}}
to:
Resource: "argoproj.io/v1alpha1, Resource=applications", GroupVersionKind: "argoproj.io/v1alpha1, Kind=Application"
Name: "guestbook", Namespace: "anandf-tenant-ns"
for: "STDIN": error when patching "STDIN": admission webhook "validate.kyverno.svc-fail" denied the request:
resource Application/anandf-tenant-ns/guestbook was blocked due to the following policies
restrict-application-project-reference:
check-application-refers-allowed-project: Application must refer only projects allowed
for the tenant.
Create kyverno policy to allow creation of application with destination namespace having tenant ID as the prefix
kubectl create -f kyverno/restrict-destination-namespace.yaml
kubectl apply -n anandf-tenant-ns -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
spec:
destination:
namespace: anandf-guestbook
server: https://kubernetes.default.svc
project: anandf-tenant
source:
directory:
recurse: true
path: guestbook
repoURL: https://github.com/argoproj/argocd-example-apps.git
syncPolicy:
automated: {}
syncOptions:
- CreateNamespace=true
EOF
Error from server: error when applying patch:
{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"argoproj.io/v1alpha1\",\"kind\":\"Application\",\"metadata\":{\"annotations\":{},\"name\":\"guestbook\",\"namespace\":\"anandf-tenant-ns\"},\"spec\":{\"destination\":{\"namespace\":\"jfischer-guestbook\",\"server\":\"https://kubernetes.default.svc\"},\"project\":\"anandf-tenant\",\"source\":{\"directory\":{\"recurse\":true},\"path\":\"guestbook\",\"repoURL\":\"https://github.com/argoproj/argocd-example-apps.git\"},\"syncPolicy\":{\"automated\":{},\"syncOptions\":[\"CreateNamespace=true\"]}}}\n"}},"spec":{"destination":{"namespace":"jfischer-guestbook"}}}
to:
Resource: "argoproj.io/v1alpha1, Resource=applications", GroupVersionKind: "argoproj.io/v1alpha1, Kind=Application"
Name: "guestbook", Namespace: "anandf-tenant-ns"
for: "STDIN": error when patching "STDIN": admission webhook "validate.kyverno.svc-fail" denied the request:
resource Application/anandf-tenant-ns/guestbook was blocked due to the following policies
restrict-destination-namespace:
check-destination-namespace-has-tenant-id-prefix: Destination namespace of Application
must match the tenant id.
argocd app create anandf-tenant-ns/guestbook \
--project anandf-tenant \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-namespace anandf-guestbook \
--dest-server https://kubernetes.default.svc \
--directory-recurse \
--sync-policy auto \
--sync-option CreateNamespace=true
argocd app create jfischer-tenant-ns/guestbook \
--project jfischer-tenant \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-namespace jfischer-guestbook \
--dest-server https://kubernetes.default.svc \
--directory-recurse \
--sync-policy auto \
--sync-option CreateNamespace=true
kubectl patch cm argocd-cm -n argocd -p '{"data":{"application.sync.impersonation.enabled": "true"}}'
PASSWORD=$(kubectl get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d)
argocd login <instance_host> --username admin --password ${PASSWORD}
argocd proj create anandf-tenant
argocd proj create jfischer-tenant
Allow only destination namespace with tenant prefix matching their ID.
argocd proj add-destination anandf-tenant https://kubernetes.default.svc 'anandf-*'
argocd proj add-destination jfischer-tenant https://kubernetes.default.svc 'jfischer-*'
Allow only applications defined in their namespace to be used for each project
argocd proj add-source-namespace anandf-tenant anandf-tenant-ns
argocd proj add-source-namespace jfischer-tenant jfischer-tenant-ns
argocd proj add-source anandf-tenant 'https://github.com/anandf/*.git'
argocd proj add-source jfischer-tenant 'https://github.com/jfischer/*.git'
For tenant admins to be able to create namespaces as part of their application sync, allow users to create namespace.
argocd proj allow-cluster-resource anandf-tenant "" "Namespace"
argocd proj allow-cluster-resource jfischer-tenant "" "Namespace"
argocd proj add-destination-service-account anandf-tenant https://kubernetes.default.svc 'anandf-*' 'anandf-tenant-ns:anandf-admin-sa'
argocd proj add-destination-service-account jfischer-tenant https://kubernetes.default.svc 'jfischer-*' 'jfischer-tenant-ns:jfischer-admin-sa'
kubectl create sa -n anandf-tenant-ns anandf-admin-sa
kubectl create sa -n jfischer-tenant-ns jfischer-admin-sa
kubectl create role -n anandf-guestbook anandf-admin --verb='*' --resource="deployment.apps" --resource="service"
kubectl create rolebinding -n anandf-guestbook anandf-admin-sa-rb --role anandf-admin --serviceaccount anandf-tenant-ns:anandf-admin-sa
kubectl create role -n jfischer-guestbook jfischer-admin --verb='*' --resource="deployment.apps" --resource="service"
kubectl create rolebinding -n jfischer-guestbook jfischer-admin-sa-rb --role jfischer-admin --serviceaccount jfischer-tenant-ns:jfischer-admin-sa
argocd app create anandf-tenant-ns/guestbook \
--project anandf-tenant \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-namespace anandf-guestbook \
--dest-server https://kubernetes.default.svc \
--directory-recurse \
--sync-policy auto
argocd app create jfischer-tenant-ns/guestbook \
--project jfischer-tenant \
--repo https://github.com/argoproj/argocd-example-apps.git \
--path guestbook \
--dest-namespace jfischer-guestbook \
--dest-server https://kubernetes.default.svc \
--directory-recurse \
--sync-policy auto