pulumi-repl
Create cloud infrastructure and explore pulumi in an interactive NodeJS REPL.
- Create and explore cloud infrastructure.
- Run
apply
and experiment with other pulumi functionality. - Save your work as a full pulumi program when you're done with
eject
! - Create ephemeral sessions that automatically delete all resources on
ctrl+c
.
Just a few lines of code to get started:
import { PulumiRepl } from "pulumi-repl";
const repl = new PulumiRepl({
stack: "dev",
project: "pulumi-repl",
eject: true,
config: {
"aws:region": { value: "us-west-2" }
},
});
repl.start().catch(err => console.error(err));
Demos
Kubernetes
Create kubernetes resources interactively! At the end, all created resources are saved in stae by the pulumi engine.
Eject
When you're done with your REPL, you can eject a pulumi program generated from all the commands you entered. Here we create a static S3 website. At the end our program is ejected in ./eject
. When we run a preview on that program, we see that there's no diff!
Usage && Requirements
Prereqs:
- Pulumi CLI logged in and configured: https://www.pulumi.com/docs/get-started/
- Cloud credentials configured as per above guide (for your cloud of choice).
Basic
import { PulumiRepl } from "pulumi-repl";
const repl = new PulumiRepl({
stack: "dev",
project: "pulumi-repl",
config: {
"aws:region": { value: "us-west-2" }
},
});
repl.start().catch(err => console.error(err));
Registering Stack Outputs in the REPL
The REPL has a builtin function registerOutput(k, v)
which creates stack exports.
$ pulumi-repl> registerOutput("websiteUrl", siteBucket.websiteEndpoint);
...
Outputs:
websiteUrl: "s3-website-bucket-82db68d.s3-website-us-west-2.amazonaws.com"
Eject
eject
will output a full pulumi program into the ./eject
directory including:
- index.js (program)
- pacakge.json
- Pulumi.yaml (your project file)
const repl = new PulumiRepl({
eject: true
stack: "dev",
project: "pulumi-repl",
config: {
"aws:region": { value: "us-west-2" }
},
});
To run your program:
```sh
$ cd ./eject
$ yarn install
$ pulumi stack select # pick the stack you want to work with
$ pulumi config set ... # set any cloud provider config values if needed
$ pulumi preview # see your program in action
Plugins and Context
The REPL comes preloaded with the following Pulumi provider plugins:
- AWS
- Azure (native)
- GCP
- Kubernetes
You can add additional provider plugins and SDKs as described below.
The REPL supports defining context values via this.addContext(k, v)
, which we use to load the random
resource provider SDK below. In addition, we access the Automation API stack object to install plugins.
import { PulumiRepl } from "pulumi-repl";
import * as random from "@pulumi/random";
const repl = new PulumiRepl({
stack: "dev",
project: "pulumi-repl-custom",
});
repl.addContext("random", random);
repl.stack.then(s => {
s.workspace.installPlugin("random", "v4.0.0").then(()=>{
repl.start().catch(err => console.error(err));
})
});
Ephemeral Stacks
Specify the ephemeral: true
arg to run the repl in ephemeral mode. On ctrl+c
all of your cloud resources will be cleaned up and destroyed.
import { PulumiRepl } from "pulumi-repl";
const repl = new PulumiRepl({
stack: "dev",
project: "pulumi-repl-custom",
ephemeral: true
});
Automation API Stack & Workspace
If you're an advanced Pulumi user, you may want to access the Automation API Stack. You can do this via this.stack
(a promise).
You can access the underlying LocalWorkspace
via this.stack.then(s => s.workspace)
.
Advanced workspace configuration options are available including custom backends (azure, filestate, etc), and custom secrets providers via ReplArgs.workspaceOpts
How it works
This library uses the native NodeJS REPL library and the Pulumi Automation API (OSS) which turns the Pulumi IaC engine into an embeddable SDK.
Caveats & Immutability
When you execute commands in the REPL, you're still running pulumi code. Because Pulumi is declarative and desired state, resources can't be mutated after they are instantiated in the REPL. You'll have to exit the session and restart to "make an edit". Each REPL session will compute differences against the previous state. If you define a resource in one session and then forget it in the next one, it will be deleted. This is just like making edits and running a normal pulumi program, the only difference is that we get to create resources incrementally and explore their shape, outputs, etc.
Read more about Pulumi's desired state architecture: https://www.pulumi.com/docs/intro/concepts/how-pulumi-works/