Managing Configuration and Secrets
In Pulumi, each stack within your project has a settings file, and this file contains a collection of values intended to capture the configuration details needed to work with a particular environment. These can be plain-text values like server names, environment types (ex: dev, test, prod), region names and so on. They can also be sensitive values such as database passwords or service tokens.
In this tutorial, we’ll demonstrate how to create and utilize configuration and secret values in Pulumi.
In this tutorial, you'll learn:
- How to create a plain-text configuration value
- How to create an encrypted secret configuration value
- How to view configuration details in the CLI
- How to access configuration values from within Pulumi program code
Prerequisites:
- The Pulumi CLI
- A Pulumi Cloud account and access token
- One of Pulumi’s supported language runtimes installed
Create a new project
To start, login to the Pulumi CLI. Next, create a new project by running the pulumi new <language>
command, making sure to replace <language>
with the supported language of your choice:
# example using python
$ pulumi new python
This command will walk you through creating a new Pulumi project.
Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.
project name (pulumi-dev):
project description (A minimal Python Pulumi program):
Created project 'pulumi-dev'
Please enter your desired stack name.
To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
stack name (dev): pulumi/dev
Created stack 'dev'
Installing dependencies...
Creating virtual environment...
Finished creating virtual environment
Updating pip, setuptools, and wheel in virtual environment...
...
...
Finished installing dependencies
Your new project is ready to go!
To perform an initial deployment, run `pulumi up`
This will create simple Pulumi program without any resources or configuration details.
Create configuration values
In a Pulumi project, you can locally store and retrieve configuration values using the pulumi config set <key> [value]
command. To demonstrate, run the following command to create a configuration value with a key of myEnvironment
and a value of development
:
$ pulumi config set myEnvironment development
This value will be stored in your project’s stack settings file Pulumi.<your-stack-name>.yaml
as shown below:
# Contents of Pulumi.<your-stack-name>.yaml file
config:
pulumi-dev:myEnvironment: development
You can also list the configuration values for your stack in the command line. To do so, run the pulumi config
command:
$ pulumi config
KEY VALUE
myEnvironment development
pulumi:tags {"pulumi:template":"python"}
To retrieve a specific configuration value, run the pulumi config get <key>
command as shown below:
$ pulumi config get myEnvironment
development
Create secret values
Pulumi supports encrypting specific values as “secrets” for extra protection. Pulumi Cloud transmits and stores state files over a secure connection, but once received the files are viewable in plain-text. By encrypting secrets, Pulumi ensures that these values never appear as plain-text in your state file. By default, the encryption method uses automatic, per-stack encryption keys provided by Pulumi Cloud, but you can also use a provider of your own choosing instead.
To encrypt a configuration value before runtime, you will need to run the pulumi config set <key> [value] --secret
command. To demonstrate how this works, you’ll create a configuration value named myPassword
. Run the CLI command pulumi config set myPassword <value-of-password>
, making sure to pass the --secret
flag, and also making sure to replace <value-of-password>
with an actual value as shown below:
pulumi config set myPassword demo-password-123 --secret
Now run the pulumi config
command again, and you will see that, unlike the value for myEnvironment
, the value for myPassword
is hidden:
$ pulumi config get myEnvironment
KEY VALUE
myEnvironment development
myPassword [secret]
pulumi:tags {"pulumi:template":"python"}
If you open your project’s stack settings file (e.g. Pulumi.<your-stack-name>.yaml
), you will notice that the password value is also encrypted there:
config:
generic-python:myEnvironment: development
generic-python:myPassword:
secure: AAABADd5YzRaVuzxM08i5z2CJ3LGkQau5e5Lhk+1Gtj37qv6zKkFr8KxmN6X+w/XMg==
Reference values in code
Within your Pulumi program code, configuration values can be retrieved for a given stack using the following:
Config.get
orConfig.require
for raw configuration valuesConfig.getSecret
orConfig.requireSecret
for secret values
get
and require
functions by referring to the Pulumi Configuration concept documentation.To demonstrate, update your Pulumi program code with the following:
"use strict";
const pulumi = require("@pulumi/pulumi");
// Create a new Pulumi Config
const config = new pulumi.Config();
// Retrieve the values of "myEnvironment" and "myPassword"
const environment = config.get("myEnvironment");
const password = config.getSecret("myPassword");
// Export values as stack outputs
module.exports = {
Environment: environment,
Password: password,
};
import * as pulumi from "@pulumi/pulumi";
// Create a new Pulumi Config
const config = new pulumi.Config();
// Retrieve the values of "myEnvironment" and "myPassword"
const environment = config.get("myEnvironment");
const password = config.getSecret("myPassword");
// Export values as stack output
export const Environment = environment;
export const Password = password;
import pulumi
# Import the configuration values
config = pulumi.Config()
# Retrieve the values of "myEnvironment" and "myPassword"
environment = config.get("myEnvironment")
password = config.get_secret("myPassword")
# Export the values as an output
pulumi.export('Environment', environment)
pulumi.export("Password", password)
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 {
// Create a Pulumi Config
config := config.New(ctx, "")
// Retrieve the value of "myEnvironment" and "myPassword"
environment := config.Get("myEnvironment")
password := config.GetSecret("myPassword")
// Export values as outputs
ctx.Export("Environment", pulumi.String(environment))
ctx.Export("Password", pulumi.StringOutput(password))
return nil
})
}
using Pulumi;
using System.Threading.Tasks;
using System.Collections.Generic;
class Program
{
static async Task<int> Main(string[] args)
{
return await Deployment.RunAsync(() =>
{
// Import the configuration values
var config = new Config();
// Retrieve the value of "myEnvironment" and "myPassword"
var environment = config.Get("myEnvironment");
var password = config.GetSecret("myPassword");
// Return a dictionary of outputs
return new Dictionary<string, object?>
{
["Environment"] = environment,
["Password"] = password
};
});
}
}
package myproject;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
public class App {
public static void main(String[] args) {
Pulumi.run(ctx -> {
// Create a Pulumi Config
var config = ctx.config();
// Retrieve the values of "myEnvironment" and "myPassword"
var environment = config.get("myEnvironment");
var password = config.getSecret("myPassword");
// Export the values as a stack outputs
ctx.export("Environment", Output.of(environment));
ctx.export("Password", Output.of(password));
});
}
}
Save your file and then run the pulumi up
command.
$ pulumi up -y
Type Name Status
+ pulumi:pulumi:Stack python-dev created (0.54s)
Outputs:
myEnvironment: "development"
Password : [secret]
Resources:
+ 1 created
Duration: 2s
You can see that the configuration values were successfully imported into the program and exported as outputs, and you can see that the value of Password
, which comes from the secret configuration value myPassword
, is still not visible.
Clean Up
Before moving on, tear down the resources that are part of your stack to avoid incurring any charges.
- Run
pulumi destroy
to tear down all resources. You'll be prompted to make sure you really want to delete these resources. A destroy operation may take some time, since Pulumi waits for the resources to finish shutting down before it considers the destroy operation to be complete. - To delete the stack itself, run
pulumi stack rm
. Note that this command deletes all deployment history from the Pulumi Service.
Next Steps
In this tutorial, you created raw and secret configuration values in your project’s stack. You also accessed these values via your Pulumi program code.
To learn more about managing and utilizing configuration and secrets in Pulumi, take a look at the following resources:
- Learn more about more about how to centralize your configuration and secrets in the Pulumi ESC documentation.
- Learn more about stack outputs and references in the Stack Outputs and References tutorial.