Skip to main content

Pulumi Ep 1: Introduction to Pulumi and Project Initialization

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
pulumi - This article is part of a series.
Part 1: This Article
Unlike Terraform, which relies on a single binary to parse HCL, Pulumi requires a dual-runtime environment: the Pulumi CLI engine, and the language host (Node.js for TypeScript). Let’s initialize our first project and explore how these two systems interact.

1. Prerequisites and Installation
#

To write Pulumi code in TypeScript, your machine must be capable of executing JavaScript.

  1. Install Node.js: Ensure you have Node.js v18 or newer installed.
    node --version
    npm --version
  2. Install Pulumi CLI: The CLI is the core engine that orchestrates the deployments.
    # macOS
    brew install pulumi/tap/pulumi
    
    # Linux
    curl -fsSL https://get.pulumi.com | sh
  3. Verify Pulumi:
    pulumi version

Cloud Credentials (AWS)
#

Pulumi does not have its own magical back-door into AWS. It uses the exact same standard AWS CLI credentials that Terraform or the Python boto3 SDK uses.

Ensure you have configured your local environment:

aws configure
# Or export the variables directly
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="secret..."
export AWS_REGION="us-east-1"

2. Initializing a New Project
#

The pulumi new command is a scaffolding tool. It generates the necessary directory structure, configuration files, and package.json dependencies for your chosen language and cloud provider.

Let’s create a new directory for our first infrastructure project:

mkdir pulumi-first-project
cd pulumi-first-project

Initialize a new AWS TypeScript project:

pulumi new aws-typescript

The Interactive Prompt
#

The CLI will prompt you for several details:

  1. Project Name: The global name of your application (e.g., pulumi-first-project). Press Enter to accept the default.
  2. Project Description: A brief description. Press Enter.
  3. Stack Name: By default, it will suggest dev. A Stack is an isolated instance of your project (like an environment). Press Enter.
  4. AWS Region: The region where resources will be deployed (e.g., us-east-1).

Once you complete the prompt, Pulumi will automatically run npm install to download the @pulumi/pulumi core SDK and the @pulumi/aws provider SDK.


3. Anatomy of a Pulumi Project
#

Open the directory in your code editor. You will see several generated files. Understanding their purpose is critical.

Pulumi.yaml (The Project Manifest)
#

This file defines the project itself. It tells the Pulumi CLI which language runtime to boot up when you run pulumi up.

name: pulumi-first-project
runtime: nodejs
description: A minimal AWS TypeScript Pulumi program

Pulumi.dev.yaml (The Stack Configuration)
#

This file stores the configuration specifically for the dev stack we created. If you create a prod stack later, Pulumi will generate a Pulumi.prod.yaml file.

config:
  aws:region: us-east-1

package.json and tsconfig.json
#

These are standard Node.js and TypeScript configuration files. Notice the dependencies:

"dependencies": {
    "@pulumi/aws": "^6.0.0",
    "@pulumi/pulumi": "^3.0.0"
}

index.ts (The Entrypoint)
#

This is where you write your actual infrastructure code. Open index.ts; you will see Pulumi has generated a default S3 bucket for you.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Create an AWS resource (S3 Bucket)
const bucket = new aws.s3.Bucket("my-bucket");

// Export the name of the bucket
export const bucketName = bucket.id;

Notice the sheer simplicity. There are no proprietary meta-arguments. It is just a standard TypeScript const instantiation of a class (aws.s3.Bucket).


4. Execution: The pulumi up Command
#

Let’s deploy this code. The equivalent of terraform plan + terraform apply in the Pulumi ecosystem is a single command: pulumi up.

pulumi up

The Plan Phase
#

Pulumi will compile your TypeScript down to JavaScript, boot up the Node.js runtime, and execute index.ts. It compares the resources declared in your code against the remote state, and prints a preview:

Previewing update (dev)

View in Browser (Ctrl+O): https://app.pulumi.com/rhidayat/pulumi-first-project/dev/previews/1a2b3c

     Type                 Name                      Plan       
 +   pulumi:pulumi:Stack  pulumi-first-project-dev  create     
 +   └─ aws:s3:Bucket     my-bucket                 create     

Resources:
    + 2 to create

Do you want to perform this update?
  yes
> no
  details

Notice how you can use the arrow keys to interactively select yes, no, or details. Select details to see the exact API payload Pulumi is about to send to AWS.

Select yes to deploy the bucket.

The Apply Phase
#

Updating (dev)

     Type                 Name                      Status      
 +   pulumi:pulumi:Stack  pulumi-first-project-dev  created     
 +   └─ aws:s3:Bucket     my-bucket                 created     

Outputs:
    bucketName: "my-bucket-1a2b3c4"

Resources:
    + 2 created

Duration: 14s

Congratulations! You have successfully deployed AWS infrastructure using TypeScript. Notice how Pulumi automatically appended a random suffix (-1a2b3c4) to the bucket name. This is a built-in feature called Auto-Naming, designed to prevent collision errors (which we will explore in a later episode).


Troubleshooting & Common Errors
#

  1. error: no credentials found

    • Root Cause: Pulumi cannot authenticate with AWS.
    • Solution: Verify your ~/.aws/credentials file is populated, or that you have AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY exported in your current terminal session.
  2. npm ERR! code ENOENT during pulumi new

    • Root Cause: Node.js or npm is not installed on your system, so Pulumi failed to download the required TypeScript SDKs.
    • Solution: Install Node.js. If you are using NVM (Node Version Manager), ensure you have run nvm use <version> in your current terminal.
  3. TS2304: Cannot find name 'aws'

    • Root Cause: Your IDE (like VS Code) is throwing a red squiggly line because it hasn’t indexed the node_modules directory yet.
    • Solution: Run npm install manually in the directory, and restart your IDE’s TypeScript server.

Conclusion & Next Steps
#

You have successfully initialized a project, understood the dual-runtime architecture, and deployed your first resource.

But where did Pulumi save the state file? In Terraform, you had a local terraform.tfstate file. In Pulumi, you won’t find one in your directory.

In Episode 2: Stacks and State Management, we will explore the Pulumi Service, understand how it handles state automatically, and learn how to manage multiple environments (like Dev and Prod) using Stacks.

pulumi - This article is part of a series.
Part 1: This Article