{"id":18429115,"url":"https://github.com/openliberty/guide-kubernetes-microprofile-config","last_synced_at":"2025-04-07T17:32:42.009Z","repository":{"id":34481669,"uuid":"150163149","full_name":"OpenLiberty/guide-kubernetes-microprofile-config","owner":"OpenLiberty","description":"A guide on how to externalize configuration using MicroProfile Config and configure your microservices using Kubernetes ConfigMaps and Secrets: https://openliberty.io/guides/kubernetes-microprofile-config.html","archived":false,"fork":false,"pushed_at":"2025-03-04T21:52:37.000Z","size":525,"stargazers_count":15,"open_issues_count":3,"forks_count":26,"subscribers_count":5,"default_branch":"prod","last_synced_at":"2025-03-22T21:51:09.979Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenLiberty.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-24T20:18:16.000Z","updated_at":"2025-03-04T21:52:41.000Z","dependencies_parsed_at":"2023-11-24T20:29:49.007Z","dependency_job_id":"f6e92ef2-c04a-4b66-8ead-9feffab2dec4","html_url":"https://github.com/OpenLiberty/guide-kubernetes-microprofile-config","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-microprofile-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-microprofile-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-microprofile-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-microprofile-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenLiberty","download_url":"https://codeload.github.com/OpenLiberty/guide-kubernetes-microprofile-config/tar.gz/refs/heads/prod","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247697939,"owners_count":20981275,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T05:15:52.835Z","updated_at":"2025-04-07T17:32:41.655Z","avatar_url":"https://github.com/OpenLiberty.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"// Copyright (c) 2018, 2024 IBM Corporation and others.\n// Licensed under Creative Commons Attribution-NoDerivatives\n// 4.0 International (CC BY-ND 4.0)\n//   https://creativecommons.org/licenses/by-nd/4.0/\n//\n// Contributors:\n//     IBM Corporation\n//\n:projectid: kubernetes-microprofile-config\n:page-layout: guide-multipane\n:page-duration: 15 minutes\n:page-releasedate: 2018-10-12\n:page-description: Externalize configuration and use Kubernetes ConfigMaps and Secrets to configure your microservices.\n:page-tags: ['kubernetes', 'docker', 'microprofile']\n:page-permalink: /guides/{projectid}\n:page-related-guides: ['kubernetes-intro', 'microprofile-config', 'cdi-intro', 'docker']\n:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod\n:source-highlighter: prettify\n:page-seo-title: Configuring Java microservices on Kubernetes with Eclipse MicroProfile Config \n:page-seo-description: A getting started tutorial with examples of how to externalize configuration with Eclipse MicroProfile Config and use Kubernetes ConfigMaps and Secrets to configure your Java microservices.\n:guide-author: Open Liberty\n= Configuring microservices running in Kubernetes\n\n[.hidden]\nNOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website].\n\nExplore how to externalize configuration using MicroProfile Config and configure your microservices using Kubernetes ConfigMaps and Secrets.\n\n:minikube-ip: 192.168.99.100\n:kube: Kubernetes\n:system-api: http://[hostname]:31000/system/properties\n:inventory-api: http://[hostname]:32000/inventory/systems\n:win: WINDOWS\n:mac: MAC\n:linux: LINUX\n\n// =================================================================================================\n// What you'll learn\n// =================================================================================================\n\n== What you'll learn\nYou will learn how and why to externalize your microservice's configuration. Externalized configuration is useful because configuration usually changes depending on your environment. You will also learn how to configure the environment by providing required values to your application using {kube}.\n\nMicroProfile Config provides useful annotations that you can use to inject configured values into your code. These values can come from any configuration source, such as environment variables. Using environment variables allows for easier deployment to different environments. To learn more about MicroProfile Config, read the https://openliberty.io/guides/microprofile-config.html[Configuring microservices^] guide.\n\nFurthermore, you'll learn how to set these environment variables with ConfigMaps and Secrets. These resources are provided by {kube} and act as a data source for your environment variables. You can use a ConfigMap or Secret to set environment variables for any number of containers.\n\n// =================================================================================================\n// Prerequisites\n// =================================================================================================\n[role='command']\ninclude::{common-includes}/kube-prereq.adoc[]\n\n// =================================================================================================\n// Getting Started\n// =================================================================================================\n[role='command']\ninclude::{common-includes}/gitclone.adoc[]\n\n// =================================================================================================\n// Starting and preparing your cluster for deployment\n// =================================================================================================\n// Static guide instruction\nifndef::cloud-hosted[]\n[role='command']\ninclude::{common-includes}/kube-start.adoc[]\nendif::[]\n\n== Deploying the microservices\n\nThe two microservices you will deploy are called `system` and `inventory`. The `system` microservice returns the JVM system properties of the running container. The `inventory` microservice adds the properties from the `system` microservice to the inventory. This demonstrates how communication can be established between pods inside a cluster. To build these applications, navigate to the `start` directory and run the following command.\n\n[role='command']\n```\ncd start\nmvn clean package\n```\n\n\n\nNext, run the `docker build` commands to build container images for your application:\n[role='command']\n```\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n```\n\nThe `-t` flag in the `docker build` command allows the Docker image to be labeled (tagged) in the `name[:tag]` format. The tag for an image describes the specific image version. If the optional `[:tag]` tag is not specified, the `latest` tag is created by default.\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nPush your images to the container registry on IBM Cloud with the following commands:\n\n```bash\ndocker tag inventory:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker tag system:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\n```\n\nUpdate the image names and set the image pull policy to **Always** so that the images in your IBM Cloud container registry are used, and remove the **nodePort** fields so that the ports can be automatically generated:\n\n```bash\nsed -i 's=system:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/system:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=inventory:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/inventory:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=nodePort: 31000==g' kubernetes.yaml\nsed -i 's=nodePort: 32000==g' kubernetes.yaml\n```\nendif::[]\n\nRun the following command to deploy the necessary {kube} resources to serve the applications.\n[role='command']\n```\nkubectl apply -f kubernetes.yaml\n```\n\nWhen this command finishes, wait for the pods to be in the Ready state. Run the following command to view the status of the pods.\n[role='command']\n```\nkubectl get pods\n```\n\nWhen the pods are ready, the output shows `1/1` for READY and `Running` for STATUS.\n\n[source, role=\"no_copy\"]\n----\nNAME                                   READY     STATUS    RESTARTS   AGE\nsystem-deployment-6bd97d9bf6-6d2cj     1/1       Running   0          34s\ninventory-deployment-645767664f-7gnxf  1/1       Running   0          34s\n----\n\nAfter the pods are ready, you will make requests to your services.\n\n// Static guide instruction\nifndef::cloud-hosted[]\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\nThe default host name for Docker Desktop is `localhost`.\n--\n\n[.tab_content.linux_section]\n--\nThe default host name for minikube is {minikube-ip}. Otherwise it can be found using the `minikube ip` command.\n--\n\nNavigate to `{system-api}` and use the username `bob` and the password `bobpwd` to authenticate. Replace `[hostname]` with the IP address or host name of your {kube} cluster. Open your browser's developer console and examine the response headers.\n\nYou can also run the `curl` command to make requests to your microservices. Use the `-u` option to pass in the username `bob` and the password `bobpwd`.\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\ncurl http://localhost:31000/system/properties -u bob:bobpwd\n```\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^]. Postman enables you to make requests using a graphical interface. To make a request with Postman, enter `\\http://localhost:31000/system/properties` into the URL bar. Next, set the `Authorization` with `Basic Auth` type. Set the `Username` field to `bob` and the `Password` field to `bobpwd`. Read the https://learning.postman.com/docs/sending-requests/authorization/#basic-auth[Authorizing requests^] document for more details. Finally, click the blue `Send` button to make the request.\n--\n\n[.tab_content.mac_section]\n--\n[role=command]\n```\ncurl http://localhost:31000/system/properties -u bob:bobpwd\n```\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl http://$(minikube ip):31000/system/properties -u bob:bobpwd\n```\n--\n\nSimilarly, navigate to `{inventory-api}/system-service`, or use the following `curl` command to add the system to your inventory.\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[role=command]\n```\ncurl http://localhost:32000/inventory/systems/system-service\n```\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl http://$(minikube ip):32000/inventory/systems/system-service\n```\n--\n\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nIn this IBM cloud environment, you need to set up port forwarding to access the services. Open another command-line session by selecting **Terminal** \u003e **New Terminal** from the menu of the IDE. Run the following commands to set up port forwarding to access the **system** service.\n```bash\nSYSTEM_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services system-service`\nkubectl port-forward svc/system-service $SYSTEM_NODEPORT:9090\n```\n\nThen, open another command-line session by selecting **Terminal** \u003e **New Terminal** from the menu of the IDE. Run the following commands to set up port forwarding to access the **inventory** service.\n```bash\nINVENTORY_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services inventory-service`\nkubectl port-forward svc/inventory-service $INVENTORY_NODEPORT:9090\n```\n\nThen use the following commands to access your **system** microservice. The ***-u*** option is used to pass in the username ***bob*** and the password ***bobpwd***.\n```bash\nSYSTEM_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services system-service`\ncurl -s http://localhost:$SYSTEM_NODEPORT/system/properties -u bob:bobpwd | jq\n```\n\nUse the following commands to access your ***inventory*** microservice.\n```bash\nINVENTORY_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services inventory-service`\ncurl -s http://localhost:$INVENTORY_NODEPORT/inventory/systems/system-service | jq\n```\n\nWhen you're done trying out the microservices, press **CTRL+C** in the command line sessions where you ran the ***kubectl port-forward*** commands to stop the port forwarding.\nendif::[]\n\n== Modifying system microservice\n\nThe `system` service is hardcoded to use a single forward slash as the context root. The context root is set in the [hotspot=webApplication file=0]`webApplication`\nelement, where the `contextRoot` attribute is specified as `\"/\"`. You'll make the value of the `contextRoot` attribute configurable by implementing it as a variable.\n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"]\n----\n#Replace the `server.xml` file.#\n`system/src/main/liberty/config/server.xml`\n----\n\n// File 0\nserver.xml\n[source, xml, linenums, role='code_column hide_tags=copyright']\n----\ninclude::finish/system/src/main/liberty/config/server.xml[]\n----\n\nThe `contextRoot` attribute in the [hotspot=webApplication file=0]`webApplication` element now gets its value from the [hotspot=context.root file=0]`context.root` variable. To find a value for the `context.root` variable, Open Liberty looks for the following environment variables, in order:\n\n// Static guide instruction\nifndef::cloud-hosted[]\n* `context.root`\n* `context_root`\n* `CONTEXT_ROOT`\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\n* `context.root`\n* `context_root`\n* `CONTEXT_ROOT`\nendif::[]\n\n== Modifying inventory microservice\n\nThe `inventory` service is hardcoded to use `bob` and `bobpwd` as the credentials to authenticate against the `system` service. You'll make these credentials configurable. \n\n[role=\"code_command hotspot file=0\", subs=\"quotes\"]\n----\n#Replace the `SystemClient` class.#\n`inventory/src/main/java/io/openliberty/guides/inventory/client/SystemClient.java`\n----\n\nSystemClient.java\n[source, java, linenums, role='code_column hide_tags=copyright']\n----\ninclude::finish/inventory/src/main/java/io/openliberty/guides/inventory/client/SystemClient.java[]\n----\n\nThe changes introduced here use MicroProfile Config and CDI to inject the value of the environment variables [hotspot=context-root hotspot=context-root1]`CONTEXT_ROOT`, [hotspot=system-app-username]`SYSTEM_APP_USERNAME` and [hotspot=system-app-password]`SYSTEM_APP_PASSWORD` into the [hotspot file=0]`SystemClient` class.\n\n\n== Creating a ConfigMap and Secret\n\nSeveral options exist to configure an environment variable in a Docker container. You can set it directly in the [hotspot file=1]`Dockerfile` with the `ENV` command. You can also set it in your [hotspot file=0]`kubernetes.yaml` file by specifying a name and a value for the environment variable that you want to set for a specific container. With these options in mind, you're going to use a ConfigMap and Secret to set these values. These are resources provided by Kubernetes as a way to provide configuration values to your containers. A benefit is that they can be reused across many different containers, even if they all require different environment variables to be set with the same value.\n\nCreate a ConfigMap to configure the app name with the following `kubectl` command.\n[role='command']\n```\nkubectl create configmap sys-app-root --from-literal contextRoot=/dev\n```\n\nThis command deploys a ConfigMap named `sys-app-root` to your cluster. It has a key called `contextRoot` with a value of `/dev`. The `--from-literal` flag allows you to specify individual key-value pairs to store in this ConfigMap. Other available options, such as `--from-file` and `--from-env-file`, provide more versatility as to what you want to configure. Details about these options can be found in the https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-configmap-em-[{kube} CLI documentation^].\n\nRun the following command to display details of the ConfigMap.\n[role='command']\n```\nkubectl describe configmaps sys-app-root\n```\n\nCreate a Secret to configure the new credentials that `inventory` uses to authenticate against `system` with the following `kubectl` command.\n[role='command']\n```\nkubectl create secret generic sys-app-credentials --from-literal username=alice --from-literal password=wonderland\n```\n \nThis command looks similar to the command to create a ConfigMap, but one difference is the word `generic`. This word creates a Secret that doesn't store information in any specialized way. Different types of secrets are available, such as secrets to store Docker credentials and secrets to store public and private key pairs.\n\nRun the following command to display details of the Secret.\n[role='command']\n```\nkubectl describe secrets/sys-app-credentials\n```\n\nA Secret is similar to a ConfigMap. A key difference is that a Secret is used for confidential information such as credentials. One of the main differences is that you must explicitly tell `kubectl` to show you the contents of a Secret. Additionally, when it does show you the information, it only shows you a Base64 encoded version so that a casual onlooker doesn't accidentally see any sensitive data. Secrets don't provide any encryption by default, that is something you'll either need to do yourself or find an alternate option to configure. Encryption is not required for the application to run.\n\nkubernetes.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/kubernetes.yaml[]\n----\n\nDockerfile\n[source, text, linenums, role='code_column']\n----\ninclude::finish/system/Dockerfile[]\n----\n\n== Updating {kube} resources\n\nNext, you will update your {kube} deployments to set the environment variables in your containers based on the values that are configured in the ConfigMap and Secret that you created previously. \n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Replace the kubernetes file.#\n`kubernetes.yaml`\n----\n\nkubernetes.yaml\n[source, yaml, linenums, role='code_column']\n----\ninclude::finish/kubernetes.yaml[]\n----\n\nThe [hotspot=contextRoot1 hotspot=contextRoot2 file=0]`CONTEXT_ROOT`, [hotspot=sysUsername1 hotspot=sysUsername2 file=0]`SYSTEM_APP_USERNAME`, and [hotspot=sysPassword1 hotspot=sysPassword2 file=0]`SYSTEM_APP_PASSWORD` environment variables are set in the [hotspot=env1 hotspot=env2 file=0]`env` sections of [hotspot=system-container file=0]`system-container` and [hotspot=inventory-container file=0]`inventory-container`.\n\nUsing the [hotspot=valueFrom1 hotspot=valueFrom2 hotspot=valueFrom3 hotspot=valueFrom4 hotspot=valueFrom5 hotspot=valueFrom6 file=0]`valueFrom` field, you can specify the value of an environment variable from various sources. These sources include a ConfigMap, a Secret, and information about the cluster. In this example [hotspot=configRef1 hotspot=configRef2 file=0]`configMapKeyRef` gets the value [hotspot=contextRootKey1 hotspot=contextRootKey2 file=0]`contextRoot` from the [hotspot=root1 hotspot=root2 file=0]`sys-app-root` ConfigMap. Similarly, [hotspot=secretRef1 hotspot=secretRef2 hotspot=secretRef3 hotspot=secretRef4 file=0]`secretKeyRef` gets the values [hotspot=username1 hotspot=username2 file=0]`username` and [hotspot=password1 hotspot=password2 file=0]`password` from the [hotspot=credentials1 hotspot=credentials2 hotspot=credentials3 hotspot=credentials4 file=0]`sys-app-credentials` Secret.\n\n\n== Deploying your changes\n\n// Static guide instruction\nifndef::cloud-hosted[]\nRebuild the application using `mvn clean package`.\n[role='command']\n```\nmvn clean package\n```\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nRebuild the application using ***mvn clean package***.\n```bash\ncd /home/project/guide-kubernetes-microprofile-config/start\nmvn clean package\n```\nendif::[]\n\nRun the `docker build` commands to rebuild container images for your application:\n[role='command']\n```\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n```\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\n\nPush your updated images to the container registry on IBM Cloud with the following commands:\n\n```bash\ndocker tag inventory:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker tag system:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\n```\n\nUpdate the image names and set the image pull policy to **Always** so that the images in your IBM Cloud container registry are used, and remove the **nodePort** fields so that the ports can be automatically generated:\n\n```bash\nsed -i 's=system:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/system:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=inventory:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/inventory:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=nodePort: 31000==g' kubernetes.yaml\nsed -i 's=nodePort: 32000==g' kubernetes.yaml\n```\nendif::[]\n\nRun the following command to deploy your changes to the {kube} cluster.\n[role='command']\n```\nkubectl replace --force -f kubernetes.yaml\n```\n\nWhen this command finishes, wait for the pods to be in the Ready state. Run the following command to view the status of the pods.\n[role='command']\n```\nkubectl get pods\n```\n\nWhen the pods are ready, the output shows `1/1` for READY and `Running` for STATUS.\n\n// Static guide instruction\nifndef::cloud-hosted[]\n\nYour application will now be available at the `http://[hostname]:31000/dev/system/properties` URL. You now need to use the new username, `alice`, and the new password, `wonderland`, to log in. Alternatively, you can run the following command:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role=command]\n```\ncurl http://localhost:31000/dev/system/properties -u alice:wonderland\n```\nIf the `curl` command is unavailable, then use https://www.getpostman.com/[Postman^]. To make a request with Postman, enter `\\http://localhost:31000/dev/system/properties` into the URL bar. Next, set the `Authorization` with `Basic Auth` type, and set the `Username` field to `alice` and `Password` field to `wonderland`. Finally, click the blue `Send` button to make the request.\n--\n\n[.tab_content.mac_section]\n--\n[role=command]\n```\ncurl http://localhost:31000/dev/system/properties -u alice:wonderland\n```\n--\n\n[.tab_content.linux_section]\n--\n[role=command]\n```\ncurl http://$(minikube ip):31000/dev/system/properties -u alice:wonderland\n```\n--\n\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nSet up port forwarding to the new services.\n\nRun the following commands to set up port forwarding to access the ***system*** service.\n\n```bash\nSYSTEM_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services system-service`\nkubectl port-forward svc/system-service $SYSTEM_NODEPORT:9090\n```\n\nThen, run the following commands to set up port forwarding to access the **inventory** service.\n\n```bash\nINVENTORY_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services inventory-service`\nkubectl port-forward svc/inventory-service $INVENTORY_NODEPORT:9090\n```\n\nYou now need to use the new username, ***alice***, and the new password, ***wonderland***, to log in. Access your application with the following commands:\n\n```bash\nSYSTEM_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services system-service`\ncurl -s http://localhost:$SYSTEM_NODEPORT/dev/system/properties -u alice:wonderland | jq\n```\nendif::[]\n\nNotice that the URL you are using to reach the application now has `/dev` as the context root. \n\n// Static guide instruction\nifndef::cloud-hosted[]\nVerify that `{inventory-api}/system-service` is working as intended. If it is not working, then check the configuration of the credentials.\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nVerify the inventory service is working as intended by using the following commands:\n\n```bash\nINVENTORY_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services inventory-service`\ncurl -s http://localhost:$INVENTORY_NODEPORT/inventory/systems/system-service | jq\n```\n\nIf it is not working, then check the configuration of the credentials.\nendif::[]\n\n== Testing the microservices\n\n// Static guide instruction\nifndef::cloud-hosted[]\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\nRun the integration tests:\n[role='command']\n```\nmvn failsafe:integration-test -Dsystem.context.root=/dev\n```\n--\n\n[.tab_content.linux_section]\n--\nRun the integration tests against a cluster running at Minikube's IP address:\n[role='command']\n```\nmvn failsafe:integration-test -Dsystem.context.root=/dev -Dsystem.service.root=$(minikube ip):31000 -Dinventory.service.root=$(minikube ip):32000\n\n```\n--\n\nendif::[]\n\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nUpdate the ***pom.xml*** files so that the ***system.service.root*** and ***inventory.service.root*** properties have the correct ports to access the **system** and **inventory** services.\n\n```bash\ncd /home/project/guide-kubernetes-microprofile-config/start\nSYSTEM_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services system-service`\nINVENTORY_NODEPORT=`kubectl get -o jsonpath=\"{.spec.ports[0].nodePort}\" services inventory-service`\nsed -i 's=localhost:31000='\"localhost:$SYSTEM_NODEPORT\"'=g' inventory/pom.xml\nsed -i 's=localhost:32000='\"localhost:$INVENTORY_NODEPORT\"'=g' inventory/pom.xml\nsed -i 's=localhost:31000='\"localhost:$SYSTEM_NODEPORT\"'=g' system/pom.xml\n```\n\nRun the integration tests by using the following command:\n\n```bash\nmvn failsafe:integration-test \\\n    -Dsystem.service.root=localhost:$SYSTEM_NODEPORT \\\n    -Dsystem.context.root=/dev \\\n    -Dinventory.service.root=localhost:$INVENTORY_NODEPORT\n```\nendif::[]\n\nThe tests for `inventory` verify that the service can communicate with `system` using the configured credentials. If the credentials are misconfigured, then the `inventory` test fails, so the `inventory` test indirectly verifies that the credentials are correctly configured.\n\nAfter the tests succeed, you should see output similar to the following in your console.\n\n[source, role=\"no_copy\"]\n----\n-------------------------------------------------------\n T E S T S\n-------------------------------------------------------\nRunning it.io.openliberty.guides.system.SystemEndpointIT\nTests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.706 s - in it.io.openliberty.guides.system.SystemEndpointIT\n\nResults:\n\nTests run: 2, Failures: 0, Errors: 0, Skipped: 0\n----\n\n[source, role=\"no_copy\"]\n----\n-------------------------------------------------------\n T E S T S\n-------------------------------------------------------\nRunning it.io.openliberty.guides.inventory.InventoryEndpointIT\nTests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.696 s - in it.io.openliberty.guides.inventory.InventoryEndpointIT\n\nResults:\n\nTests run: 3, Failures: 0, Errors: 0, Skipped: 0\n----\n\n== Tearing down the environment\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\nPress **CTRL+C** in the command-line sessions where you ran ***kubectl port-forward*** to stop the port forwarding. \nendif::[]\n\nRun the following commands to delete all the resources that you created.\n\n[role='command']\n```\nkubectl delete -f kubernetes.yaml\nkubectl delete configmap sys-app-root\nkubectl delete secret sys-app-credentials\n```\n\n// Static guide instruction\nifndef::cloud-hosted[]\n[role='command']\ninclude::{common-includes}/kube-minikube-teardown.adoc[]\nendif::[]\n\n\n// =================================================================================================\n// finish\n// =================================================================================================\n\n== Great work! You're done!\n\nYou have used MicroProfile Config to externalize the configuration of two microservices, and then you configured them by creating a ConfigMap and Secret in your {kube} cluster.\n\n// Include the below from the guides-common repo to tell users how they can contribute to the guide\n\ninclude::{common-includes}/attribution.adoc[subs=\"attributes\"]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-kubernetes-microprofile-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenliberty%2Fguide-kubernetes-microprofile-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-kubernetes-microprofile-config/lists"}