explanation of Service.get from pulumi

586 views Asked by At

I am using pulumi release to deploy a helm chart including many service and trying to get one of the deployed service. https://www.pulumi.com/blog/full-access-to-helm-features-through-new-helm-release-resource-for-kubernetes/#how-do-i-use-it shows we can use Service.get to achieve this goal but I failed to find any information of the parameters of the method. Could someone explain it a bit or point me to the correct documentation on Service.get?

Thanks

1

There are 1 answers

1
Christian Nunciato On

I think there's a bug in that post; it should be -master, not -redis-master:

...
srv = Service.get("redis-master-svc", Output.concat(status.namespace, "/", status.name, "-master"))

As for what's going on here, I'll try to explain, as you're right that this doesn't seem to be documented in a way that's easy to find, as it isn't part of the Kubernetes provider API, but rather part of the core Pulumi resource API.

To address the If you change up the example to use -master instead, you should be able to run the Pulumi program as otherwise quoted in that blog post. Here's the complete, modified program I'm using for reference:

import pulumi
from pulumi import Output
from pulumi_random.random_password import RandomPassword
from pulumi_kubernetes.core.v1 import Namespace, Service
from pulumi_kubernetes.helm.v3 import Release, ReleaseArgs, RepositoryOptsArgs

namespace = Namespace("redis-ns")

redis_password = RandomPassword("pass", length=10)

release_args = ReleaseArgs(
    chart="redis",
    repository_opts=RepositoryOptsArgs(
        repo="https://charts.bitnami.com/bitnami"
    ),
    version="13.0.0",
    namespace=namespace.metadata["name"],

    # Values from Chart's parameters specified hierarchically,
    # see https://artifacthub.io/packages/helm/bitnami/redis/13.0.0#parameters
    # for reference.
    values={
        "cluster": {
            "enabled": True,
            "slaveCount": 3,
        },
        "metrics": {
            "enabled": True,
            "service": {
                "annotations": {
                    "prometheus.io/port": "9127",
                }
            },
        },
        "global": {
            "redis": {
                "password": redis_password.result,
            }
        },
        "rbac": {
            "create": True,
        },
    },
    # By default Release resource will wait till all created resources
    # are available. Set this to true to skip waiting on resources being
    # available.
    skip_await=False)

release = Release("redis-helm", args=release_args)

# We can lookup resources once the release is installed. The release's
# status field is set once the installation completes, so this, combined
# with `skip_await=False` above, will wait to retrieve the Redis master
# ClusterIP till all resources in the Chart are available.
status = release.status
pulumi.export("namespace", status.namespace)
srv = Service.get("redis-master-svc", Output.concat(status.namespace, "/", status.name, "-master"))
pulumi.export("redisMasterClusterIP", srv.spec.cluster_ip)

When you deploy this program with pulumi up (e.g., locally with Minikube), you'll have a handful of running services:

$ pulumi up --yes
...

Updating (dev)
...

     Type                              Name              Status      
 +   pulumi:pulumi:Stack               so-71802926-dev   created     
 +   ├─ kubernetes:core/v1:Namespace   redis-ns          created     
 +   ├─ random:index:RandomPassword    pass              created     
 +   ├─ kubernetes:helm.sh/v3:Release  redis-helm        created     
     └─ kubernetes:core/v1:Service     redis-master-svc              
 
Outputs:
    namespace           : "redis-ns-0f9e4b1e"
    redisMasterClusterIP: "10.103.98.199"

Resources:
    + 4 created

Duration: 1m13s

$ minikube service list
|-------------------|------------------------------|--------------|-----|
|     NAMESPACE     |             NAME             | TARGET PORT  | URL |
|-------------------|------------------------------|--------------|-----|
| default           | kubernetes                   | No node port |
| kube-system       | kube-dns                     | No node port |
| redis-ns-0f9e4b1e | redis-helm-b5f3ea12-headless | No node port |
| redis-ns-0f9e4b1e | redis-helm-b5f3ea12-master   | No node port |
| redis-ns-0f9e4b1e | redis-helm-b5f3ea12-metrics  | No node port |
| redis-ns-0f9e4b1e | redis-helm-b5f3ea12-slave    | No node port |
|-------------------|------------------------------|--------------|-----|

Getter functions like Service.get are explained here, in the Resources docs: https://www.pulumi.com/docs/intro/concepts/resources/get/

Service.get takes two arguments. The first is the logical name you want to use to refer to the fetched resource in your stack; it can generally be any string, as long as it's unique among other resources in the stack. The second is the "physical" (i.e., provider-native) ID by which to look it up. It looks like the Kubernetes provider wants that ID to be of the form {namespace}/{name}, which is why you need to use Output.concat to assemble a string composed of the eventual values of status.namespace and status.name (as these values aren't known until the update completes). You can learn more about Outputs and Output.concat in the Resources docs as well: https://www.pulumi.com/docs/intro/concepts/inputs-outputs/

Hope that helps! Let me know if you have any other questions. I've also submitted a PR to get that blog post fixed up.