Using Pulumi on AWS

In this post I shall how to use the examples provided by Pulumi to setup a static website using AWS S3.

Pre requisities

  1. These steps assume you have already cloned 2. Python version >=3 3. AWS account

Setup user in IAM

  • Create a user in AWS which has access to create S3 resources
  • Export the credentials.csv
  • You will need the AWS_ACCESS_KEY_ID
  • You will need the AWS_SECRET_ACCESS_KEY
  • Note down the AWS region you want to deploy into

Deployment configuration

  • Export the following environment variables
export AWS_ACCESS_KEY_ID=<your access key id>
export AWS_SECRET_ACCESS_KEY=<your secret access key>

Initialize the stack

Make sure you are in the top level directory where you cloned the examples git repository

cd aws-py-s3-folder
pulumi stack init s3-website
pulumi config set aws:region <aws_region>


It is important to note that if you run ‘pulumi stack init s3-website’ inside a directory without a project file i.e. the** Pulumi.yaml file**.

You will get the following error message.

error: no Pulumi project found in the current working directory

Pulumi core files

  • Pulumi.yaml » main project file
  • » entry point file
  • www » directory holding the static content which will be served in the S3 bucket
  • requirements.txt » a list of required Python modules

Once you have initialized the Pulumi stack you will also find an extra file called ‘Pulumi.S3-website.yaml’ which contains the AWS region you configured Pulumi to use.

You will notice the requirements.txt file containing the required Python modules.


No HCL here except only Python for defining the deployment. As below you’ll notice the modules from pulumi are imported.

Definition of the S3 read policy, along with what files will be served.

The export of stack properties are defined at the bottom, these can later be inspected.

import json
import mimetypes
import os

from pulumi import export, FileAsset
from pulumi_aws import s3

web_bucket = s3.Bucket('s3-website-bucket', website={
    "index_document": "index.html"

content_dir = "www"
for file in os.listdir(content_dir):
    filepath = os.path.join(content_dir, file)
    mime_type, _ = mimetypes.guess_type(filepath)
    obj = s3.BucketObject(file,,

def public_read_policy_for_bucket(bucket_name):
    return json.dumps({
        "Version": "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
            "Resource": [

bucket_name =
bucket_policy = s3.BucketPolicy("bucket-policy",

# Export the name of the bucket
export('website_url', web_bucket.website_endpoint)


Python virtual env

This virtual environment is required to install dependency packages necessary for the deployment.

python -m venv venv
source venv/bin/activate
pip install -r requirements.txt


pulumi up
Previewing update (s3-website):
        Type                    Name                         Plan       
    +   pulumi:pulumi:Stack     aws-py-s3-folder-s3-website  create     
    +   ├─ aws:s3:Bucket        s3-website-bucket            create     
    +   ├─ aws:s3:BucketPolicy  bucket-policy                create     
    +   ├─ aws:s3:BucketObject  index.html                   create     
    +   ├─ aws:s3:BucketObject  favicon.png                  create     
    +   └─ aws:s3:BucketObject  python.png                   create     
    + 6 to create

Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
> no
Do you want to perform this update?  [Use arrows to move, enter to select, type to filter]
> yes
Do you want to perform this update? yes
Updating (s3-website):
        Type                    Name                         Status      
    +   pulumi:pulumi:Stack     aws-py-s3-folder-s3-website  created     
    +   ├─ aws:s3:Bucket        s3-website-bucket            created     
    +   ├─ aws:s3:BucketObject  index.html                   created     
    +   ├─ aws:s3:BucketObject  python.png                   created     
    +   ├─ aws:s3:BucketObject  favicon.png                  created     
    +   └─ aws:s3:BucketPolicy  bucket-policy                created     
    bucket_name: "s3-website-bucket-#####"
    website_url: "s3-website-bucket-#####".s3-website-#####""                                                                                                                                          

    + 6 created

Duration: 12s


Inspect stack output

pulumi stack output
Current stack outputs (2):
    OUTPUT       VALUE
    bucket_name  s3-website-bucket-####

Open the website_url in your browser, and you will see the static contents served in S3.


pulumi destroy -y
Previewing destroy (s3-website):
        Type                    Name                         Plan       
    -   pulumi:pulumi:Stack     aws-py-s3-folder-s3-website  delete     
    -   ├─ aws:s3:BucketPolicy  bucket-policy                delete     
    -   ├─ aws:s3:BucketObject  python.png                   delete     
    -   ├─ aws:s3:BucketObject  favicon.png                  delete     
    -   ├─ aws:s3:BucketObject  index.html                   delete     
    -   └─ aws:s3:Bucket        s3-website-bucket            delete     
    - bucket_name: "s3-website-bucket-#####""
    - website_url: "s3-website-bucket-#####".s3-website-#####""                                                                                                                                          

    - 6 to delete

Destroying (s3-website):
        Type                    Name                         Status      
    -   pulumi:pulumi:Stack     aws-py-s3-folder-s3-website  deleted     
    -   ├─ aws:s3:BucketPolicy  bucket-policy                deleted     
    -   ├─ aws:s3:BucketObject  index.html                   deleted     
    -   ├─ aws:s3:BucketObject  python.png                   deleted     
    -   ├─ aws:s3:BucketObject  favicon.png                  deleted     
    -   └─ aws:s3:Bucket        s3-website-bucket            deleted     
    - bucket_name: "s3-website-bucket-#####"
    - website_url: "s3-website-bucket-#####".s3-website-#####""                                                                                                                                          

    - 6 deleted

Duration: 8s

Delete the stack

pulumi stack rm s3-website -y
Stack 's3-website' has been removed!

Also remove the IAM user you created for this demo.


Overall time: <1min to setup a basic S3 bucket and serve static content in AWS.

Last updated on 24 Apr 2020
Published on 24 Apr 2020