This message was deleted.
s
This message was deleted.
l
Branching per environment implies (to me) that you'd use the same stack for each environment, and the stack would change based on which branch is checked out. This cannot work: the stack code has to match the stack state, which is not committed to the repo.
Instead, a stack per environment allows you to leverage the features of both your SCM and Pulumi.
Using branches for features, releases or similar, and stacks for environments.
All my Pulumi projects have per-environment stack and the flow is natural. You do have to have a single state per stack though, and that usually works best with CD, or at least CI.
q
@little-cartoon-10569 thanks for offering some feedback. Let me first try to make sure I understand your suggestion. Then I will try to make clear the other approach.
@little-cartoon-10569 if I give an example program like
Copy code
├── rds
│   ├── README.md
│   └── program
│       ├── Pulumi.state-store-prod.yaml
│       ├── Pulumi.state-store-test.yaml
│       ├── Pulumi.yaml
│       ├── __main__.py
│       ├── <http://requirements.in|requirements.in>
│       ├── requirements.txt
And I’m using stacks probably by the wrong definition, because the stack is defined as an instance
l
No that seems ok. You have a stack per RDS instance, and two RDS instances are used in the same way but in different environments (prod, test, etc.). That seems fine.
q
Yes, so if I want to test changes to main via a feature branch, one way to do that would be using per-environment branches along with feature branches maybe like so:
Copy code
1. All shared code changes start from feature forked from a master branch. No config changes exist on master.

    2. configuration changes will be applied on a fork of the feature branch (so feature will not contain configuration). Note that we need to apply code updates to the feature branch to be shared by all "configuration forks". Only when the feature is code complete, we can add configuration on top of the feature fork. PR is created / merged from the feature fork. Acceptance tests are run and on passing we continue

    3. When acceptance tests pass  (sans dev config) the feature branch will now be forked again to add test configuration. Then this forked feature with config is merged into test and acceptance tests are run. If a code change and non-config change is necessary (bug), we need to apply back on the feature branch (no config) itself. Then repeat 2. (adding config). After that we repeatethese steps again

    4. A similar process to above for prod configuration. Again note iff code changes are required, we need to repeat 2, 3, 4 . The feature branch is always based with the latest code.

    5. feature branch is merged into master.
This is a branch per environment that includes a master branch and utilizing feature branches
The reason for this approach is so that the code change to main program is propagated through the branches via feature so that we don’t merge a feature to master and have inconsistent state for the deployed environments
l
I suppose that can work. I prefer not to distinguish between code and config (all my config is code) so I don't have experience with that part of the plan. For the rest of it, so long as you have a stack per branch (and thus, you are prepared to create environments on-demand), you should be ok. You'll have to delete a lot of stacks, but that's not a problem.
q
Then given your approach, how do you isolate changes to main or program to be stack specific
l
That's the job of feature flags or similar. Code like
if ("test" == stack && Feature.isEnabled("MultiAZ")) { ...
...
q
Hmm I’ve seen that feature gating get pretty nasty. That’s what I’m trying to work against
l
I guess it depends on how it's implemented. It's the beez neez, here 🙂
q
It’s a little specific to my problem area.
l
We drop features as soon as possible, too.
q
We have been working with helm, trying to keep the helm yaml in it’s native form. It’s worked so far. We template pulumi configuration into the helm. But feature gating into helm config and templates, gets sort of nasty. And it’s a waste of code when something is only optional because we’re trying to validate it. We have to write a bunch of conditionals and maybe some optionally rendered templates that might very well be useless when the feature was released. So I’m arguing that sometimes feature gating can just be a waste of time.
l
If you're transitioning through YAML, that sounds like a pain. More complex branching might be the way to go.
q
I’m not here to convince anyone that what we’re doing is great. However we maintain the nested yaml dialect for helm when we need it. And that’s nice because we’re not converting between different configuration resources when we’re looking to compare the configurations between documentation, etc.
@little-cartoon-10569 anyhow thanks for giving me some feedback. If you think of something I should reason about further let me know.
l
Ok. Well it sounds like it's a considered approach, and I'm sure there'll be no more difficulties than you'd face trying to change your existing way of working to suit Pulumi's "simpler" way.
I think you will need to push back against anyone asking to share environments between branches. That might cause headaces.