// Module included in the following assemblies:
//
// deploying/assembly_deploy-standalone-operators.adoc

[id='deploying-the-user-operator-standalone-{context}']
= Deploying the standalone User Operator

[role="_abstract"]
This procedure shows how to deploy the User Operator as a standalone component for user management.
You can use a standalone User Operator with a Kafka cluster that is not managed by the Cluster Operator.

A standalone deployment can operate with any Kafka cluster.

Standalone deployment files are provided with Strimzi.
Use the `05-Deployment-strimzi-user-operator.yaml` deployment file to deploy the User Operator.
Add or set the environment variables needed to make a connection to a Kafka cluster.

The User Operator watches for `KafkaUser` resources in a single namespace.
You specify the namespace to watch, and the connection to the Kafka cluster, in the User Operator configuration.
A single User Operator can watch a single namespace.    
One namespace should be watched by only one User Operator.
If you want to use more than one User Operator, configure each of them to watch different namespaces. 
In this way, you can use the User Operator with multiple Kafka clusters.  

.Prerequisites

* You are running a Kafka cluster for the User Operator to connect to.
+
As long as the standalone User Operator is correctly configured for connection,
the Kafka cluster can be running on a bare-metal environment, a virtual machine, or as a managed cloud application service.

.Procedure

. Edit the following `env` properties in the `install/user-operator/05-Deployment-strimzi-user-operator.yaml` standalone deployment file.
+
.Example standalone User Operator deployment configuration
[source,shell,subs=+quotes]
----
apiVersion: apps/v1
kind: Deployment
metadata:
  name: strimzi-user-operator
  labels:
    app: strimzi
spec:
  # ...
  template:
    # ...
    spec:
      # ...
      containers:
        - name: strimzi-user-operator
          # ...
          env:
            - name: STRIMZI_NAMESPACE <1>
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: STRIMZI_KAFKA_BOOTSTRAP_SERVERS <2>
              value: my-kafka-bootstrap-address:9092
            - name: STRIMZI_CA_CERT_NAME <3>
              value: my-cluster-clients-ca-cert
            - name: STRIMZI_CA_KEY_NAME <4>
              value: my-cluster-clients-ca
            - name: STRIMZI_LABELS <5>
              value: "strimzi.io/cluster=my-cluster"
            - name: STRIMZI_FULL_RECONCILIATION_INTERVAL_MS <6>
              value: "120000"
            - name: STRIMZI_WORK_QUEUE_SIZE <7>
              value: 10000
            - name: STRIMZI_CONTROLLER_THREAD_POOL_SIZE <8>
              value: 10
            - name: STRIMZI_USER_OPERATIONS_THREAD_POOL_SIZE <9>
              value: 4
            - name: STRIMZI_LOG_LEVEL <10>
              value: INFO
            - name: STRIMZI_GC_LOG_ENABLED <11>
              value: "true"
            - name: STRIMZI_CA_VALIDITY <12>
              value: "365"
            - name: STRIMZI_CA_RENEWAL <13>
              value: "30"
            - name: STRIMZI_JAVA_OPTS <14>
              value: "-Xmx=512M -Xms=256M"
            - name: STRIMZI_JAVA_SYSTEM_PROPERTIES <15>
              value: "-Djavax.net.debug=verbose -DpropertyName=value"
            - name: STRIMZI_SECRET_PREFIX <16>
              value: "kafka-"
            - name: STRIMZI_ACLS_ADMIN_API_SUPPORTED <17>
              value: "true"
            - name: STRIMZI_MAINTENANCE_TIME_WINDOWS <18>
              value: '* * 8-10 * * ?;* * 14-15 * * ?'
            - name: STRIMZI_KAFKA_ADMIN_CLIENT_CONFIGURATION <19>
              value: |
                default.api.timeout.ms=120000
                request.timeout.ms=60000
            - name: STRIMZI_KRAFT_ENABLED <20>
              value: "false"
