Define cloud apps and infrastructure in your favorite language and deploy to any cloud with Pulumi.

Pulumi logoIf you search the Internet for Infrastructure-as-Code (IaC), it’s pretty easy to come up with a list of the most popular tools: Chef, Ansible, Puppet, Terraform…and the freshman to the IaC:  PULUMI.

It’s 4 a.m. and the production server has gone down. You can’t keep calm?

Sure, how tough is it? Except that you’ll probably need to recall what you did a year ago to set up your environment, then desperately try to figure out what you’ve installed or implemented or configured since. Finally, you’ve gathered all your findings to closely replicate the environment.

Wouldn’t it be nice to have something that manages all this configuration for you? No, there aren’t robots coming to take over the DevOps team yet. I’m talking about using Infrastructure-as-Code to automatically and consistently manage infrastructure configuration.

What is Infrastructure as Code (IaC)?

As the name suggests, Infrastructure-as-Code is the concept of managing your operations environment in the same way you manage applications or other code.

Infrastructure as code simply means to convert your infrastructure into code, where it is managed by some kind of version control system (e.g., Git), and stored in a repository where you can manage it similar to your application.

Pulumi: the new IaC tool

While learning Azure, I tried implementing IaC with Azure Resource Manager Templates (aka ARM Templates). For this, I learned Powershell and wrote several templates using it. As a developer, PowerShell isn’t the language I use on a daily basis to write my code, but I use Javascript abundantly for many of my projects.

Then the internet community whispered about Pulumi.

I’ve tried my hand at Pulumi and the experience has been very enlightening, so I’m sharing some of the more important and interesting findings with you all.

Pulumi is a multi-language and multi-cloud development platform.

Pulumi supports all major clouds — including Amazon Web Services (AWS), Azure and Google Cloud, as well as Kubernetes clusters. It lets you create all aspects of cloud programs using real languages (Pulumi currently supports JavaScript, TypeScript, and Python, with more languages supported in the future) and real code, from infrastructure on up to the application itself. Just write programs and run them, and Pulumi figures out the rest.

Using real languages unlocks tremendous benefits:

  • Familiarity: no need to learn new bespoke DSLs or YAML-based templating languages.
  • Abstraction: build bigger things out of smaller things.
  • Sharing and reuse: we leverage existing language package managers to share and reuse these abstractions, either with the community, within your team, or both.
  • Full control: use the full power of your language, including async, loops, and conditionals.

My favorite things about Pulumi

  1. Multi-Language and real language: Using general-purpose programming languages reduces the learning curve and makes it easier to express your configuration requirements.
  2. Developer friendly and easily configurable: Pulumi bridges the gap between Development and Operations teams by not treating application code and infrastructure as separate things. Developers can easily list out dependencies in the package.json file. The below snippet explains:
{
   "name": "azure-javascript",  // Name of the Pulumi project
   "main": "index.js",          // start point of the Pulumi program.
   "dependencies": {            // Dependencies with version number to be
       "@pulumi/pulumi": "latest",   installed with NPM
       "@pulumi/azure": "latest",
       "azure-storage": "latest",
       "mime": "^2.4.0"
   }
}

The YAML is created while we initialize the Pulumi Stack to configure all the parameters required for the program like credentials, location, etc.

  1. Reusable Components: Thanks to having a real language, we can build higher-level abstractions.

Below is one of my example code snippets using a Pulumi component that creates an instance of the Azure Resource Group to be used in other programs. You can find the full source code that provisions Azure Load Balancer GitHub Code.

class ResourceGroup extends pulumi.ComponentResource {
    constructor(resourceGroupName, location,path, opts)
    {
    	 super("az-pulumi-createstorageaccount:ResourceGroup", resourceGroupName,location, {}, opts); 

         console.log(`Resource Group ${resourceGroupName} : location ${location} `);
    	 // Create an Azure Resource Group
		const resourceGroup = new azure.core.ResourceGroup(resourceGroupName, 
		{
		    location:location,
		},

           { 
              parent: this 
           }
        );

	   // Create a property for the resource group name that was created
        this.resourceGroupName = resourceGroup.name,
        this.location = location
        

         // For dependency tracking, register output properties for this component
        this.registerOutputs({
            resourceGroupName: this.resourceGroupName,
           
        });

    }

}


