1. Tutorials
  2. Inspecting Infrastructure

Inspecting Infrastructure

Pulumi configurations and state data include highly structured information about the resources they manage, such as dependency information, outputs, and more. The Pulumi CLI includes commands for inspecting this data. You can use these to integrate other tools with Pulumi’s infrastructure data, or just to gain a deeper or more holistic understanding of your infrastructure.

In this tutorial, we’ll demonstrate the various ways you can use the Pulumi CLI to inspect your infrastructure.

In this tutorial, you'll learn:

  • How to view your stack's status, outputs, and configurations
  • How to view the state file of your stack
  • How to view the dependency graph of your stack's resources
  • How to preview a dry-run of your stacks updates
  • How to view your stack's details in the Pulumi Cloud

[Optional] Create a new project

The commands found in this tutorial can be run against any projects or stacks that you may have already created. Feel free to skip this step and use your own project/stack if that is the case.

To start, login to the Pulumi CLI and ensure it is configured to use your AWS account. Next, create a new project and replace the default program code with the following:

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

// Create an S3 bucket
const s3Bucket = new aws.s3.Bucket("myBucket");

// IAM Policy Document that allows the Lambda service to write to the S3 bucket
const s3BucketPolicyDocument = s3Bucket.arn.apply(arn =>
    JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Effect: "Allow",
                Principal: { Service: "lambda.amazonaws.com" },
                Action: ["s3:PutObject", "s3:PutObjectAcl"],
                Resource: `${arn}/*`,
            },
        ],
    }),
);

// Attach the policy to the bucket
const s3BucketPolicy = new aws.s3.BucketPolicy("myBucketPolicy", {
    bucket: s3Bucket.id,
    policy: s3BucketPolicyDocument,
});

// Export the names and ARNs of the created resources
exports.bucketName = s3Bucket.id;
exports.bucketArn = s3Bucket.arn;
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Create an S3 bucket
const s3Bucket = new aws.s3.Bucket("myBucket");

// IAM Policy Document that allows the Lambda service to write to the S3 bucket
const s3BucketPolicyDocument = s3Bucket.arn.apply(arn =>
    JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Effect: "Allow",
                Principal: { Service: "lambda.amazonaws.com" },
                Action: ["s3:PutObject", "s3:PutObjectAcl"],
                Resource: `${arn}/*`,
            },
        ],
    }),
);

// Attach the policy to the bucket
const s3BucketPolicy = new aws.s3.BucketPolicy("myBucketPolicy", {
    bucket: s3Bucket.id,
    policy: s3BucketPolicyDocument,
});

// Export the names and ARNs of the created resources
export const bucketName = s3Bucket.id;
export const bucketArn = s3Bucket.arn;
import pulumi
import pulumi_aws as aws
import json

# Create an S3 bucket
s3_bucket = aws.s3.Bucket("myBucket")

# IAM Policy Document that allows the Lambda service to write to the S3 bucket
s3_bucket_policy_document = s3_bucket.arn.apply(
    lambda arn: json.dumps(
        {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {"Service": "lambda.amazonaws.com"},
                    "Action": ["s3:PutObject", "s3:PutObjectAcl"],
                    "Resource": f"{arn}/*",
                }
            ],
        }
    )
)

# Attach the policy to the bucket
s3_bucket_policy = aws.s3.BucketPolicy(
    "myBucketPolicy",
    bucket=s3_bucket.id,
    policy=s3_bucket_policy_document,
)

# Export the names and ARNs of the created resources
pulumi.export("bucket_name", s3_bucket.id)
pulumi.export("bucket_arn", s3_bucket.arn)
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v4/go/aws/s3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		// Create an S3 bucket
		s3Bucket, err := s3.NewBucket(ctx, "myBucket", nil)
		if err != nil {
			return err
		}

		// IAM Policy Document that allows the Lambda service to write to the S3 bucket
		s3Bucket.Arn.ApplyT(func(arn string) (string, error) {
			policy := fmt.Sprintf(`{
				"Version": "2012-10-17",
				"Statement": [{
					"Effect": "Allow",
					"Principal": {"Service": "lambda.amazonaws.com"},
					"Action": ["s3:PutObject", "s3:PutObjectAcl"],
					"Resource": "%s/*"
				}]
			}`, arn)

			// Attach the policy to the bucket
			_, err := s3.NewBucketPolicy(ctx, "myBucketPolicy", &s3.BucketPolicyArgs{
				Bucket: s3Bucket.ID(),
				Policy: pulumi.String(policy),
			})
			if err != nil {
				return "", err
			}

			return "", nil
		})

		// Export the names and ARNs of the created resources
		ctx.Export("bucketName", s3Bucket.ID())
		ctx.Export("bucketArn", s3Bucket.Arn)

		return nil
	})
}
using Pulumi;
using Pulumi.Aws.Iam;
using Pulumi.Aws.S3;
using System.Collections.Generic;
using System.Text.Json;

