google-cloud-platformpulumipulumi-python

Pulumi micro stacks with shared component


I manage a project on Google Cloud Platform which is composed by GKE and Cloud Run. I would like to achieve a flexible and independent deployment for each Cloud Run function: each function should extend the current infrastructure but be deployable independently using also CI/CD. I want to deploy the Cloud Run functions with a single load balancer (i.e., single domain), but different paths (see). I was able to achieve this goal with a single stack, but each new function or modification requires to always modify the main repo and the CI/CD needs to always use the main repo to deploy each function.

I would like to use micro-stacks approach, but pulumi does not seem to allow the modification of the "shared" component URLMap from each micro stack. I need this component to map the load balancer with the correct path and backend service.

Micro-stack repositories structures:

Infra repo with initialization of main components (omitting useless parameters):


managed_ssl_certificate = gcp.compute.ManagedSslCertificate(...)

url_map = URLMap("cloud-run-url-map",
                      host_rules=[
                          URLMapHostRuleArgs(
                              hosts=["example.com"],
                              path_matcher="example"
                          )],
                      path_matchers=[
                          URLMapPathMatcherArgs(
                              name="example",
                              default_service=self.function_backend_service.self_link.apply(lambda self_link: self_link),
                        # Each Cloud Run function should add its path
                        path_rules=[]
                        ...
                          )])

http_load_balancer = gcp.compute.TargetHttpsProxy(url_map=url_map.id,
                                                  ssl_certificates=[managed_ssl_certificate.id],
                                                  ...)

forwarding_rule = gcp.compute.GlobalForwardingRule(target=http_load_balancer.id,
                                                    ...)

The infrastructure library which is used by each Cloud Run function and it needs to edit the "URL Map":


class MyCloudRun(ComponentResource):
    self.function = pulumi_gcp.cloudrunv2.Service(...)

    # Create a serverless network endpoint group (NEG) for the Cloud Run service
    cloud_run_neg = pulumi_gcp.compute.RegionNetworkEndpointGroup(...)

    # Create the backend service that points to the Cloud Run NEG
    self.function_backend_service = pulumi_gcp.compute.BackendService(...)

    # How to manage the URL Map? How to add the new URLMapPathMatcherPathRuleArgs ?
    # I tried to retrive the existing URL Map as follow but I got Duplicate resource URN; try giving it a unique name
    # Moreover, I am not sure how pulumi can delete the correct URLMapPathMatcherPathRuleArgs when removing the function

    original_path_matcher = URLMap.get(resource_name="my_name",id="my_id")
    new_path_rule = URLMapPathMatcherPathRuleArgs(
    paths=["/test"],
    service=self.function_backend_service)
    # The update logic is much more complex, but let's assume that original_path_matcher[0] exist and the operation of append does not create duplicate of URL Matcher.
    original_path_matcher[0].path_rules.append(new_path_rule)

What is wrong in my approach?


Solution

  • My approach to micro-stacks with a "shared" URLMap component (though it's not the most elegant solution, it functions well):

    Limitation: If changes to a Cloud Run function impact the URLMap (e.g., adding a new path), the infrastructure repository needs to be re-deployed to reflect those changes.