> For the complete documentation index, see [llms.txt](https://experience-digital-transform.gitbook.io/experience-digital-transformation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://experience-digital-transform.gitbook.io/experience-digital-transformation/national-learner-registry/deployment-and-system-integration/rke2-cluster-deployment-and-liquio-platform-configuration-guide/liquio-platform-configuration.md).

# Liquio Platform Configuration

## Argo CD and Manifest Configuration

Create a repository. In the GitLab instance, create an empty (without README) `kitsoft/k8s-manifests-<customer>-prod` repository and push the manifests provided by the developer:

```bash
cd /<path>/liquio/manifests
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://git.<customer>.gov.ua/kitsoft/k8s-manifests-<customer>-prod
git push -u origin main
```

`/<path>/liquio/manifests` is the directory the manifests from the developer's disk were copied into.

**MetalLB** — replace the IP address pool in `ip-pool.yaml` with available addresses from the cluster subnet, verify, and push:

```bash
cat manifests/metallb/ip-pool.yaml
git add manifests/metallb/ip-pool.yaml
git commit -m 'adjust ip pool'
git push origin master
```

**Traefik** — replace `loadBalancerIP` in `manifests/traefik/application-external.yaml` with one of the addresses from the MetalLB pool, then verify:

```bash
cat manifests/traefik/application-external.yaml
```

**Ceph** (optional, when Longhorn is not used — e.g. in the `ioc` environment) — in `manifests/ceph-csi-rbd/release.yaml`, replace `clusterID`, `monitors`, and `pool`, then decrypt, edit, re-encrypt, and push the secret:

```bash
sops -i -d manifests/ceph-csi-rbd/secret.yaml
# replace userID and userKey in manifests/ceph-csi-rbd/secret.yaml
sops -i -e manifests/ceph-csi-rbd/secret.yaml
git add manifests/ceph-csi-rbd/secret.yaml
git commit -m 'set up ceph'
git push origin master
```

**Argo CD** — install it, apply its secrets, and point it at the manifest repository:

```bash
helm upgrade -n argocd --install --create-namespace argocd oci://ghcr.io/argoproj/argo-helm/argo-cd --values ./argocd-values.yaml --version 9.3.4

sops -i -d argocd-age-secret.yaml
sops -i -d argocd-repo-secret.yaml
kubectl apply -f argocd-age-secret.yaml
kubectl apply -f argocd-repo-secret.yaml
git checkout argocd-age-secret.yaml
git checkout argocd-repo-secret.yaml

kubectl apply -f argocd-repo-app.yaml
```

Wait 5–10 minutes, then log in to Argo CD and verify that everything has synced:

```bash
kubectl port-forward svc/argocd-server 8080:80 -n argocd
# open https://localhost:8080
```

## Liquio Platform Configuration

### Vault

Decrypt the Vault configuration and retrieve the access details from `poprodres`:

```bash
sops -i -d manifests/vault/vault-secret.yaml

kubectl get secret -n vault poprodres-vault-cluster-app \
   -o jsonpath='{.data.fqdn-uri}' | base64 -d && echo
```

Set this URI as `connection_url` in `vault-secret.yaml`, verify, re-encrypt, and push:

```bash
cat manifests/vault/vault-secret.yaml

sops -i -e manifests/vault/vault-secret.yaml
git add manifests/vault/vault-secret.yaml
git commit -m 'set vault poprodres'
git push origin master
```

Wait for Argo CD to synchronize, verify the applied change, and restart Vault:

```bash
kubectl get secret -n vault vault-config \
  -o go-template='{{ index .data "config.hcl" | base64decode }}'

kubectl rollout restart statefulset vault -n vault
```

Configure local auto-unseal, saving the command's output:

```bash
./vault.sh -v vault -c ioc -e prod -u manual -n '*' -d manifests/vault
```

Apply the generated secrets:

```bash
mv manifests/vault/vault-unseal-keys-ioc_prod.yaml manifests/vault/vault-unseal-keys-secret.yaml
sops -i -e manifests/vault/vault-unseal-keys-secret.yaml
git add manifests/vault/vault-unseal-keys-secret.yaml
git commit -m 'add vault secret'
git push origin master
```

Log in to the Vault UI:

```bash
kubectl port-forward svc/vault-0 8200 -n vault
# open http://localhost:8200
```

### Config Manager

Before generating service configurations with `config-manager`, confirm Node.js is installed:

```bash
node -v
```

If necessary, install it (example for Ubuntu 24.04):

```bash
sudo curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && \
sudo apt-get install -y nodejs && \
sudo npm install -g npm@latest
```

On first use on a workstation, clone the project and install dependencies:

```bash
git clone git@gitlab..../config-manager.git
cd .../config-manager
npm i
```

Copy `.env.example` to `.env`, generate a new `secret-id`, and read the `role-id` (both can be run in the Vault web CLI):

```bash
vault write -force auth/approle/role/configmanager/secret-id
vault read auth/approle/role/configmanager/role-id
```

Enter the parameters obtained during the Vault installation and connect to the Vault UI. Then, for each environment (`<project>`):

* Create the `configurator/services/<project>` secret in Vault and copy in the contents of `templates/services/<project>.json`.
* Create the `configurator/templates/secrets` secret in Vault and copy in the contents of `templates/secrets.json`.
* Create the `configurator/templates/<project>` secret in Vault and copy in the contents of `templates/<project>.json`.

Run the configuration verification command from the `config-manager` root directory:

```bash
bin/config-manager --service <project> --diff --test
```

If there are no errors, generate the new or updated configurations:

```bash
bin/config-manager --service <project> -w
```

If parameter values need to change, update the `<project>/prod.secrets` secret, then re-run the verify-and-apply sequence:

```bash
bin/config-manager --service <project> --diff --test
bin/config-manager --service <project> -w
```

### RabbitMQ

Decrypt the file, add the passwords generated by Config Manager, re-encrypt, and push:

```bash
sops -i -d manifests/rabbitmq/rabbitmq-load-definitions-secret.yaml
# add the passwords generated by config manager
sops -i -e manifests/rabbitmq/rabbitmq-load-definitions-secret.yaml
git add manifests/rabbitmq/rabbitmq-load-definitions-secret.yaml
git commit -m 'add rabbitmq credentials'
git push origin master
```

Wait until Argo CD applies the change, then restart RabbitMQ:

```bash
kubectl rollout restart statefulset/rabbitmq-server -n rabbitmq
```

## Setting Hosts for Services

Use this configuration when NAT reflection is not configured on the firewall. Create `coredns-hosts.yaml`:

```yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: rke2-coredns
  namespace: kube-system
spec:
  valuesContent: |-
    zoneFiles:
      - filename: example.gov.ua.conf
        domain: example.gov.ua
        contents: |
          example.gov.ua {
            hosts {
              # october
              10.100.14.135 example.gov.ua

              # liquio
              10.100.14.135 admin.example.gov.ua
              10.100.14.135 admin-api.example.gov.ua
              10.100.14.135 cabinet.example.gov.ua
              10.100.14.135 cabinet-api.example.gov.ua
              10.100.14.135 id.example.gov.ua
              10.100.14.135 qr.example.gov.ua
              10.100.14.135 plink.example.gov.ua
              10.100.14.135 superset.example.gov.ua

              ttl 60
              fallthrough
            }
            forward . /etc/resolv.conf
          }
    extraConfig:
      import:
        parameters: /etc/coredns/*.conf
```

Apply it:

```bash
kubectl apply -f coredns-hosts.yaml
```

## Running Internal Service Checks

Run the following and verify that none of the results contain `false`:

```bash
curl https://cabinet-api-bpmn-<customer>-prod.kitsoft.ua/test/ping/services | jq
```

## Granting Administrator Privileges to a User

Find the user in the ID database, either directly or by national ID (TIN):

```sql
select * from users;
-- or search by TIN:
select * from users where ipn = 'xxxxxxxxxxxx';
```

In the ID database, grant the admin role:

```sql
update users
set role = 'individual;admin'
where "userId" = 'xxxxxxxxxxxxxxxxxxxxxxxx';
```

In the `bpmn` database, add the user to the relevant administrative units:

```sql
UPDATE units
SET updated_at = now(),
	members = members || ARRAY ['xxxxxxxxxxxxxxxxxxxxxxxx']::character varying[]
WHERE id in (1000012,1000001,1000002,1000003);
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://experience-digital-transform.gitbook.io/experience-digital-transformation/national-learner-registry/deployment-and-system-integration/rke2-cluster-deployment-and-liquio-platform-configuration-guide/liquio-platform-configuration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
