1. Tutorials
  2. Reference Azure Resources Across Stacks

Reference Azure Resources Across Stacks

In this tutorial, you will learn how to work with stack outputs, specifically how to export values from a stack and how to reference those values from another stack. You will do this by creating simple Azure Resource Group, Storage Account, and Blob Container resources in one stack. You will then create a Blob resource in a second project/stack that will upload a file to the Blob Storage defined in the first stack.

In this tutorial, you'll learn:

  • How to create a stack output
  • How to view the stack output
  • How to reference the output from a different stack

Understanding stack outputs

Every Pulumi resource has outputs, which are properties of that resource whose values are generated during deployment. You can export these values as stack outputs, and they can be used for important values like resource IDs, computed IP addresses, and DNS names.

These outputs are shown during an update, can be easily retrieved with the Pulumi CLI, and are displayed in Pulumi Cloud. For the purposes of this tutorial, you will primarily be working from the CLI.

Create a new project

# Example using Python
$ mkdir pulumi-tutorial-azure
$ cd pulumi-tutorial-azure
$ pulumi new azure-python

Then replace the default code with the following code snippet to scaffold your project with the required imports and overall program structure:

"use strict";
const pulumi = require("@pulumi/pulumi");
const resources = require("@pulumi/azure-native/resources");
const storage = require("@pulumi/azure-native/storage");

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});
import * as pulumi from "@pulumi/pulumi";
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});
import pulumi
import pulumi_azure_native as azure_native

resource_group = azure_native.resources.ResourceGroup("resource-group")

storage_account = azure_native.storage.StorageAccount(
    "storageaccount",
    resource_group_name=resource_group.name,
    kind="StorageV2",
    sku={
        "name": "Standard_LRS",
    },
)

blob_container = azure_native.storage.BlobContainer("blobcontainer",
    account_name=storage_account.name,
    resource_group_name=resource_group.name
)
package main

import (
	"github.com/pulumi/pulumi-azure-native-sdk/resources/v2"
	"github.com/pulumi/pulumi-azure-native-sdk/storage/v2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		resourceGroup, err := resources.NewResourceGroup(ctx, "resourceGroup", nil)
		if err != nil {
			return err
		}

		storageAccount, err := storage.NewStorageAccount(ctx, "sa", &storage.StorageAccountArgs{
			ResourceGroupName: resourceGroup.Name,
			Sku: &storage.SkuArgs{
				Name: pulumi.String("Standard_LRS"),
			},
			Kind: pulumi.String("StorageV2"),
		})
		if err != nil {
			return err
		}

		blobContainer, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:                 storageAccount.Name,
			ResourceGroupName:           resourceGroup.Name,
		})
		if err != nil {
			return err
		}

		return nil
	})
}
using Pulumi;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using System.Collections.Generic;

return await Pulumi.Deployment.RunAsync(() =>
{
    var resourceGroup = new ResourceGroup("resourceGroup");

    var storageAccount = new StorageAccount("sa", new StorageAccountArgs
    {
        ResourceGroupName = resourceGroup.Name,
        Sku = new SkuArgs
        {
            Name = SkuName.Standard_LRS
        },
        Kind = Kind.StorageV2
    });

    var blobContainer = new BlobContainer("blobContainer", new()
    {
        AccountName = resourceGroup.Name,
        ResourceGroupName = storageAccount.Name,
    });

});
name: azure-native-storage-account-blob-yaml
description: An example that deploys a blob into a blob storage account on Azure.
runtime: yaml

resources:
  resourceGroup:
    type: azure-native:resources:ResourceGroup
  storageAccount:
    type: azure-native:storage:StorageAccount
    properties:
      resourceGroupName: ${resourceGroup.name}
      sku:
        name: Standard_LRS
      kind: StorageV2
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: ${storageAccount.name}
      resourceGroupName: ${resourceGroup.name}

This baseline code defines the following on your behalf:

Export resource values

As mentioned in the Creating Resources on Azure tutorial, every resource has various properties. For any resources that you define in your Pulumi projects, you can export the values of its properties from your program as outputs. You can view a list of available properties that can be exported by referring to the resource properties section of a particular resource’s API documentation (e.g. Resource Group resource properties). The export syntax is as follows:

