camunda / camunda-platform-helm

Camunda Platform 8 Self-Managed Helm charts
https://docs.camunda.io/docs/self-managed/overview/
Apache License 2.0
69 stars 127 forks source link

[EPIC]: Add Identity #127

Closed Zelldon closed 2 years ago

Zelldon commented 2 years ago

Add Identity Application to the single chart. Dependency of #126.

Zelldon commented 2 years ago

Docker-compose: https://github.com/camunda-cloud/operate/pull/2415/files#diff-b358236a4158adf30757eb495bb0d551609faa7a3a796cac4d8d02d523d608ce

dlavrenuek commented 2 years ago

To set the keycloak admin credentials in identity (if it is changed from admin/admin) following env variables are used:

menski commented 2 years ago

For reference Operate Identity Integration: https://github.com/camunda-cloud/operate/pull/2415

Zelldon commented 2 years ago

Keycloak does it similar with their passwords, they create a default secret and mount it into the statefulset:

  containers:
        - name: keycloak
          image: docker.io/bitnami/keycloak:16.1.1-debian-10-r52
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsNonRoot: true
            runAsUser: 1001
          env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: BITNAMI_DEBUG
              value: "false"
            - name: KEYCLOAK_ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: zell-keycloak
                  key: admin-password
            - name: KEYCLOAK_MANAGEMENT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: zell-keycloak
                  key: management-password
            - name: KEYCLOAK_DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: zell-keycloak-postgresql
                  key: password

\cc @menski

Zelldon commented 2 years ago

Worth to read https://itnext.io/manage-auto-generated-secrets-in-your-helm-charts-5aee48ba6918

Zelldon commented 2 years ago

https://artifacthub.io/packages/helm/bitnami/common/1.3.4 is used to generate secrets

See https://github.com/bitnami/charts/blob/master/bitnami/keycloak/templates/secrets.yaml#L18-L19

AND setting in values file

https://github.com/bitnami/charts/blob/master/bitnami/keycloak/values.yaml#L109-L119

dlavrenuek commented 2 years ago

@Zelldon one thing I forgot to ask: is it possible to create file mounts from a remote source? We have a custom keycloak theme that we could add to a github release as f.e. a zip archive.

Zelldon commented 2 years ago

Hey @dlavrenuek it seems https://github.com/bitnami/charts/tree/master/bitnami/keycloak allows to configure init containers and extraVolumes, might be possible with that. But I think this would be something I would do only after we get it running :D So lower prio for me, maybe also something we can add later?

Zelldon commented 2 years ago

Just sorting my thoughts, reading along https://github.com/bitnami/charts/tree/master/bitnami/keycloak and https://docs.bitnami.com/kubernetes/apps/keycloak/configuration/manage-passwords/

Current idea:

We create a secret for keycloak (admin password) and for postegress (admin pw), mount that via keycloak.auth.existingSecret and keycloak.postgress.existingSecret. This secret contains default values like admin:admin, which is also mounted into identity.

The user can specify an own secret, which can be mounted than in keycloak, postgress and identity and replaces our default secrets. We will then not deploy own secrets.

Example secret:

existingSecret:
  name: mySecret
  keyMapping:
    admin-password: myPasswordKey
    management-password: myManagementPasswordKey
    database-password: myDatabasePasswordKey
    tls-keystore-password: myTlsKeystorePasswordKey
    tls-truststore-password: myTlsTruststorePasswordKey

https://docs.bitnami.com/kubernetes/apps/keycloak/configuration/manage-passwords/

\cc @menski

Zelldon commented 2 years ago

Small update:

I run a test where I deployed the following secret:

apiVersion: v1
kind: Secret
metadata:
  name: ccsm-keycloak-secrets
type: Opaque
stringData:
  admin-password: "admin"
  password: "admin"
  management-password: "admin"

This can be seen as our default secret we would deploy in our helm charts, (btw if we see the need this could also be random values). For simplicity with integrating with identity I sticked to the admin:admin thingy.

I run helm install zell-keycloak bitnami/keycloak --dry-run -f values.yaml --debug, to see what the manifests would look like.

The values file looks like this:

## Keycloak authentication parameters
## ref: https://github.com/bitnami/bitnami-docker-keycloak#admin-credentials
##
auth:
  ## @param auth.adminUser Keycloak administrator user
  ##
  adminUser: admin
  ## @param auth.existingSecret An already existing secret containing auth info
  ## e.g:
  ## existingSecret:
  ##   name: mySecret
  ##   keyMapping:
  ##     admin-password: myPasswordKey
  ##     management-password: myManagementPasswordKey
  ##     tls-keystore-password: myTlsKeystorePasswordKey
  ##     tls-truestore-password: myTlsTruestorePasswordKey
  ##
  ##
  existingSecret:
    name: ccsm-keycloak-secrets

postgresql:
  auth:
    existingSecret: "ccsm-keycloak-secrets"

This causes to deploy a keycloak with the following env vars:

