The aws:secretsmanager/secretVersion:SecretVersion resource, part of the Pulumi AWS provider, manages the actual secret value and its version within an existing Secrets Manager secret container. This guide focuses on three capabilities: string secret storage, JSON-encoded key-value pairs, and reading structured secrets.
Secret versions require an existing aws.secretsmanager.Secret resource as the container. The examples are intentionally small. Combine them with your own secret containers and rotation policies.
Store a simple string secret
Most secrets start as plain text values like API keys or passwords that need encryption at rest.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.secretsmanager.SecretVersion("example", {
secretId: exampleAwsSecretsmanagerSecret.id,
secretString: "example-string-to-protect",
});
import pulumi
import pulumi_aws as aws
example = aws.secretsmanager.SecretVersion("example",
secret_id=example_aws_secretsmanager_secret["id"],
secret_string="example-string-to-protect")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/secretsmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := secretsmanager.NewSecretVersion(ctx, "example", &secretsmanager.SecretVersionArgs{
SecretId: pulumi.Any(exampleAwsSecretsmanagerSecret.Id),
SecretString: pulumi.String("example-string-to-protect"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var example = new Aws.SecretsManager.SecretVersion("example", new()
{
SecretId = exampleAwsSecretsmanagerSecret.Id,
SecretString = "example-string-to-protect",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.secretsmanager.SecretVersion;
import com.pulumi.aws.secretsmanager.SecretVersionArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var example = new SecretVersion("example", SecretVersionArgs.builder()
.secretId(exampleAwsSecretsmanagerSecret.id())
.secretString("example-string-to-protect")
.build());
}
}
resources:
example:
type: aws:secretsmanager:SecretVersion
properties:
secretId: ${exampleAwsSecretsmanagerSecret.id}
secretString: example-string-to-protect
The secretId property references the secret container that must already exist. The secretString property holds the value to encrypt. Secrets Manager encrypts the value automatically and assigns it a version ID.
Store structured data as JSON
Applications often need multiple related values grouped together, like database credentials with host, username, and password.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const config = new pulumi.Config();
const example = config.getObject<Record<string, string>>("example") || {
key1: "value1",
key2: "value2",
};
const exampleSecretVersion = new aws.secretsmanager.SecretVersion("example", {
secretId: exampleAwsSecretsmanagerSecret.id,
secretString: JSON.stringify(example),
});
import pulumi
import json
import pulumi_aws as aws
config = pulumi.Config()
example = config.get_object("example")
if example is None:
example = {
"key1": "value1",
"key2": "value2",
}
example_secret_version = aws.secretsmanager.SecretVersion("example",
secret_id=example_aws_secretsmanager_secret["id"],
secret_string=json.dumps(example))
package main
import (
"encoding/json"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/secretsmanager"
"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 {
cfg := config.New(ctx, "")
example := map[string]interface{}{
"key1": "value1",
"key2": "value2",
}
if param := cfg.GetObject("example"); param != nil {
example = param
}
tmpJSON0, err := json.Marshal(example)
if err != nil {
return err
}
json0 := string(tmpJSON0)
_, err = secretsmanager.NewSecretVersion(ctx, "example", &secretsmanager.SecretVersionArgs{
SecretId: pulumi.Any(exampleAwsSecretsmanagerSecret.Id),
SecretString: pulumi.String(json0),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var config = new Config();
var example = config.GetObject<Dictionary<string, string>>("example") ??
{
{ "key1", "value1" },
{ "key2", "value2" },
};
var exampleSecretVersion = new Aws.SecretsManager.SecretVersion("example", new()
{
SecretId = exampleAwsSecretsmanagerSecret.Id,
SecretString = JsonSerializer.Serialize(example),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.secretsmanager.SecretVersion;
import com.pulumi.aws.secretsmanager.SecretVersionArgs;
import static com.pulumi.codegen.internal.Serialization.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var config = ctx.config();
final var example = config.get("example").orElse(Map.ofEntries(
Map.entry("key1", "value1"),
Map.entry("key2", "value2")
));
var exampleSecretVersion = new SecretVersion("exampleSecretVersion", SecretVersionArgs.builder()
.secretId(exampleAwsSecretsmanagerSecret.id())
.secretString(serializeJson(
example))
.build());
}
}
configuration:
# The map here can come from other supported configurations
# like locals, resource attribute, map() built-in, etc.
example:
type: map(string)
default:
key1: value1
key2: value2
resources:
exampleSecretVersion:
type: aws:secretsmanager:SecretVersion
name: example
properties:
secretId: ${exampleAwsSecretsmanagerSecret.id}
secretString:
fn::toJSON: ${example}
Secrets Manager accepts JSON-encoded strings, allowing you to store multiple key-value pairs in a single secret version. Use JSON.stringify to convert your data structure before passing it to secretString. This keeps related configuration together while maintaining encryption.
Read JSON secrets back into native structures
After storing JSON in a secret, applications need to parse it back into usable data structures.
import * as pulumi from "@pulumi/pulumi";
import * as std from "@pulumi/std";
export const example = std.jsondecode({
input: exampleAwsSecretsmanagerSecretVersion.secretString,
}).then(invoke => invoke.result?.key1);
import pulumi
import pulumi_std as std
pulumi.export("example", std.jsondecode(input=example_aws_secretsmanager_secret_version["secretString"]).result["key1"])
package main
import (
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
ctx.Export("example", pulumi.Any(std.Jsondecode(ctx, &std.JsondecodeArgs{
Input: exampleAwsSecretsmanagerSecretVersion.SecretString,
}, nil).Result.Key1))
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
return new Dictionary<string, object?>
{
["example"] = Std.Jsondecode.Invoke(new()
{
Input = exampleAwsSecretsmanagerSecretVersion.SecretString,
}).Apply(invoke => invoke.Result?.Key1),
};
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.JsondecodeArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
ctx.export("example", StdFunctions.jsondecode(JsondecodeArgs.builder()
.input(exampleAwsSecretsmanagerSecretVersion.secretString())
.build()).result().key1());
}
}
outputs:
example:
fn::invoke:
function: std:jsondecode
arguments:
input: ${exampleAwsSecretsmanagerSecretVersion.secretString}
return: result.key1
The jsondecode function converts the stored JSON string back into a native map, letting you extract individual values. This complements JSON storage by showing how to retrieve and use the structured data in your application code.
Beyond these examples
These snippets focus on specific secret version features: string and JSON secret storage, and JSON parsing for structured data. They’re intentionally minimal rather than full secrets management solutions.
The examples require pre-existing infrastructure such as the aws.secretsmanager.Secret resource (the secret container itself). They focus on storing and retrieving secret values rather than managing secret metadata or rotation.
To keep things focused, common secret version patterns are omitted, including:
- Binary secret storage (secretBinary)
- Version staging labels (versionStages)
- Write-only secrets (secretStringWo, secretStringWoVersion)
- Secret rotation and lifecycle policies
These omissions are intentional: the goal is to illustrate how secret values are stored and retrieved, not provide drop-in secrets management modules. See the SecretVersion resource reference for all available configuration options.
Let's manage AWS Secrets Manager Secret Versions
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Staging Labels & Lifecycle
AWSCURRENT staging label is present during deletion, it cannot be removed and will keep the secret version active. Move the AWSCURRENT label to another version before or after deleting this resource to fully deprecate the version.versionStages, you must include AWSCURRENT when this is the only version or when the label is currently present on this version. Otherwise, Pulumi will show a perpetual difference.AWSCURRENT staging label to the new version on creation.Secret Value Types & Formats
You must provide exactly one of these three options:
secretString: Text data (immutable, stored in state)secretBinary: Binary data encoded as base64 (immutable, stored in state)secretStringWo: Write-only text data (not stored in state after creation)
secretStringWo with secretStringWoVersion. Increment secretStringWoVersion each time you need to update the secretStringWo value to trigger an update.secretBinary.Working with JSON Secrets
JSON.stringify() to convert your object to a string and pass it to secretString, as shown in the key-value pairs example.std.jsondecode() with the secretString output to parse the JSON back into a native object and access individual keys.