exports.<output-name> = <output-value>;
export const <output-name> = <output-value>;
pulumi.export("<output-name>", <output-value>)
ctx.Export("<output-name>", <output-value>)
return await Pulumi.Deployment.RunAsync(() =>
{

    return new Dictionary<string, object?>
    {
        ["<output-name>"] = <output-value>
    };

});
outputs:
  <output-name>: ${<output-value>}

When defining these exports, you’ll need to provide two arguments:

ArgumentDescription
Output nameThis is the name you will use as the identifier of your output value
Output valueThis is the actual value of your output

To demonstrate how this works, let’s export the name of your resource group. By referring to the documentation, you can see that the name of the resource group can be referenced via its name property, so update your code to reflect that as shown below:

"use strict";
const pulumi = require("@pulumi/pulumi");
const resources = require("@pulumi/azure-native/resources");
const storage = require("@pulumi/azure-native/storage");

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});

exports.resourceGroupName = resourceGroup.name;
import * as pulumi from "@pulumi/pulumi";
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});

export const resourceGroupName = resourceGroup.name;
import pulumi
import pulumi_azure_native as azure_native

resource_group = azure_native.resources.ResourceGroup("resource-group")

storage_account = azure_native.storage.StorageAccount(
    "storageaccount",
    resource_group_name=resource_group.name,
    kind="StorageV2",
    sku={
        "name": "Standard_LRS",
    },
)

blob_container = azure_native.storage.BlobContainer("blobcontainer",
    account_name=storage_account.name,
    resource_group_name=resource_group.name
)

pulumi.export("resourceGroupName", resource_group.name)
package main

import (
	"github.com/pulumi/pulumi-azure-native-sdk/resources/v2"
	"github.com/pulumi/pulumi-azure-native-sdk/storage/v2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		resourceGroup, err := resources.NewResourceGroup(ctx, "resourceGroup", nil)
		if err != nil {
			return err
		}

		storageAccount, err := storage.NewStorageAccount(ctx, "sa", &storage.StorageAccountArgs{
			ResourceGroupName: resourceGroup.Name,
			Sku: &storage.SkuArgs{
				Name: pulumi.String("Standard_LRS"),
			},
			Kind: pulumi.String("StorageV2"),
		})
		if err != nil {
			return err
		}

		blobContainer, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:                 storageAccount.Name,
			ResourceGroupName:           resourceGroup.Name,
		})
		if err != nil {
			return err
		}

		ctx.Export("resourceGroupName", resourceGroup.Name)

		return nil
	})
}
using Pulumi;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using System.Collections.Generic;

return await Pulumi.Deployment.RunAsync(() =>
{
    var resourceGroup = new ResourceGroup("resourceGroup");

    var storageAccount = new StorageAccount("sa", new StorageAccountArgs
    {
        ResourceGroupName = resourceGroup.Name,
        Sku = new SkuArgs
        {
            Name = SkuName.Standard_LRS
        },
        Kind = Kind.StorageV2
    });

    var blobContainer = new BlobContainer("blobContainer", new()
    {
        AccountName = resourceGroup.Name,
        ResourceGroupName = storageAccount.Name,
    });

    return new Dictionary<string, object?>
    {
        ["resourceGroupName"] = resourceGroup.Name,

    };
});
name: azure-native-storage-account-blob-yaml
description: An example that deploys a blob into a blob storage account on Azure.
runtime: yaml

resources:
  resourceGroup:
    type: azure-native:resources:ResourceGroup
  storageAccount:
    type: azure-native:storage:StorageAccount
    properties:
      resourceGroupName: ${resourceGroup.name}
      sku:
        name: Standard_LRS
      kind: StorageV2
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: ${storageAccount.name}
      resourceGroupName: ${resourceGroup.name}

outputs:
  resourceGroupName: ${resourceGroup.name}

Deploy your resources

Now save your file and run the pulumi up command to preview and deploy the resources you’ve just defined in your project.

$ pulumi up -y
Previewing update (infra)

     Type                                     Name                  Plan
 +   pulumi:pulumi:Stack                      infra                 create
 +   ├─ azure-native:resources:ResourceGroup  resource-group        create
 +   ├─ azure-native:storage:StorageAccount   storageaccount        create
 +   └─ azure-native:storage:BlobContainer    blobcontainer         create

Outputs:
    resourceGroupName: output<string>

Resources:
    + 4 to create

Updating (infra)

     Type                                     Name                  Status
 +   pulumi:pulumi:Stack                      infra                 created (40s)
 +   ├─ azure-native:resources:ResourceGroup  resource-group        created (3s)
 +   ├─ azure-native:storage:StorageAccount   storageaccount        created (27s)
 +   └─ azure-native:storage:BlobContainer    blobcontainer         created (3s)

Outputs:
    resourceGroupName: "resource-group0e6ebba3"

Resources:
    + 4 created

Duration: 42s

You can see that the output you’ve created has been provided as a part of the update details. You will learn the different ways you can access this output in the next steps of the tutorial.

Access outputs via the CLI

Now that your resources are deployed, you can access its value either via the CLI or via your Pulumi program code. To access it via the CLI, you can use the pulumi stack output command. Running this command by itself will list the names and values of all of the exports in your program:

$ pulumi stack output

Current stack outputs (1):
    OUTPUT             VALUE
    resourceGroupName  resource-group0e6ebba3

If you want to retrieve a specific output value, you will need to provide the name of your desired output as shown below:

$ pulumi stack output resourceGroupName

resource-group0e6ebba3

This can be especially useful if you have any workflow scripts that depend on the outputs of your program. For example, if you wanted to view the details of your resource group using the Azure CLI, you can do so by running the az group show command and passing the output of resourceGroupName to the --resource-group flag:

$ az group show --resource-group $(pulumi stack output resourceGroupName)

{
  "id": "/subscriptions/0282681f-7a9e-424b-80b2-96babd57a8a1/resourceGroups/resource-group0e6ebba3",
  "location": "westus2",
  "managedBy": null,
  "name": "resource-group0e6ebba3",
  "properties": { "provisioningState": "Succeeded" },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}

You have seen how you can reference your output values from the CLI. Now let’s take a look at how you can do the same from within another Pulumi program stack.

Access outputs via stack reference

Stack references allow you to access the outputs of one stack from another stack. This enables developers to create resources even when there are inter-stack dependencies. For this section, you are going to create a new Pulumi program that will access stack output values from your existing program.

Reference resource group name

Start by making a new Pulumi project in a new directory. In this new program, you will need to add the code that will reference an output value from your first program. This can be done using Pulumi’s Stack Reference functionality. When defining a stack reference in code, you will need to pass in the fully qualified name of the stack as an argument. This name is comprised of the organization, project, and stack names in the format of <organization>/<project>/<stack>

For example, if the name of your organization is acmecorp, the name of your first program is infra, and the name of your stack is dev, then your fully qualified name will be acmecorp/infra/dev.

With that being said, a stack reference will look like the following in your code:

"use strict";
const pulumi = require("@pulumi/pulumi");

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");
import * as pulumi from "@pulumi/pulumi";

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");
import pulumi

stack_ref = pulumi.StackReference("acmecorp/infra/dev")
package main

import (
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
        stackRef, err := pulumi.NewStackReference(ctx, "acmecorp/infra/dev", nil)
        if err != nil {
            return err
        }

		return nil
	})
}
using Pulumi;

return await Pulumi.Deployment.RunAsync(() =>
{

    var stackRef = new StackReference("acmecorp/infra/dev");

});
name: my-second-app-dev
runtime: yaml
description: A program to create a Stack Reference

resources:
  stack-ref:
    type: pulumi:pulumi:StackReference
    properties:
      name: acmecorp/infra/dev
Make sure that the fully qualified name in the example above is populated with the values that are specific to your Pulumi organization, project, and stack.

You will now create an export in your second program that will output the value of the resource group name from your first program. This is to demonstrate how to retrieve output values from another stack for use in your program.

For the value of your export, you can retrieve it by taking your stack reference variable and using a Stack Reference function called getOutput() against it.

Update your code with the following:

"use strict";
const pulumi = require("@pulumi/pulumi");

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");

// Retrieve resource group name from the first stack
// using the stack reference above
const resourceGroupName = stackRef.getOutput("resourceGroupName");