...
      containers:
        - name: keycloak
          image: docker.io/bitnami/keycloak:16.1.1-debian-10-r52
          imagePullPolicy: IfNotPresent
          securityContext:
            runAsNonRoot: true
            runAsUser: 1001
          env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: BITNAMI_DEBUG
              value: "false"
            - name: KEYCLOAK_ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ccsm-keycloak-secrets
                  key: admin-password
            - name: KEYCLOAK_MANAGEMENT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ccsm-keycloak-secrets
                  key: management-password
            - name: KEYCLOAK_DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ccsm-keycloak-secrets
                  key: password

And postgress also uses our configured secret:

  containers:
        - name: postgresql
          image: docker.io/bitnami/postgresql:14.2.0-debian-10-r35
          imagePullPolicy: "IfNotPresent"
          securityContext:
            runAsUser: 1001
          env:
            - name: BITNAMI_DEBUG
              value: "false"
            - name: POSTGRESQL_PORT_NUMBER
              value: "5432"
            - name: POSTGRESQL_VOLUME_DIR
              value: "/bitnami/postgresql"
            - name: PGDATA
              value: "/bitnami/postgresql/data"
            # Authentication
            - name: POSTGRES_USER
              value: "bn_keycloak"
            - name: POSTGRES_POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ccsm-keycloak-secrets
                  key: postgres-password
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: ccsm-keycloak-secrets
                  key: password
            - name: POSTGRES_DB
              value: "bitnami_keycloak"

This now allows us to deploy the secret per default, and the user could potentially replace it with an own secret. We just need to configure identity similar, that it access the secret.

dlavrenuek commented 2 years ago

@Zelldon If it is possible to have all secrets being randomly generated, we should do it. Having default secrets will always lead to security risks because there will be users who forget to update it or just don't know/understand how to do it.

Zelldon commented 2 years ago

Hey @dlavrenuek and @menski

yesterday I made some good progress, and had a breakthrough :tada:

identity

All services where up and running and seem to connect to each other.

But there came up some questions form me which I would like to clarify, you can have a look at the changes here https://github.com/camunda/camunda-platform-helm/pull/251

BTW @dlavrenuek thanks for your input! I removed our default secret and reuse the secrets generated by the keycloak helm chart, which are random generated if not specified.

Questions:

  1. If I port forward to the identity and open it in the browser it redirects immediately to localhost:18080/ (you can see that URL in the image above). This seems to redirect to Keycloak? I Had to port-forward to Keycloak as well to see the login mask. Is this expected?
  2. What would be the credentials here to login? The admin user seem to not work here?
  3. Is there anything I can do to login via CLI? Or direct http requests and get a cookie ? I want to use that in our integration tests, to verify whether login works and I can access the other services. Does this make sense?

Would be really nice if you could check the questions above and maybe also have a small look at the PR #251 , whether the configuration makes sense to you.

menski commented 2 years ago

If I port forward to the identity and open it in the browser it redirects immediately to localhost:18080/ (you can see that URL in the image above). This seems to redirect to Keycloak? I Had to port-forward to Keycloak as well to see the login mask. Is this expected?

Yes this is expected right now as you need access to KeyCloaks web interface, it serves the Login page, but also you might want to login to keycloak to configure LDAP etc.

What would be the credentials here to login? The admin user seem to not work here?

As you are about to login to the Camunda Platform this are our default credentials demo:demo

Is there anything I can do to login via CLI? Or direct http requests and get a cookie ? I want to use that in our integration tests, to verify whether login works and I can access the other services. Does this make sense?

I will check it out, not sure yet

Zelldon commented 2 years ago

One think I saw during manually testing is that identity crashloops until keycloak is available, maybe we can add here a better handling. Like we do in operate/tasklist? @menski @dlavrenuek

dlavrenuek commented 2 years ago

@Zelldon a user can be added per env variables f.e. like here: https://github.com/camunda-cloud/identity/blob/main/docker-compose-e2e.yml#L37

or here without a name but with the Operate role to access operate: https://github.com/camunda-cloud/operate/blob/master/config/docker-compose.identity.yml#L26

Note that if Operate should be initialized in Identity, two additional values need to be added as in https://github.com/camunda-cloud/operate/blob/master/config/docker-compose.identity.yml#L24

      KEYCLOAK_INIT_OPERATE_SECRET: the-cake-is-alive
      KEYCLOAK_INIT_OPERATE_ROOT_URL: http://localhost:8080
Zelldon commented 2 years ago

Nice thanks @dlavrenuek this helps for the Operate integration I will do after https://github.com/camunda/camunda-platform-helm/pull/251 is merged and we have the next release candidate

dlavrenuek commented 2 years ago

@Zelldon is it possible to specify Keycloak as a dependency to Identity in a way so Identity is only started after Keycloak did? We do it in docker-compose with depends_on:... but it does not support a readiness probe, so the Identity container is restarted multiple times.

Zelldon commented 2 years ago

This is not possible in K8s, see also https://stackoverflow.com/a/53059163/2165134

Normally afaik applications retry and support a readiness and liveness check, here we can add a delay

Zelldon commented 2 years ago

Identity was successful integrated with all services and added to the helm charts