Write infra as code with Pulumi
By: Raja Gopal
Tags: Cloud, Infra As Code, Pulumi, Learn, Infrastructure

Photo by Oskar Yildiz on Unsplash

Hello All!!!

Before I jump into Pulumi, let me give an introduction to this tool. When I talk about the topic Infra as a code, we all remember a few tools in the market, they are ARM templates, CFT and Terraform. Of these, Terraform is the most widely used tool for being able to work with multiple clouds like AWS, Azure, Azure DevOps, Kubernetes, GCP, etc. Terraform is very efficient in provisioning infrastructures in most of the clouds and it also helps users to handle multi-cloud in a single project. But, the challenge comes in when users are required to learn a new language called HCL that is specific to terraform although it can be written in JSON the JSON format doesn’t have enough support for complex use cases.

Not only the effort to learn a new language but also the challenge that comes in when the code written in HCL had to test. There are multiple tools revolve around in the market like Tfsec, Terraform-compliance and Hashicorp themselves provide an enterprise tool called Sentinel. These tools stand out of Terraform and they have to be manually incorporated into your pipelines where you deploy the infrastructure. Some tools like Tfsec also help you to scan at the repository level but it supports only Github workflow. Again, there is an effort required to learn the language required to execute the tools. Some are simple like Tfsec for which the custom checks can be written in either JSON/YML but a tool like Sentinel is not so.

So, why Pulumi?

If you can write infrastructure code in the programming language that you are comfortable with, won’t you opt for that? Yes, Pulumi offers you that flexibility. You can write in TypeScript, Python, Go and CSharp. This also helps you to perform the unit-tests with many easier tools and the test case can also be written in the same language.

Pulumi provides three different products, Pulumi SDK, Pulumi for teams and Crossguard.

Pulumi SDK — provide the development framework to write infrastructure code and

Pulumi for teams — provide managing team efforts and stacks for multiple clouds.

Pulumi Crossguard — provide the “Policy as code” for Pulumi which is similar to “Sentinel” for Terraform but Crossguard will not require you to learn a new language nor it is difficult.

How to start with?

Pulumi can be installed using the native package managers of each environment.

Windows

choco install pulumi

Or can be installed with an installation script as below

@”%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe” -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command “[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; iex ((New-Object System.Net.WebClient).DownloadString(‘https://get.pulumi.com/install.ps1'))" && SET “PATH=%PATH%;%USERPROFILE%\.pulumi\bin”

Linux

Can be installed with the installation script

curl -fsSL https://get.pulumi.com | sh

MACOS

using the native brew package

brew install pulumi

Let's start with Azure Cloud

Pre-Requisite:

install pulumi install Go configure Azure CLI

Create a New Project

# from within your $GOPATH

$ mkdir quickstart && cd quickstart

$ pulumi new azure-go

For the first time, Pulumi will expect you to log in to the Pulumi Service. Signup with the Pulumi service which is free for individual users, with features available for teams. Once you are signed in to the Pulumi service, you can log in with either an access token or a prompt that will help you to log in with web browser. To know more about the Pulumi CLI, please read here.

The access token for each organization that you create in the Pulumi Service is available in the “Settings” tab.

Projects: Project is a collection of code

Stack: It is an instance of a code. For example, a stack can be considered as an environment like Dev, Stage and Prod.

Work offline?

Yes, Pulumi also helps you to login into your local workstation as below.

pulumi login --local

Start write the program

Next, you can configure your environment with some global values namely, “client_id”, “client_secret” and names of the resources going to be created. The configuration of these values is done with the Pulumi CLI as below.

pulumi config set clientId “sometext” pulumi config set clientSecret --secret “client secret”

The config command will create a new config file called “pulumi-<stack>.yaml”. When the secret flag is passed with the config command, it is encrypted and stored in the config file.

A typical Pulumi project looks like below

pulumi.yaml : file contains the basic information about the project like name and description.

main.go: The program file where the code is written

The Go program file will import the required packages for Pulumi core and the Pulumi Azure SDK.

The main function will call the pulumi.Run function which creates the resources.

Configuration and strings

The values which we already configured in the pulumi-<stack>.yaml file can be called inside the program by initializing the “config” package as

c := config.New(ctx, “”)

the config values are then called in as below

Name: pulumi.String(c.Require(“storageName”)),

A keynote to keep in mind is, any value you feel to hard-code should be used with the respective Pulumi variable function. For example, if you are passing a value for “resource group “, then it looks like

Name: pulumi.String(“testpulumi”),

Dependencies

By default, all the resources are mapped with their dependent when the stack is built but there are some exceptional cases where you may require to add an explicit “dependsOn” to your code and this case can only be identified after the code is executed.

Build the Stack

Once you complete your code, build your stack with the command, “pulumi up”. The progress of the stack can be viewed from the command line as well as from the Pulumi Service. The command can be appended with “-y” to avoid the prompt for confirmation.

Once the resources are created, they are viewable in the resources tab

Stack

The stacks and their components details are fetched with the Pulumi CLI

pulumi stack ls

pulumi stack -u -s azure-dev

pulumi stack export --file stack.json pulumi stack import --file stack.json

Troubleshooting

If any operations like “pulumi up” or “pulumi destroy” got interrupted it may result in the stack being not usable with some pending operations. This can be resolved by exporting the stack and remove the resources under “pending” and then import it back.

Termination

The entire stack can be deleted with the command, “pulumi destroy -y”

While destroying, the resource dependencies are taken with the help of the stack information.

I will end this story here and continue to write more on Pulumi and its use case for different clouds.

Thanks…..