Skip to main content
Pulumi logo Pulumi logo
  1. Docs
  2. Infrastructure as Code
  3. Guides
  4. Basics
  5. Language Essentials
  6. Variables

Variables and Values

    A variable gives a name to a value so you can reuse it and refer to it later. Every configuration language you already use has a version of this: a locals block in HCL, a variables: section in Pulumi YAML. In a general-purpose language, naming a value is the most basic thing you do, and it works the same way whether the value is a string, a number, or the result of creating a resource.

    Where you have seen this before

    In Pulumi YAML, variables names a value once so you can reference it elsewhere in the same file:

    variables:
      bucketName: my-app-data
    resources:
      bucket:
        type: aws:s3:Bucket
        properties:
          bucket: ${bucketName}
    

    In Terraform HCL, a locals block does the same thing, and ${...} interpolation substitutes it into a string:

    locals {
      bucket_name = "my-app-data"
    }
    
    resource "aws_s3_bucket" "bucket" {
      bucket = "${local.bucket_name}"
    }
    

    The syntax

    In a general-purpose language, you declare a variable and assign it a value in one statement. Most Pulumi languages infer the type from the value, so you rarely write the type out yourself.

    const bucketName = "my-app-data";
    const replicaCount = 3;
    
    bucket_name = "my-app-data"
    replica_count = 3
    
    bucketName := "my-app-data"
    replicaCount := 3
    
    var bucketName = "my-app-data";
    var replicaCount = 3;
    
    var bucketName = "my-app-data";
    var replicaCount = 3;
    
    variables:
      bucketName: my-app-data
      replicaCount: 3
    
    locals {
      bucket_name   = "my-app-data"
      replica_count = 3
    }
    

    Building a string out of a variable works the way you’d expect from ${...} interpolation, just with each language’s own syntax: template literals in TypeScript, f-strings in Python, fmt.Sprintf in Go, $"..." in C#, and String.format in Java.

    const label = `${bucketName}-${replicaCount}`;
    
    label = f"{bucket_name}-{replica_count}"
    
    label := fmt.Sprintf("%s-%d", bucketName, replicaCount)
    
    var label = $"{bucketName}-{replicaCount}";
    
    var label = String.format("%s-%d", bucketName, replicaCount);
    
    variables:
      label: ${bucketName}-${replicaCount}
    
    locals {
      label = "${local.bucket_name}-${local.replica_count}"
    }
    

    In a Pulumi program

    Stack configuration is the language equivalent of a Pulumi.<stack>.yaml value you’d otherwise reference directly. You read it into a variable with pulumi.Config and use it the same way you’d use any other variable. Set the value first, since config.require fails if it isn’t set:

    pulumi config set environment production
    
    import * as pulumi from "@pulumi/pulumi";
    import * as aws from "@pulumi/aws";
    
    const config = new pulumi.Config();
    const environment = config.require("environment");
    
    const bucket = new aws.s3.Bucket(`data-${environment}`);
    
    import pulumi
    import pulumi_aws as aws
    
    config = pulumi.Config()
    environment = config.require("environment")
    
    bucket = aws.s3.Bucket(f"data-{environment}")
    
    package main
    
    import (
    	"fmt"
    
    	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
    	"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, "")
    		environment := cfg.Require("environment")
    
    		_, err := s3.NewBucket(ctx, fmt.Sprintf("data-%s", environment), nil)
    		return err
    	})
    }
    
    using Pulumi;
    using Pulumi.Aws.S3;
    
    return await Deployment.RunAsync(() =>
    {
        var config = new Config();
        var environment = config.Require("environment");
    
        var bucket = new Bucket($"data-{environment}");
    });
    
    import com.pulumi.Pulumi;
    import com.pulumi.Config;
    import com.pulumi.aws.s3.Bucket;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
                var config = ctx.config();
                var environment = config.require("environment");
    
                var bucket = new Bucket("data-" + environment);
            });
        }
    }
    
    config:
      environment:
        type: string
    resources:
      bucket:
        type: aws:s3:Bucket
        properties:
          bucket: data-${environment}
    
    variable "environment" {
      type = string
    }
    
    resource "aws_s3_bucket" "bucket" {
      bucket = "data-${var.environment}"
    }
    

    What to watch out for

    Not every value on a resource is a plain string or number you can interpolate directly. Many resource properties are outputs: values Pulumi doesn’t know until the resource is actually created, such as a generated ARN or a load balancer’s DNS name. Ordinary string interpolation doesn’t work on an output, because the value isn’t available when your program runs. See inputs and outputs for how that model works, and each language’s interpolation helper, such as pulumi.interpolate in TypeScript or pulumi.Output.format() in Python, for building strings out of them.

    Next steps

    Continue to conditionals to see how if statements replace count-based conditionals.

    Learn more

    • Configuration for the full set of options for reading and validating stack configuration.

      The infrastructure as code platform for any cloud.