1. Docs
  2. Infrastructure as Code
  3. Concepts
  4. Inputs & Outputs
  5. Using Output Helpers

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 single Output<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’s str.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 single Output[str].

    For more details, see the Python SDK documentation.

    Go provides:

    • pulumi.Sprintf() — Works like Go’s fmt.Sprintf(), accepting a format string and a variadic list of arguments that may be plain values or Pulumi outputs. Returns a pulumi.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 containing Output<T> values, and Output.Format returns a single Output<string>.

    For more details, see the .NET SDK documentation.

    Java provides:

    • Output.format() — Works like Java’s String.format(), accepting a format string with %s placeholders and a list of arguments that may be plain values or Pulumi outputs. Returns an Output<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 an Output<string> of its JSON representation. Equivalent in behavior to JSON.stringify().

    For more details, see the Node.js SDK documentation.

    • pulumi.Output.json_dumps() — Accepts a value or output and returns an Output[str] of its JSON representation. Equivalent in behavior to json.dumps().

    For more details, see the Python SDK documentation.

    • pulumi.JSONMarshal() — Accepts a pulumi.Input value and marshals it to a JSON string output using Go’s encoding/json package.

    For more details, see the Go SDK documentation.

    • Output.JsonSerialize() — Accepts an Output<T> and returns an Output<string> of its JSON representation using System.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 an Output<string> and returns an Output<any> of the parsed value. Equivalent in behavior to JSON.parse().

    For more details, see the Node.js SDK documentation.

    • pulumi.Output.json_loads() — Accepts an Output[str] and returns a deserialized output. Equivalent in behavior to json.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 an Output<string> containing JSON and returns an Output<T> of the deserialized value using System.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.