We have found ourselves in a situation where we ha...
# general
b
We have found ourselves in a situation where we have an unsatisfactory solution, but we wanted to know if there is a better, more elegant alternative. • We have a project containing shared infrastructure, with stacks allocated per environment (UAT/PROD). • We also have projects containing infrastructure per partner/environment (e.g., PARTNER-A-UAT, PARTNER-B-UAT, etc.), and they have stack references to the shared infrastructure (Ex, a VPC in the shared environment is referenced by partner/environment to add a subnet). • We manage triggering Pulumi previews and updates in CircleCI, where the workflow builds out the shared infra, then the partners. Which works fine in the full CI/CD workflow • We want to be able to run the shared and partner lower env previews for Pull Requests in GitHub. The problem is that without running the actual Pulumi apply in the shared environment and adding, for example, the VPC referenced in the partner stack, it will fail. Our hacky solution is to: 1. Are we running the code currently in a
preview
? 2. If so, mock all stack references to the shared project. Is there a better way to do this?
👀 3
m
Hey Chris, Some questions upfront: • Are you using Pulumi Cloud to store your states? • What kind of information are you exporting in your shard infra stack? Is it simple types or objects? • Can you gives us some infos from
pulumi about
in both projects? Would help a lot
b
• Pulumi Cloud • The object. • happy to (but don't want to publish our infra on a public forum). Truncated Shared:
Copy code
CLI          
Version      3.190.0
Go Version   go1.25.0
Go Compiler  gc

Plugins
KIND      NAME    VERSION
language  nodejs  3.190.0

Host     
OS       darwin
Version  15.6.1
Arch     arm64

This project is written in nodejs: executable='*/.nvm/versions/node/v20.17.0/bin/node' version='v20.17.0'

Current Stack: */uat-shared-infra

...

Found no pending operations associated with uat-shared-infra

Backend        
Name           <http://pulumi.com|pulumi.com>
URL            <https://app.pulumi.com/*>
User           *
Organizations  *
Token type     personal

Dependencies:
NAME         VERSION
@types/node  20.14.2
@types/tape  5.6.4
husky        9.0.11
nx           19.3.0
ts-standard  12.0.2
typescript   5.4.5
The Truncated Partner Env
Copy code
CLI          
Version      3.190.0
Go Version   go1.25.0
Go Compiler  gc

Plugins
KIND      NAME    VERSION
language  nodejs  3.190.0

Host     
OS       darwin
Version  15.6.1
Arch     arm64

This project is written in nodejs: executable='*/.nvm/versions/node/v20.17.0/bin/node' version='v20.17.0'

Current Stack: */uat-bevel

...

Found no pending operations associated with uat-bevel

Backend        
Name           <http://pulumi.com|pulumi.com>
URL            <https://app.pulumi.com/*>
User           *
Organizations  *
Token type     personal

Dependencies:
NAME         VERSION
@types/node  20.14.2
@types/tape  5.6.4
husky        9.0.11
nx           19.3.0
ts-standard  12.0.2
typescript   5.4.5
m
ok, that is already good informations. With object, you mean an custom interface or a type? Asking to try to recreate the scenario. 😅
b
We create a resource and export it (probably overdoing it). Ex:
Copy code
const vpc = new gcp.VCP('name',{....})

export default {vpc}
then, in the partner env
Copy code
const ref = new pulumi.StackReference(`${org}/*/${stack}`)
const vpc = ref.getOuput('vpc')
way over simplified, but you get the point.
and basically we then cheat with:
Copy code
const vpc = runningPreview ? getMock('vpc') : ref.getOuput('vpc')
so our preview for the partner env runs before we'd run the update on the shared.
m
Thats what I thought too. I use Stack References only for values like
id
or so. The bare minumum of infos needed in the other stack. Or as @salmon-account-74572 wrote: > exported the essential values He made a guide of best practices here: https://www.pulumi.com/blog/iac-best-practices-applying-stack-references/
b
we'd still have to do something like const vpcName = runningPreview ? 'fake-name' : ref.getOuput('vpc-name')
m
I have to play with exporting whole resources as outputs.
here a simple example Project 1, Stack dev
Copy code
import * as pulumi from "@pulumi/pulumi";

export const test = "engin"
and running pulumi up:
Copy code
pulumi up -y -f
Updating (dev)

View in Browser (Ctrl+O): <https://app.pulumi.com/dirien/p1/dev/updates/1>

     Type                 Name    Status
 +   pulumi:pulumi:Stack  p1-dev  created (1s)

Outputs:
    test: "engin"

Resources:
    + 1 created

Duration: 4s
Now Project 2 and stack dev
Copy code
import * as pulumi from "@pulumi/pulumi";


var stackReference = new pulumi.StackReference("dirien/p1/dev");

export const bucketName = stackReference.getOutput("test");
Running preview:
Copy code
pulumi preview
Previewing update (dev2)

View in Browser (Ctrl+O): <https://app.pulumi.com/dirien/p2/dev2/previews/9ab0fad0-df3d-4dd0-af80-d57a4021e1e9>

     Type                 Name     Plan
 +   pulumi:pulumi:Stack  p2-dev2  create

Outputs:
    bucketName: "engin"

Resources:
    + 1 to create
So preview works fine on the second project, in your case your customer code, referencing project 1 aka your shared infra
b
Yeah, that works fine for our full CI/CD workflow, which looks like:
Copy code
[pulumi preview shared]  ==> [pulumi update shared] ==> [pulumi preview partner env]  ==> [pulumi update partner env]
But for the Pull Request workflow, which gets run in CI as commits go to a pull request to validate it before the above is ran, it will go:
Copy code
[pulumi preview shared]  ==> [pulumi preview partner env]
So our two solutions are: • Mock the stack reference output if running preview • Have to do multiple PR's for any shared infra. ◦ Push Shared Infra with no ref in partner env (updating the shared env) ◦ Push a separate PR to Partner Env so the reference in Shared exists, so it does not break in preview. Neither makes us totally happy. (mocking results in a little less work and quicker deployments).
m
Why do you run the preview of shared in the PR when there is no change in the shared infra?
@bland-jackal-6231 As we talked in the huddle I tag @witty-candle-66007 here and gave him some infos from your setup.
w
Hi @bland-jackal-6231 I don’ t have much to add, really. But, customers I’ve worked with will have the shared infra settled before running previews, etc on the dependent stack(s). But, really, your Mock solution isn’t that bad, imo, if that keeps things tidy. The one “issue” is that it might mean you don’t know of a problem until the updates run.
b
My hope, was something fancy like using the output of Preview A for the stack refs in Preview B. It would be a neat feature.
m
@bland-jackal-6231 best thing would be to open a feature request in pulumi/pulumi. We can then take this issue and can try to advocate for it.