exports.resourceGroupName = resourceGroupName;
import * as pulumi from "@pulumi/pulumi";

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");

// Retrieve resource group name from the first stack
// using the stack reference above
const resourceGroupName = stackRef.getOutput("resourceGroupName");

export const resourceGroupName = resourceGroupName;
import pulumi

stack_ref = pulumi.StackReference("acmecorp/infra/dev")

# Retrieve resource group name from the first stack
# using the stack reference above
resource_group_name = stack_ref.get_output("resourceGroupName")

pulumi.export("resourceGroupName", resource_group_name)
package main

import (
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
        stackRef, err := pulumi.NewStackReference(ctx, "acmecorp/infra/dev", nil)
        if err != nil {
            return err
        }

        // Retrieve resource group name from the first stack
        // using the stack reference above
        resourceGroupName := stackRef.GetOutput(pulumi.String("resourceGroupName"))

        ctx.Export("resourceGroupName", resourceGroupName)
		return nil
	})
}
using Pulumi;

return await Pulumi.Deployment.RunAsync(() =>
{

    var stackRef = new StackReference("acmecorp/infra/dev");

    // Retrieve resource group name from the first stack
    // using the stack reference above
    var resourceGroupName = stackRef.GetOutput("resourceGroupName");

    return new Dictionary<string, object?>
    {
        ["resourceGroupName"] = resourceGroupName
    };

});
name: my-second-app-dev
runtime: yaml
description: A program to create a Stack Reference

resources:
  stack-ref:
    type: pulumi:pulumi:StackReference
    properties:
      name: acmecorp/infra/dev

variables:
  resourceGroupName: ${stack-ref.outputs["resourceGroupName"]}

outputs:
  resourceGroupName: ${resourceGroupName}

To verify that your stack reference is working, run pulumi up.

$ pulumi up -y

Previewing update (dev):

     Type                      Name                     Plan
 +   pulumi:pulumi:Stack  my-second-app-dev             create

Outputs:
    resourceGroupName: output<string>

Resources:
    + 4 to create

Do you want to perform this update? yes
Updating (dev):

     Type                      Name                     Status
 +   pulumi:pulumi:Stack  my-second-app-dev             created (2s)

Outputs:
    resourceGroupName: "resource-group0e6ebba3"

Resources:
    + 1 created

Duration: 3s

You should see the name of your resource group from your first program successfully outputted in the update details of your second program.

Use stack reference in resource definition

In this section, you will use everything you have learned in this tutorial to define a resource that uses a stack reference in the resource definition. In your second program, you will be defining a Blob resource that will upload a file to the Blob container that was created in your first program. Use the following steps as a guide for adding the Blob resource:

  • Navigate to the Azure Native Registry documentation page
  • Search for the azure-native.storage.Blob resource
  • Define the Blob resource in your second program code
  • Export required property values in your first program code
  • Import required property values in your second program
  • Save and deploy your first program code
  • Then save and deploy your second program code

Once you have completed these steps, you can verify that the Blob was successfully created and uploaded to the container by navigating to Storage Accounts -> Your Storage Account -> Storage browser -> Blob containers -> blobcontainer in the Azure Portal.

View complete solution

You can view the code for the complete solution below.

First program code

"use strict";
const pulumi = require("@pulumi/pulumi");
const resources = require("@pulumi/azure-native/resources");
const storage = require("@pulumi/azure-native/storage");

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});

exports.resourceGroupName = resourceGroup.name;
exports.storageAccountName = storageAccount.name;
exports.blobContainerName = blobContainer.name;
import * as pulumi from "@pulumi/pulumi";
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";

const resourceGroup = new resources.ResourceGroup("resourceGroup");

const storageAccount = new storage.StorageAccount("sa", {
    resourceGroupName: resourceGroup.name,
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
});

const blobContainer = new storage.BlobContainer("blobContainer", {
    accountName: storageAccount.name,
    resourceGroupName: resourceGroup.name,
});

export const resourceGroupName = resourceGroup.name;
export const storageAccountName = storageAccount.name;
export const blobContainerName = blobContainer.name;
import pulumi
import pulumi_azure_native as azure_native

resource_group = azure_native.resources.ResourceGroup("resource-group")

