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

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.

Top