----
<1> The Kubernetes namespace for the User Operator to watch for `KafkaUser` resources. Only one namespace can be specified.
<2>  The host and port pair of the bootstrap broker address to discover and connect to all brokers in the Kafka cluster.
Use a comma-separated list to specify two or three broker addresses in case a server is down.
<3> The Kubernetes `Secret` that contains the public key (`ca.crt`) value of the CA (certificate authority) that signs new user certificates for mTLS authentication.
<4> The Kubernetes `Secret` that contains the private key (`ca.key`) value of the CA that signs new user certificates for mTLS authentication.
<5> The label to identify the `KafkaUser` resources managed by the User Operator.
This does not have to be the name of the Kafka cluster.
It can be the label assigned to the `KafkaUser` resource.
If you deploy more than one User Operator, the labels must be unique for each.
That is, the operators cannot manage the same resources.
<6> The interval between periodic reconciliations, in milliseconds.
The default is `120000` (2 minutes).
<7> The size of the controller event queue.
The size of the queue should be at least as big as the maximal amount of users you expect the User Operator to operate.
The default is `1024`.
<8> The size of the worker pool for reconciling the users.
Bigger pool might require more resources, but it will also handle more `KafkaUser` resources
The default is `50`.
<9> The size of the worker pool for Kafka Admin API and Kubernetes operations.
Bigger pool might require more resources, but it will also handle more `KafkaUser` resources
The default is `4`.
<10> The level for printing logging messages.
You can set the level to `ERROR`, `WARNING`, `INFO`, `DEBUG`, or `TRACE`.
<11> Enables garbage collection (GC) logging.
The default is `true`.
<12> The validity period for the CA.
The default is `365` days.
<13> The renewal period for the CA. The renewal period is measured backwards from the expiry date of the current certificate.
The default is `30` days to initiate certificate renewal before the old certificates expire.
<14> (Optional) The Java options used by the JVM running the User Operator
<15> (Optional) The debugging (`-D`) options set for the User Operator
<16> (Optional) Prefix for the names of Kubernetes secrets created by the User Operator.
<17> (Optional) Indicates whether the Kafka cluster supports management of authorization ACL rules using the Kafka Admin API.
When set to `false`, the User Operator will reject all resources with `simple` authorization ACL rules.
This helps to avoid unnecessary exceptions in the Kafka cluster logs.
The default is `true`.
<18> (Optional) Semi-colon separated list of Cron Expressions defining the maintenance time windows during which the expiring user certificates will be renewed.
<19> (Optional) Configuration options for configuring the Kafka Admin client used by the User Operator in the properties format.
<20> (Optional) Indicates whether the Kafka cluster the User Operator is connecting to is using KRaft instead of ZooKeeper.
Set this variable to `true` if the Kafka cluster uses KRaft.
The default is `false`.
Note that some features are not available when running against KRaft clusters. 
For example, management of SCRAM-SHA-512 users is disabled because Apache Kafka currently does not support it.

. If you are using mTLS to connect to the Kafka cluster, specify the secrets used to authenticate connection.
Otherwise, go to the next step.
+
.Example mTLS configuration
[source,shell,subs=+quotes]
----
# ....
env:
  - name: STRIMZI_CLUSTER_CA_CERT_SECRET_NAME <1>
    value: my-cluster-cluster-ca-cert
  - name: STRIMZI_EO_KEY_SECRET_NAME <2>
    value: my-cluster-entity-operator-certs
# ..."
----
<1> The Kubernetes `Secret` that contains the public key (`ca.crt`) value of the CA that signs Kafka broker certificates.
<2> The Kubernetes `Secret` that contains the certificate public key (`entity-operator.crt`) and private key (`entity-operator.key`) that is used for mTLS authentication against the Kafka cluster.

. Deploy the User Operator.
+
[source,shell,subs=+quotes]
kubectl create -f install/user-operator

. Check the status of the deployment:
+
[source,shell,subs="+quotes"]
----
kubectl get deployments
----
+
.Output shows the deployment name and readiness
[source,shell,subs="+quotes"]
----
NAME                   READY  UP-TO-DATE  AVAILABLE
strimzi-user-operator  1/1    1           1
----
+
`READY` shows the number of replicas that are ready/expected.
The deployment is successful when the `AVAILABLE` output shows `1`.
