Deploy with Ansible¶
Deploy one OpenOP platform per operator, using existing Kubernetes clusters or Ubuntu VMs on which Ansible first installs k3s. With multiple operators, a separate playbook configures partner identities, agreements and federation.
What you end up with¶
Ansible runs Helm on the operator host to install the platform. SRM deploys application workloads into the oop-apps namespace.
flowchart LR
ctl["Ansible controller"]
host["Operator host<br/>Helm · kubectl · kubeconfig"]
subgraph cluster["Operator Kubernetes cluster"]
subgraph ns["Namespace oop · Helm release oop"]
public["Portal · OEG · FM"]
srm["SRM"]
deps["Keycloak · PostgreSQL · NATS"]
end
apps["Namespace oop-apps<br/>Application workloads"]
end
ctl -->|SSH| host
host -->|"helm upgrade --install"| ns
ctl -. "Public endpoint checks" .-> public
srm -->|"Helm / Kubernetes API"| apps
Each FM obtains a client-credentials token from the partner’s Keycloak and uses it to call the partner’s FM.
flowchart LR
subgraph A["operator-a"]
fmA["FM"]
kcA["Keycloak · federation realm<br/>Client: operator-b"]
end
subgraph B["operator-b"]
fmB["FM"]
kcB["Keycloak · federation realm<br/>Client: operator-a"]
end
fmA -->|"Get token as operator-a"| kcB
fmB -->|"Get token as operator-b"| kcA
fmA -->|"OPG.04 EWBI requests"| fmB
fmB -->|"OPG.04 EWBI requests"| fmA
Before you start¶
On the controller (the machine you run Ansible from):
- Python 3.12 or newer, Git, and SSH access to each remote operator host.
- network access to each operator's public platform endpoints for the deployment checks and end-to-end tests.
- For the end-to-end tests,
kubectland a kubeconfig for each operator's cluster.
For each operator:
- A Kubernetes cluster and, on the host Ansible connects to,
kubectl, Helm, the Python Kubernetes client and a kubeconfig for that cluster. The optional k3s playbook installs these tools and configures the kubeconfig. - A public address (
oop_platform_public_host) reachable by users, the controller and partner operators. With the default configuration, allow access to Keycloak30081, Portal30082when enabled, OEG32263and FM30989. - Resources for a complete platform, as listed in the Helm guide.
The example uses HTTP and NodePorts on a test network. Configure TLS, DNS and access to the container registry to suit your deployment environment.
Steps¶
1. Get the playbooks¶
git clone https://labs.etsi.org/rep/oop/deploy/ansible.git
cd ansible
git checkout v2.0.0-release
cd ansible
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
ansible-galaxy collection install -r requirements.yml
Every command below runs from this ansible/ansible folder, with the virtual environment active.
2. Write the inventory¶
Copy the example; *.local.yml files are ignored by Git:
Each operator is one host in the group oop_platform_operators. Replace the example addresses and set ansible_user in the group variables to your SSH user. ansible_host is the address used for SSH; oop_platform_public_host is the address clients and partner operators use to reach the platform.
all:
children:
oop_platform_operators:
vars:
ansible_user: ubuntu
oop_platform_chart_version: v2.0.0-release
oop_platform_fm_image_tag: "2.0.0"
oop_platform_oeg_image_tag: "2.0.0"
oop_platform_srm_image_tag: "2.0.0"
oop_platform_portal_enabled: true
oop_platform_portal_image_tag: "2.0.0"
oop_platform_allow_insecure_partner_endpoints: true # plain HTTP between operators
oop_platform_extra_values: # lets SRM deploy apps into oop-apps
srm:
workloads:
namespaces: [oop-apps]
# ... plus oop_platform_partner_agreement and oop_platform_bootstrap,
# copied unchanged from r2.example.yml
hosts:
operator_a:
ansible_host: 192.0.2.10
oop_platform_public_host: 192.0.2.10
oop_platform_federation_id: operator-a
oop_platform_country_code: ES
oop_platform_mcc: "214"
oop_platform_mncs: ["07"]
oop_platform_federation_clients: [operator-b]
srm_zone_name: Barcelona
operator_b:
ansible_host: 192.0.2.20
oop_platform_public_host: 192.0.2.20
oop_platform_federation_id: operator-b
oop_platform_country_code: FR
oop_platform_mcc: "208"
oop_platform_mncs: ["01"]
oop_platform_federation_clients: [operator-a]
srm_zone_name: Paris
What matters most:
- Versions. Set the chart and the four image tags as above. The example file in the
v2.0.0-releasetag still carries the pre-release values (a chart commit,ci-develop-*images, and the portal turned off), so don't keep them. For an API-only deployment, setoop_platform_portal_enabled: falseand follow the API instructions in the federation tutorial. - Federation identity.
oop_platform_federation_ididentifies this operator to its partners and is the Keycloak client ID those partners create for it.oop_platform_federation_clientslists partners accepted by this operator. For federation, configure these lists reciprocally. - Zones. The example’s
oop_platform_bootstrapdeclares one zone per operator, named bysrm_zone_name, with applications running in namespaceoop-appson that operator’s cluster.oop_platform_partner_agreementdefines the zones and resource terms offered to partners, including the available resource profiles (flavours). - Application endpoints. In the Kubernetes control path's
infrastructure, setendpoint_hostto the address application clients use to reach workload NodePorts. For the sample in-cluster backend, useendpoint_host: "{{ oop_platform_public_host }}"when that public address reaches the workload ports. See Kubernetes for local and remote connection settings. - Plain Ubuntu VMs. Also add the hosts to the group
k3s_nodes. A host whosek3s_servernames another host joins that one as an agent; the commented block at the end ofr2.example.ymlshows how. - Secrets. When secret variables are unset, the chart generates the values and stores them in the cluster. For deployments you need to preserve, back up the generated credentials securely or provide your own through Ansible Vault before the first installation.
3. Install k3s, only if needed¶
The playbook installs k3s on the hosts in k3s_nodes, waits for the nodes to become Ready, and prepares the server hosts with a kubeconfig and the tools needed to deploy OpenOP. Skip this step when using existing Kubernetes clusters.
4. Deploy one platform per operator¶
For each operator, the role validates the inventory, checks the FM partner and OEG callback encryption keys against any values supplied through Vault, fetches the selected Helm chart and installs or upgrades the platform. It then checks readiness and the public endpoints from the controller, and prints a deployment summary.
The run ends with one summary per operator:
OOP Release 2 is up on operator_a (namespace oop).
Portal: http://192.0.2.10:30082
OEG: http://192.0.2.10:32263
Federation (FM): http://192.0.2.10:30989
Partner tokens: http://192.0.2.10:30081/realms/federation
Generated in the cluster and stored nowhere else:
- Federation Manager partner secret key (federation-manager-keys)
- OEG callback key (oegcontroller-keys)
- database passwords (postgres-credentials)
- Keycloak admin password (keycloak-credentials)
Re-run the same command to apply inventory changes to an existing deployment. See Known issues when changing the chart version.
5. Federate the operators¶
The playbook needs access to all participating operators in the inventory. For each pair, it:
- Retrieves the partner client credentials from Keycloak.
- Registers each operator as a partner in the other’s FM.
- Applies the agreements defined by
oop_platform_partner_agreement. - Creates the federation contexts using OPG.04
CreateFederation.
If an agreement was edited in the Portal, the next run restores the inventory’s terms.
The playbook does not subscribe to the partner’s zones, and applications can’t be deployed in a partner zone until you do. Subscribe in each operator’s Portal, or through the API, as in Federate two operators › Subscribe to the partner’s zone. The same tutorial shows every step by hand.
Check it worked¶
The tests create temporary Keycloak clients on each platform and remove them after the run.
pip install -r tests/r2_e2e/requirements.txt
ansible-playbook -i inventory/r2.local.yml playbooks/scenarios/r2_existing_cluster/e2e.yml
| Test file | What it checks |
|---|---|
test_platform.py |
Keycloak issuers, OEG/FM availability and operator identity |
test_auth.py |
token rejection and partner access restrictions |
test_federation.py |
partner registry, federation lifecycle, FM restart and offered zones |
test_apps.py |
application registration, listing, retrieval and deletion |
test_exposure.py |
isolation of FM’s internal API from public access |
Pass extra pytest arguments with -e '{"e2e_pytest_args":"-k federation"}', for example to select federation-related tests.
The release tag still marks test_apps_are_private_to_their_tenant as an expected failure. OEG 2.0.0 now passes that read/delete isolation check, so pytest reports XPASS(strict) and fails the run. See Known issues for the workaround.
First, check federation status in each operator’s Portal. Sign in with the operator role and open Federation. Each configured partner should appear as active and Federated.
Then, check the platform services from each operator host. Use the kubeconfig and platform namespace configured in that operator’s inventory entry:
kubectl --kubeconfig OPERATOR_KUBECONFIG -n oop get pods
curl --fail-with-body -sS http://OPERATOR_PUBLIC_HOST:30989/healthz
Replace the placeholders with that operator’s inventory values; change oop if its platform namespace differs. Expect the platform pods to be ready and the FM health response to be {"status":"ok"}.
Remove it¶
This runs helm uninstall and waits for completion. The chart retains its generated Secrets and volumes, allowing a later deployment to reuse the stored data.
To remove the retained Secrets and PVCs as well, delete the platform namespace after uninstalling the release.
If k3s was installed for this setup, you can also remove it with:
ansible-playbook -i inventory/r2.local.yml playbooks/infrastructure/k3s/undeploy.yml -e k3s_confirm_uninstall=true
This removes k3s, its workloads and locally stored cluster data from those machines.
Known issues¶
Changing the chart version. Deployment may fail at Fetch the chart because of the cached shallow checkout. Remove the cached Helm repository on the affected operator host and rerun deploy.yml. Its default location is ~/.cache/oop-platform/<inventory-host>/helm.
A test reports XPASS(strict). For v2.0.0-release, run the remaining tests while excluding the case with the outdated expected-failure mark:
ansible-playbook -i inventory/r2.local.yml playbooks/scenarios/r2_existing_cluster/e2e.yml \
-e '{"e2e_pytest_argv":["-k","not test_apps_are_private_to_their_tenant"]}'
All options¶
See the scenario README for the full inventory reference, Secrets and Vault variables, agreement settings and partners outside the inventory (oop_platform_partners). Variable defaults are in roles/oop-platform/defaults/main.yml.
Use oop_platform_extra_values for additional chart settings. Configure topology and control-path credentials through oop_platform_bootstrap, as described in Define zones and Kubernetes integration.