Pulumi – Just another IaC? – Part 1

Pulumi infrastructure as actual code!

Pulumi allows you to write code in your favourite language. It supports languages such as Python, Javascript, C# and more.

The obvious benefit is your team can use their language of choice to write IaC. Lets be frank, DSLs are never going to be same compared to the expressiveness of your programming language of choice.

Additional benefits can include:

  • Using design patterns such as factories (If you want to abstract more, maybe if you are multi-cloud)
  • Unit testing using Unit test frameworks you use for your other applications (NUnit, MSUnit, XUnit)
  • Language features such as lambdas, loops, conditionals and more


In this example i am using my Mac OS. For further details on other OS please visit :https://www.pulumi.com/

To install pulumi on Mac:

brew install pulumi

I am using dotnet core so have already installed the dotnet core 3.0 runtime.

Make sure you have installed azure cli:https://www.pulumi.com/docs/intro/cloud-providers/azure/setup/

Creating your first project

In this example repo i created a folder called pulumi-dotnecore. To create a new pulumi project run the following command:

pulumi new projectname

Note when you run this you wull be redirected to the Pulumi portal where you will have to sign up if you have not already.

Pulumi structure

The Pulumi cli will create a dotnet console project with the following structure:


A word about state

As you are aware Terraform requires state management of the tfstate file. And if you are using ARM there is no state file as it is managed by the ARM deployment. Pulumi gives you the perception that it is similar to ARM when using the Pulumi service backend.


However, this is not entirely true. Pulumi tracks state via a checkpoint. This defaults to automatic state management when starting with the Pulumi service backend. However, if that does not fit your requirement you can defer to a json state file locally or use a remote backend in your chosen cloud provider. Further info can be found here:


The Pulumi stage/environment file

The file named Pulumi.dev.yaml is essentially the equivalent of your ARM parameters file or your Terraform .tfvars file. This is the file where you define your environment values for a particular stage of deployment (dev, uat, prod)

The Pulumi API framework provides you access to these values in your code via the config API. The key line is the config.Require method call on the Config object below.

        var config = new Config();
        var storageAccount = new Account("storage", new AccountArgs
            ResourceGroupName = resourceGroup.Name,
            Location = resourceGroup.Location,
            AccountReplicationType = 
            AccountTier = 
            EnableHttpsTrafficOnly = true

The Pulumi Stack

Pulumi works on the notion of infrastructure defined as a stack. For example in C# you define your resources in a file that inherits from the Stack parent class:

   class StorageAccountStack : Stack

Within the constructor of the class you then define the key infrastructure components of your stack. In the above example we define a storage account and a resource group. To see the full class go to:


This code is executed from your Program.cs file.

class Program
    static Task<int> Main() => Deployment.RunAsync<StorageAccountStack>


Both ARM and Terraform allow you declare outputs of your IaC deployments. Pulumi offers this construct using properties in C#. The way you define outputs is as follows:

[Output] public Output<string> ConnectionString { get; set; }
[Output] public Output<string> StorageUri { get; set; }

The above properties must be set in your Stack file.

The Pulumi inner loop

To deploy the above code Pulumi CLI offers a similar concept to Terraform plan and apply. Instead of plan you use Pulumi preview. To apply the changes you then use pulumi plan.

pulumi preview
Previewing update (dev)

View Live: https://app.pulumi.com/Khan/azureiac/dev/previews/8178ef36-8fee-4b6a-8026-3b53d6c53703

     Type                         Name           Plan       
 +   pulumi:pulumi:Stack          azureiac-dev   create     
 +   ├─ azure:core:ResourceGroup  resourceGroup  create     
 +   └─ azure:storage:Account     storage        create     
    + 3 to create

When you are happy then use pulumi up:

pulumi up
Previewing update (dev)

View Live: https://app.pulumi.com/Khan/azureiac/dev/previews/8ad865af-806f-476e-ae30-bc20c23da746

     Type                         Name           Plan       
 +   pulumi:pulumi:Stack          azureiac-dev   create     
 +   ├─ azure:core:ResourceGroup  resourceGroup  create     
 +   └─ azure:storage:Account     storage        create     
    + 3 to create

Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
> no

A word of note for Terraform

Terraform is actively bridging the gap from DSL to enabling programmers to use a programming language. This is currently through the Cloud Development Kit by Hashicorp.



Pulumi is fairly new in the IaC tooling ecosystem compared to Terraform. Terraform is widely used across multi-cloud providers. It is actively contributed to by the Open source community.

In the next part I will explore some basic gotchas in terms of how resources are named by default (particularly resource groups), how to use it in a CI/CD automation tool.

I hope this was a useful and beneficial introduction to Pulumi.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: