What is the recommended way to promote code from o...
# general
e
What is the recommended way to promote code from one environment to another, for example from dev to stage then to prod? I can use the pulumi project and stacks constructs but im not sure if that gives me the controls that i need. For example if i create an AWS EKS cluster in a project and launched it to all stacks (dev, stage, prod). Then i need to make a change, something that is not as easy as a parameter that can be in the stack environment config, something like changing networking cni. This will be a bunch of various code changes and it could take a while to roll out with testing along the way in the various environments (dev, stage, prod). Once i have made this change in dev and it is working for me, i would like to open a PR to get it reviewed, merged and then versioned so that the next environment can use it. I would like that the project or stack can reference a github URL that can ref a tag/commit. I am coming from the Terraform world where you can do this via:
Copy code
module "consul" {
  source = "github.com/hashicorp/example?ref=v1.2.0"
}
Is there something similar in pulumi? Does this make sense to do or am i trying to follow too closely to what i have done in Terraform? I have found Pulumi Components: https://www.pulumi.com/docs/iac/using-pulumi/extending-pulumi/build-a-component/#sharing-via-git. This gets me most of the way there but i still have to run a
Copy code
pulumi package add <repo_url>@<release-version>
Which means i have to run this command and the CI/CD pipeline has to run it as well. This would mean adding a script that runs this command with the version? So the person updating it would have to update the version here? Not the worst thing but the workflow seems to be just a little off as in it is making the user look into another file that is not a Pulumi file to update a version number. Other notes: • i am only using python • I dont want to publish these publicly. Not that there are any secrets or proprietary things in it. For now, we dont want to spend time to make it publicly consumable.
l
If you need to make the code change in dev to prove it in prod.. then it is the same code, isn't it? Pulumi's stacks support this model exactly. You can check out Pulumi code from a tag for a particular deployment to a particular environment, that's very appropriate. Wrap your prod deployment in a script that does that, zero friction. Pulumi Components don't add any deployment-related functionality: they're very good at helping reduce dependency management overload, at allowing multiple languages to be used in a single project, and generally adding code-level sugar to the projects. You may find features of Pulumi ESC or Pulumi Deployments actually add capabilities to your deployment tool suite, whereas Components just make it easier to take advance of capabilities you already have.
As to the original question:
What is the recommended way to promote code from one environment to another, for example from dev to stage then to prod?
There is no single answer to this. A "downside" of Pulumi being built on general purpose languages is that there's no real limit to the ways it can be used. I would caveat that by saying it's not managed in the same way as some SaaS solutions which actually promote environments or the code on them (that is,
dev -> prod
): everything is just
code repository -> target environment
. It uses the (more common?) concept of "build once, deploy many times", and therefore, deploying from git tags or something like that is how people usually achieve environment promotion.
If you want to force a more rigorous environment promotion policy, you can implement your own or look into software that does this. I know there's loads, but I can't list many. Only one of my clients uses one: Octopus Deploy. It's fine at its job, and it does what you're describing. There may well be better options for you.
In their case, they use Octopus mostly for app deployments onto Pulumi-managed infra, so we don't actually use it in the way you describe. But I can see how Pulumi projects could be invoked from Octopus and you'd get the nice environment-promotion tables, along with the gates that Octopus can provide for the higher-risk deployments (2 signoffs required for prod, etc.).
e
That makes sense. Sometimes a tool can be too opinionated on how to do things and some tools are less opinionated. I guess i was hoping Pulumi would be a little bit more opinionated (just a little). Trying to walk through the tag method you mentioned would have a dir like this for the eks:
Copy code
pulumi/aws/eks
├── Pulumi.dev.yaml
├── Pulumi.prod.yaml
├── Pulumi.stage.yaml
├── Pulumi.yaml
├── deploy-dev.sh
├── deploy-prod.sh
└── deploy-stage.sh
Pulumi project file and stack files. Then a script for deployment into the env would contain something like:
Copy code
#!/bin/bash

GIT_TAG=v0.0.1

# clone out the repo
git clone --branch $GIT_TAG <https://github.com/my-repo/temp1.git>

cd /to/the/path/of/this/deploy

pulumi up --stack prod --yes
Is that what you were thinking about @little-cartoon-10569?
f
in my mind pulumi component ~ tf module, you put it in git and tag it then you create a program with stacks per every environment. you can reference component@ref using package add. it is also possible to use local folder too there what I don't know if it is possible to reference different version of the component in different stacks, maybe someone from pulumi can clarify. if not, it would be a useful feature
l
Yea something lke that. Probably a pipelines file, azure-pipelines.yml, .gitlab-pipelines.yml, whatever.
Components are like classes, not programs. You compose components into programs.
You cannot (as far as I know) reference different versions of components per stack. You would need different git tags for that.
e
Glad to hear you guys are saying components are like tf modules and classes. From going through the pulumi docs and think through how this would work, i am down that path as well. I have this first vpc pulumi component: https://github.com/ManagedKube/temp1 I can create a project and in that project folder i run:
Copy code
pulumi package add <https://github.com/ManagedKube/temp1.git/vpc@0.0.0>
Which downloads the yaml with more information in it and this is my Pulumi.yaml file for the project:
Copy code
name: vpc
description: A VPC
runtime: yaml
packages:
  vpc: <https://github.com/ManagedKube/temp1.git/vpc@0.0.0>
resources:
  vpc:
    type: vpc:Vpc
    properties:
      vpcName: test-test-vpc
      cidrBlock: 10.9.0.0/16
      igwName: my-igw
      tagsAdditional:
        github_repository: my-repo
        github_repository_path: "infra/aws/40-vpc"
outputs:
  vpc_id: ${vpc.vpcId}
• It seems you can only use the
packages
key in a Pulumi Project file and not in the stack files • Even with the package named off in the Pulumi.yaml file, you still have to run
pulumi package add ....
to get it to download the package I am trying to use github actions (similar to any other pipelining CI/CD tool). However with this workflow the official Pulumi action (https://github.com/pulumi/actions) doesnt support the
pulumi package add
command. I havent tried it yet, just looking at the docs. If it doesnt "just work", i would have to go and do something custom. Not the worst thing but it would be another thing i would have to maintain. I was just hoping there was a cleaner solution.
f
something I do, is put all variables for my component in the stack and then reference it in pulumi.yaml https://github.com/dmfigol/pulumi-aws-vpc-python/blob/main/examples/yaml/Pulumi.yaml I wish I could reference package in stack config though. I agree with you that this pulumi package add doesnt look very clean
e
@famous-ambulance-44173 thanks for posting this. This looks like the direction I want to go towards but it looks like it has been thought through more than what i crafted up by just reading a few docs. Can I ask you a few questions with this? Do you have to do a pulumi package add?
Copy code
pulumi package add <https://github.com/dmfigol/pulumi-aws-vpc-python@0.0.0-x9bc475e6cbf54f2baa2b0d2575fceee3a80acffb>
f
@echoing-battery-61643 almost, it was
pulumi package add <https://github.com/dmfigol/pulumi-aws-vpc-python>
and resulted in what you saw in yaml
e
@famous-ambulance-44173 how does it know which git commit or tag to go and fetch?
f
you can add
@ref
at the end
e
Ah ok...thanks! THis has been very helpful, appreciate your time.