return await Deployment.RunAsync(() =>
{
    var bucket = new Bucket("myBucket");

    var s3BucketPolicyDocument = bucket.Arn.Apply(arn => JsonSerializer.Serialize(new
    {
        Version = "2012-10-17",
        Statement = new[]
        {
            new
            {
                Effect = "Allow",
                Principal = new { Service = "lambda.amazonaws.com" },
                Action = new[] { "s3:PutObject", "s3:PutObjectAcl" },
                Resource = $"{arn}/*"
            }
        }
    }));

    var bucketPolicy = new BucketPolicy("myBucketPolicy", new BucketPolicyArgs
    {
        Bucket = bucket.Id,
        Policy = s3BucketPolicyDocument
    });

    return new Dictionary<string, object?>
    {
        ["bucketName"] = bucket.Id,
        ["bucketArn"] = bucket.Arn
    };
});
package myproject;

import com.pulumi.Pulumi;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketPolicy;
import com.pulumi.aws.s3.BucketPolicyArgs;
import static com.pulumi.codegen.internal.Serialization.*;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var bucket = new Bucket("myBucket");

            var policyDocument = bucket.arn().applyValue(arn -> serializeJson(
                jsonObject(
                    jsonProperty("Version", "2012-10-17"),
                    jsonProperty("Statement", jsonArray(jsonObject(
                        jsonProperty("Effect", "Allow"),
                        jsonProperty("Action", jsonArray("s3:PutObject", "s3:PutObjectAcl")),
                        jsonProperty("Principal", jsonObject(
                            jsonProperty("Service", "lambda.amazonaws.com")
                        )),
                        jsonProperty("Resource", arn + "/*")
                    )))
                )
            ));

            var bucketPolicy = new BucketPolicy("myBucketPolicy", BucketPolicyArgs.builder()
                .bucket(bucket.id())
                .policy(policyDocument)
                .build());

            ctx.export("bucketName", bucket.id());
            ctx.export("bucketArn", bucket.arn());
        });
    }
}
name: aws-s3bucket-bucketpolicy-yaml
runtime: yaml
description: An example that deploys an S3 bucket and bucket policy on AWS.

resources:
  myBucket:
    type: aws:s3/bucket:Bucket

  myBucketPolicy:
    type: aws:s3/bucketPolicy:BucketPolicy
    properties:
      bucket: ${myBucket.id}
      policy:
        fn::toJSON:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Service: "lambda.amazonaws.com"
              Action:
                - "s3:PutObject"
                - "s3:PutObjectAcl"
              Resource: "${myBucket.arn}/*"

outputs:
  bucket_name: ${myBucket.id}
  bucket_arn: ${myBucket.arn}

This code example creates the following resources:

  • An S3 bucket
  • An S3 bucket policy definition
  • An S3 bucket policy attachment

It also includes two exports that will output the name and ARN of the S3 bucket.

Now run the pulumi up command to deploy your resources before moving onto the next steps.

Inspect your infrastructure

In this section, you will run a number of commands in the Pulumi CLI that will enable you to view more details about the resources you have deployed.

pulumi stack

The pulumi stack command is used to provide a quick overview of the current stack’s status and configuration. Running this command will list the management details, resources, and output names and values of the current stack.

Run the pulumi stack command as shown below:

pulumi stack graph

The pulumi stack graph command is used to visualize the dependency graph of a Pulumi stack. This graphical representation can help users to understand the relationships and dependencies between resources in their infrastructure.

Run the pulumi stack graph <filename> command as shown below, making sure to replace <filename> with the name of the file that you want the graph to be exported to:

The output of the file will be in Graphviz DOT format. You can use an online viewer such as GraphvizOnline to view a visual representation of the graph.

pulumi stack output

The pulumi stack output command is used to list all output names and values that are exported from a stack. This command helps to facilitate automation workflows and integration with other tools and scripts by providing easy access to important output values.

Run the pulumi stack output command as shown below:

You can return the value of just a single output by adding the name of the desired output property to the command. To demonstrate, run the pulumi stack output <outputname> command, replacing <outputname> with one of the output names of your stack.

pulumi stack export

The pulumi stack export command is used to export the current state of a stack in JSON format to standard out. This state definition contains all the information about the resources, their states, and the configuration of the stack. The exported state can be used for things like backup, migration, or debugging purposes.

Run the pulumi stack export command as shown below:

pulumi preview

The pulumi preview command is an important tool for understanding the changes that will be made to your infrastructure before actually applying them. It does a dry run of the update, showing a detailed preview of the resources that will be created, updated, or deleted without making any actual changes to your cloud resources.

Before running this command, you will need to make a change to your Pulumi program. Change the name of your S3 bucket resource and then save your file.

Now run the pulumi preview command to display a preview of the updates that will be made:

pulumi console

The pulumi console command opens the current stack in the Pulumi Console, providing a graphical user interface to view and manage your Pulumi stack and resources. From there, you can view detailed information about the stack such as its resources, outputs, and configuration values.

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 used a variety of Pulumi CLI commands to view more details about your infrastructure. To learn more about creating and managing resources in Pulumi, take a look at the following resources: