1. Prerequisites and Installation#
To write Pulumi code in TypeScript, your machine must be capable of executing JavaScript.
- Install Node.js: Ensure you have Node.js v18 or newer installed.
node --version npm --version - 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 - 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-projectInitialize a new AWS TypeScript project:
pulumi new aws-typescriptThe Interactive Prompt#
The CLI will prompt you for several details:
- Project Name: The global name of your application (e.g.,
pulumi-first-project). Press Enter to accept the default. - Project Description: A brief description. Press Enter.
- Stack Name: By default, it will suggest
dev. A Stack is an isolated instance of your project (like an environment). Press Enter. - 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 programPulumi.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-1package.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 upThe 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
detailsNotice 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: 14sCongratulations! 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#
error: no credentials found- Root Cause: Pulumi cannot authenticate with AWS.
- Solution: Verify your
~/.aws/credentialsfile is populated, or that you haveAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYexported in your current terminal session.
npm ERR! code ENOENTduringpulumi 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.
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_modulesdirectory yet. - Solution: Run
npm installmanually in the directory, and restart your IDE’s TypeScript server.
- Root Cause: Your IDE (like VS Code) is throwing a red squiggly line because it hasn’t indexed the
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.

