The aws:secretsmanager/secretVersion:SecretVersion resource, part of the Pulumi AWS provider, manages the actual secret value and version within an existing Secrets Manager secret container. This guide focuses on two capabilities: storing string and JSON secret values, and parsing structured secrets for application use.
Secret versions belong to an aws.secretsmanager.Secret resource, which provides the container and metadata. The examples are intentionally small. Combine them with your own secret containers and rotation policies.
Store a simple string secret value
Most secret storage begins with a single credential like an API key or password.
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 where this version will be stored. The secretString property holds the actual credential value. Secrets Manager encrypts the value at rest and manages access through IAM policies.
Store structured configuration as JSON
Applications often need multiple related credentials grouped together. Secrets Manager accepts JSON for structured data.
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}
JSON.stringify converts the key-value pairs into a string that Secrets Manager can store. This allows you to group related credentials (database username and password, API keys and endpoints) in a single secret rather than managing multiple separate secrets.
Read JSON secrets back into application code
After storing structured secrets, applications parse them back into native 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 parses the secretString back into a map, allowing you to access individual keys. This example retrieves the key1 value from the JSON structure stored in the previous example.
Beyond these examples
These snippets focus on specific secret version features: string and JSON secret storage, and secret value parsing and retrieval. They’re intentionally minimal rather than full secret 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 provisioning the secret metadata.
To keep things focused, common secret version patterns are omitted, including:
- Version staging labels (versionStages)
- Binary secret data (secretBinary)
- Write-only secret updates (secretStringWo, secretStringWoVersion)
- Secret rotation and lifecycle management
These omissions are intentional: the goal is to illustrate how secret values are stored and retrieved, not provide drop-in secret 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
Version Lifecycle & Staging Labels
AWSCURRENT staging label is present during deletion, it can’t be removed and the version stays active. Move the AWSCURRENT label to another version before or after deleting the resource to fully deprecate this version.versionStages, you must include the AWSCURRENT staging label when this is the only version or when the label is currently present on this version. Otherwise, Pulumi will show a perpetual difference.Secret Value Configuration
These are mutually exclusive options for storing secret data:
- secretString: Standard text data (use for most cases)
- secretBinary: Binary data encoded as base64
- secretStringWo: Write-only text data that doesn’t update in state (use when you don’t want the value stored in state)
JSON.stringify() to convert your object to a string for secretString, as shown in the key-value pairs example.std.jsondecode() to parse the secretString back into a native object, then access individual keys.Write-Only Secrets
secretStringWo field is write-only and its value is not updated in state during read operations. This is by design to avoid storing sensitive values in state.secretStringWoVersion integer whenever you update secretStringWo. This triggers Pulumi to recognize the change and update the secret.Immutability & Updates
secretId, secretBinary, secretString, and secretStringWoVersion. Changing these requires creating a new secret version.