Pulumi: The Real Infrastructure as Code

8grams
9 min readJun 23, 2024

--

Introduction

Infrastructure as Code (IaC) has revolutionized the way we manage and provision infrastructure. IaC allows developers and operations teams to define and manage infrastructure using code, which can be version-controlled and treated like application code. This approach brings numerous benefits, including improved consistency, repeatability, and collaboration. Over the years, several IaC tools have emerged, each with its own strengths and weaknesses. Among these, Pulumi has gained significant attention for its unique approach and capabilities.

History of Pulumi

Pulumi was founded in 2017 by Joe Duffy and Eric Rudder, two veterans of the tech industry with a shared vision for modernizing infrastructure management. Joe Duffy, a former Microsoft executive, had extensive experience in building developer tools and platforms, while Eric Rudder brought his deep knowledge of software engineering and product development. Together, they envisioned a new kind of IaC tool that would bridge the gap between developers and operations teams, enabling them to work more efficiently and effectively.

Since its inception, Pulumi has evolved rapidly, with several key milestones marking its growth. The initial releases focused on establishing a solid foundation, with support for major cloud providers like AWS, Azure, and Google Cloud. Over time, Pulumi expanded its capabilities to include Kubernetes, serverless computing, and multi-cloud deployments. Key partnerships and an active community have further propelled Pulumi’s development, making it a robust and versatile IaC tool.

Purpose and Creation of Pulumi

The motivation behind Pulumi’s creation stemmed from the limitations and challenges associated with existing IaC tools. Traditional IaC tools often relied on domain-specific languages (DSLs) or templating systems, which could be restrictive and cumbersome. Pulumi aimed to overcome these challenges by enabling the use of familiar programming languages for defining and managing infrastructure. This approach not only makes IaC more accessible to developers but also enhances flexibility and expressiveness.

Pulumi’s primary goal is to bridge the gap between developers and operations teams. By allowing infrastructure to be defined using general-purpose programming languages such as JavaScript, TypeScript, Python, Go, and .NET, Pulumi empowers developers to leverage their existing skills and tools. This integration fosters better collaboration and accelerates the development and deployment process, ultimately leading to more efficient and effective infrastructure management.

Key Concept

Pulumi operates by allowing users to write code that describes the desired state of their infrastructure. This code is then executed by Pulumi to create, update, or delete resources in the target environment. The core components of Pulumi’s architecture include:

Pulumi CLI
The Pulumi Command-Line Interface (CLI) is the primary tool used to interact with Pulumi. It allows users to perform actions such as initializing projects, previewing infrastructure changes, deploying resources, and managing state. Key commands include pulumi new, pulumi up, pulumi preview, and pulumi destroy.

Pulumi SDK
The Pulumi Software Development Kit (SDK) is a collection of libraries that enable developers to define and manage infrastructure using programming languages like JavaScript, TypeScript, Python, Go, and .NET. The SDK provides abstractions over cloud provider APIs, simplifying the process of resource management.

Pulumi Service
The Pulumi Service is a managed backend that handles state management and collaboration. It stores the state of infrastructure deployments, enabling features such as concurrent updates, audit logging, and access control. The service provides a centralized and secure place to manage infrastructure state.

State
State in Pulumi refers to the current configuration and status of the infrastructure resources managed by Pulumi. The state file keeps track of the resources that have been created, updated, or deleted. This state can be stored locally or in the Pulumi Service, which ensures consistency and allows for rollback capabilities.

Stack
A stack in Pulumi is an isolated instance of a Pulumi program, which represents a specific configuration of infrastructure for a particular environment (e.g., development, staging, production). Each stack has its own state and can be managed independently, allowing for different configurations and deployments for each environment.

Project
A project in Pulumi is a collection of infrastructure code that defines a set of resources and their configuration. A project can have multiple stacks, each representing different environments or configurations. The project structure typically includes configuration files, code files, and metadata.

Resource
A resource in Pulumi represents a piece of infrastructure, such as an AWS S3 bucket, an Azure virtual machine, or a Kubernetes pod. Resources are defined in code and managed by Pulumi. Each resource has properties and configurations that define its behavior and characteristics.

Provider
A provider in Pulumi is a plugin or library that allows Pulumi to interact with a specific cloud service or platform. Providers translate the infrastructure code into API calls to the underlying cloud service. Examples include the AWS, Azure, Google Cloud, and Kubernetes providers.

Component Resource
A component resource in Pulumi is a higher-level abstraction that groups multiple resources into a single reusable unit. Component resources help organize and encapsulate related infrastructure elements, making the code more modular and reusable. For example, a component resource might encapsulate all resources needed for a web application, such as a load balancer, database, and compute instances.

Configuration
Configuration in Pulumi refers to the settings and parameters that control the behavior of a project and its resources. Configurations can be defined in configuration files or passed as command-line arguments. They allow for customization and variation across different stacks and environments.

Policy as Code
Policy as Code in Pulumi allows organizations to define and enforce infrastructure policies programmatically. These policies can include security rules, compliance requirements, and best practices. Policy as Code helps ensure that infrastructure deployments adhere to organizational standards and reduces the risk of misconfigurations.

Key Features of Pulumi

