Configuration
In many cases, different stacks for a single project will need differing values. For instance, you may want to use a different size for your AWS EC2 instance, or a different number of servers for your Kubernetes cluster between your development and production stacks.
Pulumi offers a configuration system for managing such differences. Instead of hard-coding the differences, you can store and retrieve configuration values using a combination of the CLI and the programming model.
The key-value pairs for any given stack are stored in your project’s stack settings file, which is automatically named Pulumi.<stack-name>.yaml
. You can typically ignore this file, although you may want to check it in and version it with your project source code.
Configuration Options
You can use both the CLI and the programming model for your Pulumi configuration.
- The CLI offers a
config
command withset
andget
subcommands for managing key-value pairs. - The programming model offers a
Config
object with various getters and setters for retrieving values.
All shell environment variables are passed to the running program and can be accessed using standard runtime APIs, such as
process.env
in Node.js andos.environ
in Python, which can also be used for dynamic behavior. Configuration is preferable, however, because it is designed for multi-stack collaborative scenarios.
Configuration Keys
Configuration keys use the format [<namespace>:]<key-name>
, with a colon delimiting the optional namespace and the actual key name. In cases where a simple name without a colon is used, Pulumi automatically uses the current project name from Pulumi.yaml
as the namespace.
As an example, this capability allows the AWS package to accept a configuration value for aws:region
without conflicting with other packages using the common key name region
. It also allows custom components to define their own key spaces without risk of conflicting with other components, packages, or projects.
Setting and Getting Configuration Values
The pulumi config
CLI command can get, set, or list configuration key-value pairs in your current project stack:
pulumi config set <key> [value]
sets a configuration entry<key>
to[value]
.pulumi config get <key>
gets an existing configuration value with the key<key>
.pulumi config
gets all configuration key-value pairs in the current stack (as JSON if--json
is passed).
config set
command, any existing values for <key>
will be overridden without warning.For example, to set and then get the current AWS region in the aws
package, you would run the following:
$ pulumi config set aws:region us-west-2
$ pulumi config get aws:region
us-west-2
To set and get configuration in the current project (named broome-proj
for example), we can use the simplified key name:
$ pulumi config set name BroomeLLC
$ pulumi config get name
BroomeLLC
If [value]
is not specified when setting a configuration key, the CLI will prompt for it interactively. Alternatively, the value can be set from standard input, which is useful for multiline values or any value that must be escaped on the command line:
$ cat my_key.pub | pulumi config set publicKey
Accessing Configuration from Code
Configuration values can be retrieved using either Config.get
Config.get
Config.get
config.Get
Config.Get
Config.require
Config.require
Config.require
config.Require
Config.Require
Config.get
Config.get
Config.get
config.Get
Config.Get
undefined
undefined
None
nil
null
Config.require
Config.require
Config.require
config.Require
Config.Require
The following example uses an empty constructor. If you are writing code that will be imported into a broader project, such as your own library of components, you should pass your library’s name to the constructor. This string is used as a namespace for all configuration keys. Similarly, if you want to access the config of another library, such as the config for a standard library like aws
, you should also pass the library’s name to the constructor. The default constructor automatically uses the current project for that namespace.
let config = new pulumi.Config();
let name = config.require("name");
let lucky = config.getNumber("lucky") || 42;
console.log(`Hello, ${name} -- I see your lucky number is ${lucky}!`);
let config = new pulumi.Config();
let name = config.require("name");
let lucky = config.getNumber("lucky") || 42;
console.log(`Hello, ${name} -- I see your lucky number is ${lucky}!`);
config = pulumi.Config();
name = config.require('name');
lucky = config.get_int('lucky') or 42
print(f'Hello, {name} -- I see your lucky number is {lucky}!')
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
conf := config.New(ctx, "")
name := conf.Require("name")
lucky, err := conf.TryInt("lucky")
if err != nil {
lucky = 42
}
fmt.Printf("Hello, %v -- I see your lucky number is %v!\n", name, lucky)
return nil
}
}
var config = new Pulumi.Config();
var name = config.Require("name");
var lucky = config.GetInt32("lucky") ?? 42;
Console.WriteLine($"Hello, {name} -- I see your lucky number is {lucky}!");
Structured Configuration
Structured configuration is also supported and can be set using pulumi config set
and the --path
flag. When --path
is used, it indicates the config key contains a path of where to store the value in an object.
For example:
$ pulumi config set --path 'data.active' true
$ pulumi config set --path 'data.nums[0]' 1
$ pulumi config set --path 'data.nums[1]' 2
$ pulumi config set --path 'data.nums[2]' 3
The structure of data
is persisted in the stack’s Pulumi.<stack-name>.yaml
file as:
config:
proj:data:
active: true
nums:
- 1
- 2
- 3
For structured config, true
and false
values are persisted as boolean values, and values convertible to integers are persisted as integers.
The data
config can be accessed in your Pulumi program using:
let config = new pulumi.Config();
let data = config.requireObject("data");
console.log(`Active: ${data.active}`);
interface Data {
active: boolean;
nums: number[];
}
let config = new pulumi.Config();
let data = config.requireObject<Data>("data");
console.log(`Active: ${data.active}`);
config = pulumi.Config()
data = config.require_object("data")
print("Active:", data.get("active"))
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)
type Data struct {
Active bool
Nums []int
}
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
var d Data
cfg := config.New(ctx, "")
cfg.RequireObject("data", &d)
fmt.Printf("Active: %v\n", d.Active)
return nil
})
}
var config = new Pulumi.Config();
var data = config.RequireObject<JsonElement>("data");
Console.WriteLine($"Active: {data.GetProperty("active")}");