storage_account = azure_native.storage.StorageAccount(
    "storageaccount",
    resource_group_name=resource_group.name,
    kind="StorageV2",
    sku={
        "name": "Standard_LRS",
    },
)

blob_container = azure_native.storage.BlobContainer("blobcontainer",
    account_name=storage_account.name,
    resource_group_name=resource_group.name
)


blob_resource = azure_native.storage.Blob("blobresource",
    account_name=storage_account_name,
    container_name=blob_container_name,
    resource_group_name=resource_group_name,
    access_tier=azure_native.storage.BlobAccessTier.HOT,
    source=pulumi.StringAsset("content"),
    type=azure_native.storage.BlobType.BLOCK
)

pulumi.export("resourceGroupName", resource_group.name)
pulumi.export("storageName", storage_account.name)
pulumi.export("containerName", blob_container.name)
package main

import (
	"github.com/pulumi/pulumi-azure-native-sdk/resources/v2"
	"github.com/pulumi/pulumi-azure-native-sdk/storage/v2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		resourceGroup, err := resources.NewResourceGroup(ctx, "resourceGroup", nil)
		if err != nil {
			return err
		}

		storageAccount, err := storage.NewStorageAccount(ctx, "sa", &storage.StorageAccountArgs{
			ResourceGroupName: resourceGroup.Name,
			Sku: &storage.SkuArgs{
				Name: pulumi.String("Standard_LRS"),
			},
			Kind: pulumi.String("StorageV2"),
		})
		if err != nil {
			return err
		}

		blobContainer, err := storage.NewBlobContainer(ctx, "blobContainer", &storage.BlobContainerArgs{
			AccountName:                 storageAccount.Name,
			ResourceGroupName:           resourceGroup.Name,
		})
		if err != nil {
			return err
		}

		ctx.Export("resourceGroupName", resourceGroup.Name)
		ctx.Export("storageAccountName", storageAccount.Name)
		ctx.Export("blobContainerName", blobContainer.Name)

		return nil
	})
}
using Pulumi;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using System.Collections.Generic;

return await Pulumi.Deployment.RunAsync(() =>
{
    var resourceGroup = new ResourceGroup("resourceGroup");

    var storageAccount = new StorageAccount("sa", new StorageAccountArgs
    {
        ResourceGroupName = resourceGroup.Name,
        Sku = new SkuArgs
        {
            Name = SkuName.Standard_LRS
        },
        Kind = Kind.StorageV2
    });

    var blobContainer = new BlobContainer("blobContainer", new()
    {
        AccountName = resourceGroup.Name,
        ResourceGroupName = storageAccount.Name,
    });

    return new Dictionary<string, object?>
    {
        ["resourceGroupName"] = resourceGroup.Name,
        ["storageAccountName"] = storageAccount.Name,
        ["blobContainerName"] = blobContainer.Name
    };
});
name: azure-native-storage-account-blob-yaml
description: An example that deploys a blob into a blob storage account on Azure.
runtime: yaml

resources:
  resourceGroup:
    type: azure-native:resources:ResourceGroup
  storageAccount:
    type: azure-native:storage:StorageAccount
    properties:
      resourceGroupName: ${resourceGroup.name}
      sku:
        name: Standard_LRS
      kind: StorageV2
  blobContainer:
    type: azure-native:storage:BlobContainer
    properties:
      accountName: ${storageAccount.name}
      resourceGroupName: ${resourceGroup.name}

outputs:
  resourceGroupName: ${resourceGroup.name}
  storageAccountName: ${storageAccount.name}
  blobContainerName: ${blobContainer.name}

Second program code

"use strict";
const pulumi = require("@pulumi/pulumi");

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");

const resourceGroupName = stackRef.getOutput("resourceGroupName");
const storageAccountName = stackRef.getOutput("storageAccountName");
const blobContainerName = stackRef.getOutput("blobContainerName");

const blobResource = new storage.Blob("blobResource", {
    accountName: storageAccountName,
    containerName: blobContainerName,
    resourceGroupName: resourceGroupName,
    accessTier: storage.BlobAccessTier.Hot,
    source: new pulumi.asset.StringAsset("content"),
    type: storage.BlobType.Block,
});
import * as pulumi from "@pulumi/pulumi";

