Using Output Helpers
Pulumi’s SDKs include helper functions designed for the most common output manipulation tasks: constructing strings from output values and working with JSON. These helpers wrap apply and all internally, but expose a more concise interface that closely mirrors each language’s native string and JSON facilities.
Use a helper when you need to build a string from one or more outputs or serialize a data structure that contains outputs to JSON. Use apply or all directly when the transformation you need is more complex than a simple string or JSON operation.
String interpolation
Pulumi’s string interpolation helpers let you construct a string from one or more output values without calling apply or all explicitly. The helpers work for both a single output and multiple outputs, so they serve as a convenient shorthand regardless of how many values you are combining.
"use strict";
const pulumi = require("@pulumi/pulumi");
const aws = require("@pulumi/aws");
const bucket = new aws.s3.Bucket("bucket");
const file = new aws.s3.BucketObject("bucket-object", {
bucket: bucket.id,
key: "some-file.txt",
content: "some-content",
});
// concat takes a list of args and concatenates all of them into a single output:
exports.s3Url1 = pulumi.concat("s3://", bucket.bucket, "/", file.key);
// interpolate takes a JavaScript template literal and expands outputs correctly:
exports.s3Url2 = pulumi.interpolate`s3://${bucket.bucket}/${file.key}`;
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const bucket = new aws.s3.Bucket("bucket");
const file = new aws.s3.BucketObject("bucket-object", {
bucket: bucket.id,
key: "some-file.txt",
content: "some-content",
});
// concat takes a list of args and concatenates all of them into a single output:
export const s3Url1: pulumi.Output<string> = pulumi.concat("s3://", bucket.bucket, "/", file.key);
// interpolate takes a JavaScript template literal and expands outputs correctly:
export const s3Url2: pulumi.Output<string> = pulumi.interpolate`s3://${bucket.bucket}/${file.key}`;
import pulumi
import pulumi_aws as aws
bucket = aws.s3.Bucket("bucket")
file = aws.s3.BucketObject("bucket-object",
bucket=bucket.id,
key="some-file.txt",
content="some-content",
)
# concat takes a list of args and concatenates all of them into a single output:
s3Url1 = pulumi.Output.concat("s3://", bucket.bucket, "/", file.key)
# format takes a template string and a list of args or keyword args and formats the string, expanding outputs correctly:
s3Url2 = pulumi.Output.format("s3://{0}/{1}", bucket.bucket, file.key)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
bucket, err := s3.NewBucket(ctx, "bucket", nil)
if err != nil {
return err
}
file, err := s3.NewBucketObject(ctx, "bucket-object", &s3.BucketObjectArgs{
Bucket: bucket.ID(),
Key: pulumi.String("some-file.txt"),
Content: pulumi.String("some-content"),
})
if err != nil {
return err
}
s3Url := pulumi.Sprintf("s3://%s/%s", bucket.ID(), file.Key)
ctx.Export("s3Url", s3Url)
return nil
})
}
using System.Collections.Generic;
using Pulumi;
using Pulumi.Aws.S3;
return await Deployment.RunAsync(() =>
{
var bucket = new Bucket("bucket");
var file = new BucketObject("bucket-object", new BucketObjectArgs
{
Bucket = bucket.Id,
Key = "some-file.txt",
Content = "some-content",
});
var s3Url = Output.Format($"s3://{bucket.Id}/{file.Key}");
return new Dictionary<string, object?>
{
["s3Url"] = s3Url,
};
});
package myproject;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketObject;
import com.pulumi.aws.s3.BucketObjectArgs;
import com.pulumi.core.Output;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var bucket = new Bucket("bucket");
var file = new BucketObject("bucket-object", BucketObjectArgs.builder()
.bucket(bucket.id())
.key("some-file.txt")
.content("some-content")
.build());
var s3Url = Output.format("s3://%s/%s", bucket.bucket(), file.key());
ctx.export("s3Url", s3Url);
}
}
name: aws-s3bucket-bucketobject-interpolate-yaml
runtime: yaml
description: An example that creates an S3 bucket and bucket object
resources:
bucket:
type: aws:s3:Bucket
name: bucket
bucketObject:
type: aws:s3/bucketObject:BucketObject
name: bucket-object
properties:
bucket: ${bucket.id}
key: some-file.txt
content: some-content
outputs:
s3Url: s3://${bucket.id}/${bucketObject.key}
TypeScript and JavaScript provide two string helpers:
pulumi.interpolate— A tagged template literal that accepts Pulumi outputs directly inside${}expressions. It is the most idiomatic option in TypeScript and handles any number of values.pulumi.concat()— Concatenates a list of strings and outputs into a singleOutput<string>. Useful when you are building a string from a dynamic list of values rather than a fixed template.
For more details, see the Node.js SDK documentation.
Python provides two string helpers:
pulumi.Output.format()— Works like Python’sstr.format(), accepting a format string with positional or keyword placeholders. This is the most idiomatic option for Python programs.pulumi.Output.concat()— Concatenates a list of strings and outputs into a singleOutput[str].
For more details, see the Python SDK documentation.
Go provides:
pulumi.Sprintf()— Works like Go’sfmt.Sprintf(), accepting a format string and a variadic list of arguments that may be plain values or Pulumi outputs. Returns apulumi.StringOutput.
For more details, see the Go SDK documentation.
.NET provides:
Output.Format()— Works like C#’s interpolated string syntax. Pass a C# interpolated string containingOutput<T>values, andOutput.Formatreturns a singleOutput<string>.
For more details, see the .NET SDK documentation.
Java provides:
Output.format()— Works like Java’sString.format(), accepting a format string with%splaceholders and a list of arguments that may be plain values or Pulumi outputs. Returns anOutput<String>.
For more details, see the Java SDK documentation.
Pulumi YAML supports string interpolation natively. Use ${...} syntax directly within any string value to reference resource outputs or variables:
outputs:
s3Url: s3://${bucket.id}/${bucketObject.key}
For more details, see the YAML language reference.
JSON helpers
Many cloud resources accept JSON strings as inputs — IAM policies, Lambda function configurations, S3 bucket policies, and others. Pulumi’s JSON helpers let you work with data structures that contain outputs without needing to call apply manually to extract the underlying values.
Converting outputs to JSON strings
If you need to produce a JSON string from a data structure that contains one or more output values, use one of the JSON stringify helpers. These helpers accept a mix of plain values and Pulumi outputs, serialize the entire structure to JSON, and return an Output<string> suitable for passing to another resource as an input.
"use strict";
const pulumi = require("@pulumi/pulumi");
const aws = require("@pulumi/aws");
// Get the account ID of the current user as a Pulumi output.
const accountID = aws.getCallerIdentityOutput().accountId;
// Create an S3 bucket.
const bucket = new aws.s3.Bucket("my-bucket");
// Create an S3 bucket policy allowing anyone in the account to list the contents of the bucket.
const policy = new aws.s3.BucketPolicy("my-bucket-policy", {
bucket: bucket.id,
policy: pulumi.jsonStringify({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: {
AWS: pulumi.interpolate`arn:aws:iam::${accountID}:root`,
},
Action: "s3:ListBucket",
Resource: bucket.arn,
},
],
}),
});
// Export the name of the bucket
exports.bucketName = bucket.id;
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Get the account ID of the current user as a Pulumi output.
const accountID = aws.getCallerIdentityOutput().accountId;
// Create an S3 bucket.
const bucket = new aws.s3.Bucket("my-bucket");
// Create an S3 bucket policy allowing anyone in the account to list the contents of the bucket.
const policy = new aws.s3.BucketPolicy("my-bucket-policy", {
bucket: bucket.id,
policy: pulumi.jsonStringify({
Version: "2012-10-17",
Statement: [
{
Effect: "Allow",
Principal: {
AWS: pulumi.interpolate`arn:aws:iam::${accountID}:root`,
},
Action: "s3:ListBucket",
Resource: bucket.arn,
},
],
}),
});
// Export the name of the bucket.
export const bucketName = bucket.id;
import pulumi
import pulumi_aws as aws
# Get the account ID of the current user as a Pulumi output.
account_id = aws.get_caller_identity_output().apply(
lambda identity: identity.account_id
)
# Create an S3 bucket.
bucket = aws.s3.Bucket("my-bucket")
# Create an S3 bucket policy allowing anyone in the account to list the contents of the bucket.
policy = aws.s3.BucketPolicy(
"my-bucket-policy",
bucket=bucket.id,
policy=pulumi.Output.json_dumps(
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": pulumi.Output.format("arn:aws:iam::{0}:root", account_id)
},
"Action": "s3:ListBucket",
"Resource": bucket.arn,
}
],
}
),
)
# Export the name of the bucket
pulumi.export("bucketName", bucket.id)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Get the account ID of the current user as a Pulumi Output.
callerIdentity, err := aws.GetCallerIdentity(ctx, nil, nil)
if err != nil {
return err
}
accountID := callerIdentity.AccountId
// Create an AWS resource (S3 Bucket)
bucket, err := s3.NewBucket(ctx, "my-bucket", nil)
if err != nil {
return err
}
// Create an S3 bucket policy allowing anyone in the account to list the contents of the bucket.
_, err = s3.NewBucketPolicy(ctx, "my-bucket-policy", &s3.BucketPolicyArgs{
Bucket: bucket.ID(),
Policy: pulumi.JSONMarshal(map[string]interface{}{
"Version": pulumi.ToOutput("2012-10-17"),
"Statement": pulumi.ToOutput([]interface{}{
pulumi.ToMapOutput(map[string]pulumi.Output{
"Effect": pulumi.ToOutput("Allow"),
"Principal": pulumi.ToMapOutput(map[string]pulumi.Output{
"AWS": pulumi.Sprintf("arn:aws:iam::%s:root", accountID),
}),
"Action": pulumi.ToOutput("s3:ListBucket"),
"Resource": bucket.Arn,
}),
}),
}),
})
if err != nil {
return err
}
// Export the name of the bucket
ctx.Export("bucketName", bucket.ID())
return nil
})
}
using System.Collections.Generic;
using Pulumi;
using Pulumi.Aws.S3;
return await Deployment.RunAsync(() =>
{
// Get the account ID of the current user as a Pulumi output.
var accountID = Pulumi.Aws.GetCallerIdentity.Invoke().Apply(identity => identity.AccountId);
// Create an S3 bucket.
var bucket = new Bucket("my-bucket");
// Create an S3 bucket policy allowing anyone in the account to list the contents of the bucket.
var policy = new BucketPolicy("my-bucket-policy", new BucketPolicyArgs
{
Bucket = bucket.Id,
Policy = Output.JsonSerialize(Output.Create(
new
{
Version = "2012-10-17",
Statement = new[]
{
new
{
Effect = "Allow",
Principal = new
{
AWS = Output.Format($"arn:aws:iam::{accountID}:root")
},
Action = "s3:ListBucket",
Resource = bucket.Arn,
}
}
}
))
}
);
// Export the name of the bucket.
return new Dictionary<string, object?> { ["bucketName"] = bucket.Id };
});
pulumi.jsonStringify()— Accepts a value or output object and returns anOutput<string>of its JSON representation. Equivalent in behavior toJSON.stringify().
For more details, see the Node.js SDK documentation.
pulumi.Output.json_dumps()— Accepts a value or output and returns anOutput[str]of its JSON representation. Equivalent in behavior tojson.dumps().
For more details, see the Python SDK documentation.
pulumi.JSONMarshal()— Accepts apulumi.Inputvalue and marshals it to a JSON string output using Go’sencoding/jsonpackage.
For more details, see the Go SDK documentation.
Output.JsonSerialize()— Accepts anOutput<T>and returns anOutput<string>of its JSON representation usingSystem.Text.Json.
For more details, see the .NET SDK documentation.
Java does not provide a dedicated JSON stringify helper. Use apply with a JSON library such as Jackson or Gson to serialize output values to JSON strings manually.
Converting JSON strings to outputs
If you have an output in the form of a JSON string and need to read individual fields from it or pass it to a function that expects a plain object, use one of the JSON parse helpers. These accept an output containing a JSON string and return a deserialized output.
"use strict";
const pulumi = require("@pulumi/pulumi");
const jsonIAMPolicy = pulumi.output(`{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}`);
// Parse the string output.
const policyWithNoStatements = pulumi.jsonParse(jsonIAMPolicy).apply(policy => {
// Empty the policy's Statements list.
policy.Statement = [];
return policy;
});
// Export the modified policy.
exports.policy = policyWithNoStatements;
import * as pulumi from "@pulumi/pulumi";
const jsonIAMPolicy = pulumi.output(`{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}`);
// Parse the string output.
const policyWithNoStatements: pulumi.Output<object> = pulumi.jsonParse(jsonIAMPolicy).apply(policy => {
// Empty the policy's Statements list.
policy.Statement = [];
return policy;
});
// Export the modified policy.
export const policy = policyWithNoStatements;
import pulumi
json_iam_policy = pulumi.Output.from_input(
"""
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}
"""
)
def update_policy(policy):
# Empty the policy's Statements list.
policy.update({"Statement": []})
return policy
# Parse the string output.
policy_with_no_statements = pulumi.Output.json_loads(json_iam_policy).apply(
lambda policy: update_policy
)
# Export the modified policy.
pulumi.export("policy", policy_with_no_statements)
package main
import (
"encoding/json"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
jsonIAMPolicy := pulumi.ToOutput(`{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}`)
// Parse the string output.
policyWithNoStatements := jsonIAMPolicy.ApplyT(
func(jsonStr string) (map[string]interface{}, error) {
var policy map[string]interface{}
if err := json.Unmarshal([]byte(jsonStr), &policy); err != nil {
return nil, err
}
// Empty the policy's Statements list.
policy["Statement"] = []interface{}{}
return policy, nil
},
)
// Export the modified policy.
ctx.Export("policy", policyWithNoStatements)
return nil
})
}
using System.Collections.Generic;
using Pulumi;
return await Deployment.RunAsync(() =>
{
var jsonIAMPolicy = Output.Create(
@"
{
""Version"": ""2012-10-17"",
""Statement"": [
{
""Sid"": ""VisualEditor0"",
""Effect"": ""Allow"",
""Action"": [
""s3:ListAllMyBuckets"",
""s3:GetBucketLocation""
],
""Resource"": ""*""
},
{
""Sid"": ""VisualEditor1"",
""Effect"": ""Allow"",
""Action"": [
""s3:*""
],
""Resource"": ""arn:aws:s3:::my-bucket""
}
]
}
"
);
// Parse the Output<string> into a C# Dictionary.
var policyWithNoStatements = Output
.JsonDeserialize<Dictionary<string, object?>>(jsonIAMPolicy)
.Apply(policy =>
{
// Empty the policy's Statements list.
policy["Statement"] = Output.Create(new List<Dictionary<string, object?>> { });
return policy;
});
// Export the modified policy.
return new Dictionary<string, object?> { ["policy"] = policyWithNoStatements, };
});
pulumi.jsonParse()— Accepts anOutput<string>and returns anOutput<any>of the parsed value. Equivalent in behavior toJSON.parse().
For more details, see the Node.js SDK documentation.
pulumi.Output.json_loads()— Accepts anOutput[str]and returns a deserialized output. Equivalent in behavior tojson.loads().
For more details, see the Python SDK documentation.
Go does not have a dedicated JSON parse helper. Use ApplyT with json.Unmarshal to parse a JSON string output into a Go struct or map.
For more details, see the Go SDK documentation.
Output.JsonDeserialize<T>()— Accepts anOutput<string>containing JSON and returns anOutput<T>of the deserialized value usingSystem.Text.Json.
For more details, see the .NET SDK documentation.
Java does not provide a dedicated JSON parse helper. Use apply with a JSON library such as Jackson or Gson to deserialize JSON string outputs into Java objects manually.
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.