Pulumi offers a rich set of features that make it stand out in the IaC landscape. One of its most notable features is multi-cloud support. Pulumi can manage infrastructure across major cloud providers such as AWS, Azure, Google Cloud, and Kubernetes, enabling organizations to adopt a multi-cloud strategy with ease. This capability is particularly valuable in today’s cloud-native world, where flexibility and agility are paramount.

Another key feature of Pulumi is code reusability and modularity. Pulumi allows developers to create reusable components and stacks, which can be shared and reused across projects. This modular approach promotes best practices, reduces duplication, and accelerates development. For example, a team can create a standardized VPC component and reuse it in multiple projects, ensuring consistency and reducing setup time.

Integration with CI/CD pipelines is another area where Pulumi excels. Pulumi can be easily integrated into existing CI/CD workflows, allowing infrastructure changes to be automatically tested, validated, and deployed. This integration streamlines the deployment process, reduces manual intervention, and enhances overall reliability.

State management is a critical aspect of any IaC tool, and Pulumi’s approach to state management offers several advantages. By storing state in the Pulumi Service, Pulumi eliminates the need for managing state files, reducing complexity and improving security. The centralized state management also facilitates collaboration, as multiple team members can work on the same project without conflicts.

Pulumi also supports testing and policy as code, enabling teams to implement robust testing and governance practices. Developers can write unit tests for their infrastructure code, ensuring that changes are tested and validated before deployment. Additionally, Pulumi’s policy as code framework allows organizations to enforce compliance and security policies programmatically, reducing the risk of misconfigurations and ensuring adherence to best practices.

Comparison with Terraform

When comparing Pulumi with Terraform, several key differences and similarities emerge. One of the most significant differences is the language and syntax used for defining infrastructure. Terraform uses HashiCorp Configuration Language (HCL), a domain-specific language designed specifically for IaC. In contrast, Pulumi allows the use of general-purpose programming languages, providing greater flexibility and expressiveness.

State management is another area where Pulumi and Terraform differ. Terraform relies on state files, which can be stored locally or remotely. Managing these state files can sometimes be challenging, especially in collaborative environments. Pulumi’s centralized state management in the Pulumi Service simplifies this process, providing a more reliable and secure solution.

The ecosystem and community support for both tools are robust, but they cater to different needs and preferences. Terraform has a large and mature ecosystem, with a vast repository of modules and community contributions. Pulumi, on the other hand, leverages existing programming language ecosystems, allowing developers to use familiar tools and libraries.

Multi-cloud capabilities are strong in both Pulumi and Terraform. Both tools support major cloud providers and allow for multi-cloud deployments. However, Pulumi’s ability to use general-purpose languages can make it easier to implement complex logic and workflows, providing an edge in certain scenarios.

Extensibility and flexibility are strengths of both tools, but they approach it differently. Terraform’s plugin system allows for extending its capabilities, while Pulumi’s use of general-purpose languages enables developers to leverage a wide range of libraries and frameworks. This flexibility can be a deciding factor for teams with specific requirements or complex workflows.

Comparison with Other IaC Tools

The comparison table below outlines the differences and similarities between Pulumi, Terraform, AWS CloudFormation, and Google Cloud Deployment Manager. Pulumi stands out by using general-purpose programming languages such as JavaScript and Python, making it highly flexible for developers. Terraform uses its own HashiCorp Configuration Language (HCL), while AWS CloudFormation and Google Cloud Deployment Manager rely on JSON/YAML and YAML/Python respectively.

Get Started with Pulumi

Getting started with Pulumi involves a few key steps: setting up the environment, initializing a new project, writing infrastructure code, and deploying the infrastructure.

Setting Up the Environment

First, install the Pulumi CLI. You can download the CLI from the official Pulumi website or install it using a package manager. For example, on macOS, you can use Homebrew:

~$ brew install pulumi

Next, install the appropriate Pulumi SDK for your preferred programming language. For example, if you are using Python and want to work with AWS’s resources, you can install the Pulumi SDK using pip:

~$ pip install pulumi
~$ pip install pulumi-aws

Initializing a New Project

Once the Pulumi CLI and SDK are installed, you can initialize a new Pulumi project. Navigate to your project directory and run:

~$ pulumi new [template]

Replace [template] with the template corresponding to your preferred language and cloud provider. For example, to create a new TypeScript project for AWS, use:

~$ pulumi new aws-typescript

This command will create a new Pulumi project with a basic structure and configuration files.

Writing Infrastructure Code

With your project initialized, you can start writing code to define your infrastructure. Open the main file (e.g., index.ts for TypeScript) and add code to create resources. Here is an example of creating an S3 bucket in AWS using TypeScript:

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

// Create an AWS S3 bucket
const bucket = new aws.s3.Bucket("my-bucket", {
website: {
indexDocument: "index.html",
},
});

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

This code snippet imports the necessary Pulumi and AWS libraries, defines an S3 bucket resource, and exports the bucket’s name.

Deploying the Infrastructure

After writing your infrastructure code, you can deploy it using the Pulumi CLI. Run the following command to preview the changes:

~$ pulumi preview

If the preview looks correct, proceed with the deployment:

~$ pulumi up

Pulumi will execute the code, create the defined resources, and manage the state. The CLI will provide output with the details of the deployed resources.

And that’s a wrap! In the next article, we will create a complete infrastructure on GCP (including GKE + CloudSQL) using Pulumi. Stay tune!

--

--

8grams

We are a DevOps Consulting Firm with a mission to empower businesses with modern DevOps practices and technologies