Stringing Workloads together
Deploying another Workload
You can deploy more than one Workload into the same Platform Orchestrator Application. Doing so requires no more than providing another Score file and deploying it into the same target Application and Environment.
Copy your score.yaml
to another name:
cp score.yaml crazy_score.yaml
Edit the new file crazy_score.yaml
and change the value of name
to crazy-quickstart
. Leave the file unchanged otherwise.
Then deploy your new workload:
humctl score deploy -f crazy_score.yaml
The deployment will target the development
Environment of the quickstart
Application based on the HUMANITEC_*
environment variables as before.
Check the result in the Platform Orchestrator UI. Navigate to the development
Environment of the quickstart
Application. You will see the new Workload named crazy-quickstart
next to the previously existing quickstart
Workload.
Check the result on the Kubernetes Cluster:
kubectl get all -n ${NAMESPACE_DEVELOPMENT}
You will find that the new Workload has resulted in a duplication of all Kubernetes objects, including a new instance of an in-cluster PostgreSQL database. That is because each postgres
resource a Workload requests is a private Resource by default, i.e. it is owned by that particular Workload. If that is what you want, you’re good. The next section will demonstrate how to define Resources that are shared among Workloads.
First, access your new Workload:
kubectl port-forward service/crazy-quickstart 8080:8080 -n ${NAMESPACE_DEVELOPMENT}
Open http://localhost:8080. You will see that this Workload again has access to the Shared Value MOTD
through the environment
resource. This particular resource, fulfilling the Score convention, is not private to the Workload.
Quit the port forwarding via Cmd-C or Ctrl-C.
Accessing another Workload’s resources
A Workload’s resources can be accessed from other Workloads of the same Application. Assuming that the new Workload crazy-quickstart
would want to access the PostgreSQL instance of the quickstart
Workload, you can adjust the placeholders for the connection string in the crazy_score.yaml
like this, and re-deploy it:
OVERRIDE_POSTGRES: "postgres://${modules.quickstart.externals.db.username}:${{modules.quickstart.externals.db.password}..."
Feel free to try this on your own. We will present an architecturally cleaner solution using a truly shared database in a minute.
Another use case would be that a Workload has a dns
resource to configure ingress traffic, and another Workload needs to know the DNS name. That other Workload could resolve it using this notation:
# ... start of score.yaml
variables:
DNS_NAME: ${modules.myworkload.externals.dns.host}
Using Shared Resources
While the mechanism seen in the previous section could be used by one of our Workloads to access the PostgreSQL database of the other, it may be preferable to have a database that is not owned by one particular Workload. The Platform Orchestrator has the concept of Shared Resources for the Workloads of an Application.
To define a Shared Resource, add an identical id
to the resource in both (!) Score files score.yaml
and crazy_score.yaml
:
...
resources:
db:
type: postgres
id: common-pg
...
If you want to check for correctness of your edits or skip the self-editing, you can find preconfigured files in the solutions
subdirectory. To use them, execute:
cp solutions/shared_db_score.yaml score.yaml
cp solutions/shared_db_crazy_score.yaml crazy_score.yaml
db
is local to each Score file and may differ as long as the id
is identical.Redeploy both Workloads to the development
Environment:
humctl score deploy
humctl score deploy -f crazy_score.yaml
Check the result in the Platform Orchestrator UI. Navigate to the development
Environment of the quickstart
Application. In the “Shared Resources” section, you will find a new Resource named shared.common-pg
of type: postgres
.
Navigate to either the quickstart
or the crazy-quickstart
Workload. The previously seen Resource Dependency of the postgres
Resource is now gone.
Check the result on the Kubernetes Cluster:
kubectl get all -n ${NAMESPACE_DEVELOPMENT}
You will find that a new PostgreSQL database named postgres-shared-common-pg
has been provisioned.
To prove that both Workloads are indeed accessing the same resource, check the connection string used by both running containers:
# quickstart Workload
kubectl exec \
$(kubectl get pods -l app.kubernetes.io/name=quickstart -n ${NAMESPACE_DEVELOPMENT} \
-o custom-columns=NAME:metadata.name --no-headers) \
-n ${NAMESPACE_DEVELOPMENT} \
-- env | \
grep OVERRIDE_POSTGRES
# crazy-quickstart Workload
kubectl exec \
$(kubectl get pods -l app.kubernetes.io/name=crazy-quickstart -n ${NAMESPACE_DEVELOPMENT} \
-o custom-columns=NAME:metadata.name --no-headers) \
-n ${NAMESPACE_DEVELOPMENT} \
-- env | \
grep OVERRIDE_POSTGRES
Recap
And that concludes this chapter. You have:
- ✅ Deployed a second Workload into your Application
- ✅ Seen how to access another Workloads resources
- ✅ Established a shared database for both of your Workloads
Your setup now looks like this (omitting some prior details for simplicity):
%%{ init: { 'flowchart': { 'curve': 'linear' } } }%%
flowchart LR
subgraph scoreFileA[Score file]
direction TB
scoreWorkloadA[Workload]
scoreWorkloadA ~~~ scoreDbA(Resource\npostgres\nid: common-pg)
end
subgraph scoreFileB["Crazy Score" file]
direction TB
scoreWorkloadB[Workload]
scoreWorkloadB ~~~ scoreDbB(Resource\npostgres\nid: common-pg)
end
subgraph platformOrchestrator[Platform Orchestrator]
cloudAccount(Cloud Account)
subgraph application[Application]
envDevelopment(Environment\n"development")
envStaging[Environment\n"staging"]
end
resDefCluster(Resource Definition\nCluster)
resDefNamespace(Resource Definition\nNamespace)
resDefDb(Resource Definition\nPostgreSQL)
end
subgraph cloudInfrastructure[Cloud Infrastructure]
subgraph k8sCluster[Kubernetes Cluster]
subgraph namespaceDev[Namespace development]
workloadDevA(Workload) --> dbDev(PostgreSQL\n"common-pg")
workloadDevB("Crazy" Workload) --> dbDev
end
subgraph namespaceStaging[Namespace staging]
workloadStaging(Workload) --> dbStaging(PostgreSQL)
end
end
end
scoreFileB -->|humctl score deploy| envDevelopment
scoreFileA -->|humctl score deploy| envDevelopment
envDevelopment --> namespaceDev
envStaging --> namespaceStaging
resDefCluster -.- k8sCluster
%% Using the predefined styles
class scoreFileB,workloadDevB highlight
class application,k8sCluster nested
Note that once more the staging
namespace does not yet have the shared PostgreSQL provisioned because you have not deployed there yet.
This highlight concludes the content part of the Quickstart! Go ahead to clean up your environment.