const stackRef = new pulumi.StackReference("acmecorp/infra/dev");

const resourceGroupName2 = stackRef.getOutput("resourceGroupName");
const storageAccountName2 = stackRef.getOutput("storageAccountName");
const blobContainerName2 = stackRef.getOutput("blobContainerName");

const blobResource = new storage.Blob("blobResource", {
    accountName: storageAccountName2,
    containerName: blobContainerName2,
    resourceGroupName: resourceGroupName2,
    accessTier: storage.BlobAccessTier.Hot,
    source: new pulumi.asset.StringAsset("content"),
    type: storage.BlobType.Block,
});
import pulumi

stack_ref = pulumi.StackReference("acmecorp/infra/dev")

resource_group_name = stack_ref.get_output("resourceGroupName")
storage_account_name = stack_ref.get_output("storageAccountName")
blob_container_name = stack_ref.get_output("blobContainerName")

blob_resource = azure_native.storage.Blob("blobresource",
    account_name=storage_account_name,
    container_name=blob_container_name,
    resource_group_name=resource_group_name,
    access_tier=azure_native.storage.BlobAccessTier.HOT,
    source=pulumi.StringAsset("content"),
    type=azure_native.storage.BlobType.BLOCK
)
package main

import (
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
        stackRef, err := pulumi.NewStackReference(ctx, "acmecorp/infra/dev", nil)
        if err != nil {
            return err
        }

        resourceGroupName := stackRef.GetOutput(pulumi.String("resourceGroupName"))
        storageAccountName := stackRef.GetOutput(pulumi.String("storageAccountName"))
        blobContainerName := stackRef.GetOutput(pulumi.String("blobContainerName"))

		_, err = storage.NewBlob(ctx, "blobResource", &storage.BlobArgs{
			AccountName:       storageAccountName,
			ContainerName:     blobContainerName,
			ResourceGroupName: resourceGroupName,
			AccessTier:        storage.BlobAccessTierHot,
			Source: pulumi.NewStringAsset("content"),
			Type:   storage.BlobTypeBlock,
		})

		return nil
	})
}
using Pulumi;

return await Pulumi.Deployment.RunAsync(() =>
{

    var stackRef = new StackReference("acmecorp/infra/dev");

    var resourceGroupName = stackRef.GetOutput("resourceGroupName");
    var storageAccountName = stackRef.GetOutput("storageAccountName");
    var blobContainerName = stackRef.GetOutput("blobContainerName");

    var blobResource = new Blob("blobResource", new()
    {
        AccountName = storageAccountName,
        ContainerName = blobContainerName,
        ResourceGroupName = resourceGroupName,
        AccessTier = BlobAccessTier.Hot,
        Source = new StringAsset("content"),
        Type = BlobType.Block,
    });

});
name: infra
runtime: yaml
description: A program to create a Stack Reference

resources:
  stack-ref:
    type: pulumi:pulumi:StackReference
    properties:
      name: acmecorp/infra/dev

  blobResource:
    type: azure-native:storage:Blob
    properties:
      accessTier: Hot
      accountName: ${storageAccountName}
      containerName: ${blobContainerName}
      resourceGroupName: ${resourceGroupName}
      source:
        fn::StringAsset: content
      type: Block

variables:
  resourceGroupName: ${stack-ref.outputs["resourceGroupName"]}
  storageAccountName: ${stack-ref.outputs["storageAccountName"]}
  blobContainerName: ${stack-ref.outputs["blobContainerName"]}

Clean up

Before moving on, tear down the resources that are part of your stack to avoid incurring any charges.

  1. Run pulumi destroy to tear down all resources. You'll be prompted to make sure you really want to delete these resources. A destroy operation may take some time, since Pulumi waits for the resources to finish shutting down before it considers the destroy operation to be complete.
  2. To delete the stack itself, run pulumi stack rm. Note that this command deletes all deployment history from the Pulumi Service.

Next steps

In this tutorial, you created a Lambda function that writes a file to an S3 bucket. You also referenced the documentation to create an EventBridge Scheduler that would run the Lambda function on a scheduled basis.

You exported Lambda properties into stack outputs, and referenced those outputs across stacks using stack references.

To learn more about creating and managing resources in Pulumi, take a look at the following resources: