Pulumi-Day1- Getting Started
Tags: devops, python, aws, pulumi
Published: 2024-07-01 10:20:21

Hi All,

I am starting to learn pulimi. Pulumi's infrastructure-as-code SDK helps you create, deploy, and manage AWS containers, serverless functions, and infrastructure using programming languages like TypeScript, Python, Go, C#, and Java, and markup languages like YAML. The Pulumi AWS provider packages and CLI help you accomplish all these within minutes.

Docs
- https://www.pulumi.com/docs/clouds/aws/get-started/create-project/
- https://www.pulumi.com/docs/clouds/aws/get-started/begin/
- https://www.pulumi.com/docs/clouds/aws/get-started/create-project/

Scope of this blog will be just to check how pulumi project works. Its a learning journey for Infrastructure as code with AWS.

Selected Pulumi for infrastructure-as-code as it provides programming language flexibility (It means you write test cases) & integration with a lot of the cloud providers (like aws, azure, gcp etc).

As I am comfortable with Python, it will be my choice of language.
Also, I am using my windows personal machine.

## Environment Setup

Following link: https://www.pulumi.com/docs/clouds/aws/get-started/begin/
Looks like you need Powershell is preferred to install pulumi as per documentation.

_To install pulumi_

```
choco install pulumi
```
To check installed pulumi version
```
pulumi version
```
Version installed: v3.121.0

You need to install Python or any other language you are using. I have Python already installed in my system. So, need to install it.


## Configure Pulumi to access your AWS account

Following page: https://www.pulumi.com/registry/packages/aws/installation-configuration/

Pulumi requires cloud credentials to manage and provision resources. You must use an IAM user account that has programmatic access with rights to deploy and manage resources handled through Pulumi.

I already have AWS CLI installed on my system. For pulumi we need to create a new IAM user/ existing IAM user. 

Followed below mentioned steps

1. I create a new IAM user "pulumi-user"
2. Gave AdministratorAccess to the user (note: Gave it admin access for ease of experiments)
3. Added profile "pulumi-dev" aws_access key & secret key in ~/.aws/credentials (screenshot below)
4. Configure pulumi to use the profile from your terminal (command: pulumi config set aws:profile pulumi-dev)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s40rcunmtfqpf768cm2n.png)


## Create a Pulumi Project

Reference link: https://www.pulumi.com/docs/clouds/aws/get-started/create-project/

I created a gitlab project called "pulumi". Created the project "awsproj" as mentioned in the steps given on the document.

```
PS > pulumi new aws-python
This command will walk you through creating a new Pulumi project.

Enter a value or leave blank to accept the (default), and press <ENTER>.
Press ^C at any time to quit.

project name (project): awsproj
project description (A minimal AWS Python Pulumi program):
Created project 'awsproj'

stack name (dev):
Created stack 'dev'
Enter your passphrase to protect config/secrets:
Re-enter your passphrase to confirm:

The toolchain to use for installing dependencies and running the program pip
aws:region: The AWS region to deploy into (us-east-1):
Saved config

Installing dependencies...

Creating virtual environment...
Finished creating virtual environment
Updating pip, setuptools, and wheel in virtual environment...
Requirement already satisfied: pip in c:\users\debashis\git_projects\pulumi\venv\lib\site-packages (22.0.4)
Collecting pip
  Downloading pip-24.1.1-py3-none-any.whl (1.8 MB)
     ---------------------------------------- 1.8/1.8 MB 11.6 MB/s eta 0:00:00
Requirement already satisfied: setuptools in c:\users\debashis\git_projects\pulumi\venv\lib\site-packages (58.1.0)
Collecting setuptools
  Downloading setuptools-70.1.1-py3-none-any.whl (883 kB)
     ------------------------------------- 883.3/883.3 KB 28.2 MB/s eta 0:00:00
Collecting wheel
  Using cached wheel-0.43.0-py3-none-any.whl (65 kB)
Installing collected packages: wheel, setuptools, pip
  Attempting uninstall: setuptools
    Found existing installation: setuptools 58.1.0
    Uninstalling setuptools-58.1.0:
      Successfully uninstalled setuptools-58.1.0
  Attempting uninstall: pip
    Found existing installation: pip 22.0.4
    Uninstalling pip-22.0.4:
      Successfully uninstalled pip-22.0.4
Successfully installed pip-24.1.1 setuptools-70.1.1 wheel-0.43.0
Finished updating
Installing dependencies in virtual environment...
Collecting pulumi<4.0.0,>=3.0.0 (from -r requirements.txt (line 1))
  Downloading pulumi-3.121.0-py3-none-any.whl.metadata (11 kB)
Collecting pulumi-aws<7.0.0,>=6.0.2 (from -r requirements.txt (line 2))
  Downloading pulumi_aws-6.42.1-py3-none-any.whl.metadata (8.4 kB)
Collecting protobuf~=4.21 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Downloading protobuf-4.25.3-cp310-abi3-win_amd64.whl.metadata (541 bytes)
Collecting grpcio~=1.60.1 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Downloading grpcio-1.60.1-cp310-cp310-win_amd64.whl.metadata (4.2 kB)
Collecting dill~=0.3 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Downloading dill-0.3.8-py3-none-any.whl.metadata (10 kB)
Collecting six~=1.12 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Downloading six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Collecting semver~=2.13 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Downloading semver-2.13.0-py2.py3-none-any.whl.metadata (5.0 kB)
Collecting pyyaml~=6.0 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1))
  Using cached PyYAML-6.0.1-cp310-cp310-win_amd64.whl.metadata (2.1 kB)
Collecting parver>=0.2.1 (from pulumi-aws<7.0.0,>=6.0.2->-r requirements.txt (line 2))
  Downloading parver-0.5-py3-none-any.whl.metadata (2.7 kB)
Collecting typing-extensions>=4.11 (from pulumi-aws<7.0.0,>=6.0.2->-r requirements.txt (line 2))
  Downloading typing_extensions-4.12.2-py3-none-any.whl.metadata (3.0 kB)
Collecting arpeggio>=1.7 (from parver>=0.2.1->pulumi-aws<7.0.0,>=6.0.2->-r requirements.txt (line 2))
  Downloading Arpeggio-2.0.2-py2.py3-none-any.whl.metadata (2.4 kB)
Collecting attrs>=19.2 (from parver>=0.2.1->pulumi-aws<7.0.0,>=6.0.2->-r requirements.txt (line 2))
  Downloading attrs-23.2.0-py3-none-any.whl.metadata (9.5 kB)
Downloading pulumi-3.121.0-py3-none-any.whl (263 kB)
   ---------------------------------------- 263.4/263.4 kB 5.5 MB/s eta 0:00:00
Downloading pulumi_aws-6.42.1-py3-none-any.whl (9.3 MB)
   ---------------------------------------- 9.3/9.3 MB 14.8 MB/s eta 0:00:00
Downloading dill-0.3.8-py3-none-any.whl (116 kB)
   ---------------------------------------- 116.3/116.3 kB 6.6 MB/s eta 0:00:00
Downloading grpcio-1.60.1-cp310-cp310-win_amd64.whl (3.7 MB)
   ---------------------------------------- 3.7/3.7 MB 3.2 MB/s eta 0:00:00
Downloading parver-0.5-py3-none-any.whl (15 kB)
Downloading protobuf-4.25.3-cp310-abi3-win_amd64.whl (413 kB)
   ---------------------------------------- 413.4/413.4 kB ? eta 0:00:00
Using cached PyYAML-6.0.1-cp310-cp310-win_amd64.whl (145 kB)
Downloading semver-2.13.0-py2.py3-none-any.whl (12 kB)
Downloading six-1.16.0-py2.py3-none-any.whl (11 kB)
Downloading typing_extensions-4.12.2-py3-none-any.whl (37 kB)
Downloading Arpeggio-2.0.2-py2.py3-none-any.whl (55 kB)
   ---------------------------------------- 55.3/55.3 kB ? eta 0:00:00
Downloading attrs-23.2.0-py3-none-any.whl (60 kB)
   ---------------------------------------- 60.8/60.8 kB ? eta 0:00:00
Installing collected packages: arpeggio, typing-extensions, six, semver, pyyaml, protobuf, grpcio, dill, attrs, pulumi, parver, pulumi-aws
Successfully installed arpeggio-2.0.2 attrs-23.2.0 dill-0.3.8 grpcio-1.60.1 parver-0.5 protobuf-4.25.3 pulumi-3.121.0 pulumi-aws-6.42.1 pyyaml-6.0.1 semver-2.13.0 six-1.16.0 typing-extensions-4.12.2
Finished installing dependencies
Finished installing dependencies

Your new project is ready to go!

To perform an initial deployment, run `pulumi up`
```
As we can see, it created a virtual environment ".venv".

Note: I have used pip as the package installer as finding error while using poetry.

How project structure looks like?
```
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        01-07-2024     14:29                venv
-a----        01-07-2024     14:29             14 .gitignore
-a----        01-07-2024     14:29            117 Pulumi.dev.yaml                                                                                                      
-a----        01-07-2024     14:29            206 Pulumi.yaml
-a----        01-07-2024     14:29             48 requirements.txt
-a----        01-07-2024     14:29            229 __main__.py
```

Contents inside requirements.txt

```
pulumi>=3.0.0,<4.0.0
pulumi-aws>=6.0.2,<7.0.0
```

**<u>Activate the Virtual Environment</u>**

To activate the virtual environment
```
.\venv\Scripts\activate
```
Check pip dependencies

```
pip freeze

Arpeggio==2.0.2
attrs==23.2.0
dill==0.3.8
grpcio==1.60.1
parver==0.5
protobuf==4.25.3
pulumi==3.121.0
pulumi_aws==6.42.1
PyYAML==6.0.1
semver==2.13.0
six==1.16.0
typing_extensions==4.12.2
```


## Running a Pulumi Project

When you create a pulumi project, it generates a __main__.py by default.

Content of __main__.py
```
"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket('my-bucket')

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)

```

It means if we run this script, it should create an S3 bucket with the prefix "my-bucket".

Lets run it
command:

```
pulumi up
```

_Screenshot of the run_

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h6stwhc5w7yuupm7sq0.png)

As you can see, it created an S3 bucket

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q55ns2g0blqe866w9uzx.png)

## Destroying Resources
command
```
pulumi destroy
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7oc1psw7w80ud3a78yvr.png)

As you can see bucket got destroyed.