PulumiUP: Hear from technical leaders as they present the vision for the future of cloud engineering. Save Your Spot

Migrating to Pulumi from Terraform

Terraform uses a proprietary DSL called HCL to describe and provision infrastructure resources.

In Pulumi, you describe infrastructure using familiar languages and tools, providing productivity gains, better abstraction and reuse, and developer approachability — while still supporting robust infrastructure as code provisioning across many clouds.

Need help converting?

Benefits of Pulumi

Modern Programming Languages

With Pulumi, you get all of the benefits of a modern programming language for provisioning cloud infrastructure: code completion, error checking, versioning, IDE support, and general productivity gains — without the need to manage YAML and DSL syntax.

Familiar Constructs

Real languages means you get familiar constructs like for loops, functions, and classes - cutting boilerplate and enforcing best practices. Pulumi lets you leverage existing package management tools and techniques.

Ephemeral Infrastructure

Pulumi has deep support for cloud native technologies, like Kubernetes, and supports advanced deployment scenarios that cannot be expressed with Terraform. Pulumi is a proud member of the Cloud Native Computing Foundation (CNCF).

TF Provider Integration

Pulumi is able to adapt any Terraform Provider for use with Pulumi, enabling management of any infrastructure supported by the Terraform Providers ecosystem using Pulumi programs. Find out more here.

Take advantage of real coding features with Pulumi

Pulumi provides a more expressive and efficient way to define cloud resources:

  • Use variable loops, not copy/paste
  • Use any Node libaries (or Python/Go)
  • On-the-fly error checking
  • Freeform code instead of complex interpolations

Find many other examples here.

import * as aws from "@pulumi/aws";
import { readdirSync } from "fs";
import { join as pathjoin } from "path";

const bucket = new aws.s3.Bucket("mybucket");

const folder = "./files";
let files = readdirSync(folder);
for (let file of files) {
    const object = new aws.s3.BucketObject(file, {
        bucket: bucket,
        source: new pulumi.FileAsset(pathjoin(folder, file))

export const bucketname = bucket.id;
resource "aws_s3_bucket" "mybucket" {
    bucket_prefix = "mybucket"

resource "aws_s3_bucket_object" "data_txt" {
    key        = "data.txt"
    bucket     = "${aws_s3_bucket.mybucket.id}"
    source     = "./files/data.txt"

resource "aws_s3_bucket_object" "index_html" {
    key        = "index.html"
    bucket     = "${aws_s3_bucket.mybucket.id}"
    source     = "./files/index.html"

resource "aws_s3_bucket_object" "index_js" {
    key        = "index.js"
    bucket     = "${aws_s3_bucket.mybucket.id}"
    source     = "./files/index.js"

resource "aws_s3_bucket_object" "main.css" {
    key        = "main.css"
    bucket     = "${aws_s3_bucket.mybucket.id}"
    source     = "./files/main.css"

resource "aws_s3_bucket_object" "favicon.ico" {
    key        = "favicon.ico"
    bucket     = "${aws_s3_bucket.mybucket.id}"
    source     = "./files/favicon.ico"

Productive cloud native programming

Pulumi is designed with cloud native computing in mind - from containers to serverless, providing a productive model for quickly building and deploying apps:

  • Rich, built in support for event handlers
  • Easy-to-use in-line Lambdas for simple functions
  • Use JavaScript for both infrastructure and Lambda callbacks
  • Avoid the need for significant boiler plate code

Find many other examples here.

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

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

// Register a Lambda to handle Bucket Notification
bucket.onObjectCreated("newObj", async (ev, ctx) => {
    // Write code inline, or use a Zip

// Export the bucket name for easy scripting
export const bucketName = bucket.id;
resource "aws_s3_bucket" "mybucket" {
    bucket_prefix = "mybucket"

data "archive_file" "lambda_zip" {
    type        = "zip"
    output_path = "lambda.zip"

    source {
    filename = "index.js"
    content = < {

data "aws_iam_policy_document" "lambda-assume-role-policy" {
    statement {
        actions = ["sts:AssumeRole"]

        principals {
            type        = "Service"
            identifiers = ["lambda.amazonaws.com"]

resource "aws_iam_role" "lambda" {
    assume_role_policy = "${data.aws_iam_policy_document.lambda-assume-role-policy.json}"

resource "aws_lambda_function" "my_lambda" {
    filename = "${data.archive_file.lambda_zip.output_path}"
    source_code_hash = "${data.archive_file.lambda_zip.output_base64sha256}"
    function_name = "my_lambda"
    role = "${aws_iam_role.lambda.arn}"
    handler = "index.handler"
    runtime = "nodejs8.10"

resource "aws_lambda_permission" "allow_bucket" {
    statement_id  = "AllowExecutionFromS3Bucket"
    action        = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.my_lambda.arn}"
    principal     = "s3.amazonaws.com"
    source_arn    = "${aws_s3_bucket.mybucket.arn}"

resource "aws_s3_bucket_notification" "bucket_notification" {
    bucket = "${aws_s3_bucket.mybucket.id}"

    lambda_function {
        lambda_function_arn = "${aws_lambda_function.my_lambda.arn}"
        events              = ["s3:ObjectCreated:*"]

output "bucket_name" {
    value = "${aws_s3_bucket.mybucket.id}"

How Pulumi Works


  • Code in modern languages
  • Share and reuse patterns
  • Use your favorite IDE and tools


  • Preview changes
  • Run pulumi up to deploy
  • Integrate with CI/CD


  • Audit all changes
  • Manage complex environments
  • Implement policies and controls

Get Started with Pulumi

Use Pulumi's open source SDK to create, deploy, and manage infrastructure on any cloud.

Google Cloud

See how top engineering teams enable developers and operators to work better together with Pulumi.

Pulumi has given our team the tools and framework to achieve a unified development and DevOps model, boosting productivity and taking our business to any cloud environment that our customers need. We retired 25,000 lines of complex code that few team members understood and replaced it with 100s of lines in a familiar programming language.

Kim Hamilton
CTO, Learning Machine

Need assistance?

More from Pulumi

Migrate to Pulumi

In this video, Pulumi CTO, Luke Hoban, discusses how to begin to migrate to Pulumi from existing tools such as CloudFormation and Terraform.

Learn more
Video thumbnail diagram

Serverless, Containers, and Infrastructure

In this blog post, we show how productive Pulumi can be at combining different aspects of cloud architecture for truly cloud native programming.

Learn more