module.exports.ResourceGroup = ResourceGroup;


This class can be instantiated as below:

// import the class 
const resourceGroup = require("./create-resource-group.js");


// Create an Azure Resource Group
// Arguments : Resource group name and location
let azureResouceGroup = new resourceGroup.ResourceGroup("rgtest","EastUS");

  1. Multi-Cloud: Pulumi supports all major clouds — including AWS, Azure and Google Cloud, as well as Kubernetes clusters. This delivers a consolidated programming model and tools for managing cloud software anywhere. There’s no need to learn three different YAML dialects, and five different CLIs, just to get a simple container-based application stood up in production.

The below code uses a single Pulumi program to provision resources in both AWS and GCP (Google Cloud Platform). The example is in typescript and it is required to install @pulumi/aws and @pulumi/gcp packages from NPM.

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

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

// Create a GCP resource (Storage Bucket)
const gcpBucket = new gcp.storage.Bucket("my-bucket");

// Export the names of the buckets
export const bucketNames = [
awsBucket.bucket,
gcpBucket.name,
];

Pulumi ensures that resources will be created in both clouds. Let’s take a look at how Pulumi creates the plan for both clouds and deploy the resources to the respective clouds.

Previewing update (multicloud-ts-buckets-dev):

Type Name Plan
+ pulumi:pulumi:Stack multicloud-ts-buckets-multicloud-ts-buckets-dev create
+ ├─ gcp:storage:Bucket my-bucket create
+ └─ aws:s3:Bucket my-bucket create

Resources:
3 changes
+ 3 to create

Do you want to perform this update? yes
Updating (multicloud-ts-buckets-dev):

Type Name Status
+ pulumi:pulumi:Stack multicloud-ts-buckets-multicloud-ts-buckets-dev created
+ ├─ gcp:storage:Bucket my-bucket created
+ └─ aws:s3:Bucket my-bucket created

Outputs:
bucketNames: [
[0]: "my-bucket-c819937"
[1]: "my-bucket-f722eb9"
]

Resources:
3 changes
+ 3 created

Duration: 21.713128552s

The outputs show the name of the AWS and GCP buckets respectively.

Another scenario would be to create a storage account and S3 object in Azure and AWS respectively using Pulumi.

// Creating storage account in Azure

const pulumi = require("@pulumi/pulumi");
const azure = require("@pulumi/azure");

const storageAccount = new azure.storage.Account(storageAccountName, {
   	resourceGroupName: rgName,
    	location: rgLocation,
    	accountTier: "Standard",
    	accountReplicationType: "LRS",
 });

// Creating S3 bucket  in AWS

const pulumi = require("@pulumi/pulumi");
const azure = require("@pulumi/aws");

const siteBucket = new aws.s3.Bucket("my-bucket",{
	website: {
    indexDocument: "index.html",
  }
});

Pulumi enables you to mix and match these cloud resources inside of the same or different program or file.

  1. Stacks: A core concept in Pulumi is the idea of a “stack.” A stack is an isolated instance of your cloud program whose resources and configuration are distinct from all other stacks. You might have a stack each for production, staging, and testing, or perhaps for each single-tenanted environment. Pulumi’s CLI makes it trivial to spin up and tear down lots of stacks.

Closing Thoughts

I would like to close this post with a statement: Cloud Renaissance for DevOps and Developers as called by the whole internet community. Building powerful cloud software will be more enjoyable, more productive, and more collaborative for the developers. Of course, everything comes with a cost: after exploring, I found that Pulumi lacks some documentation. Besides this, for developers to write IAC, a deep understanding of infrastructure is a must.

I hope that this post has given you a better idea of the overall platform, approach, and unique strengths.

Happy Puluming 🙂