From AWS Console Chaos to a Static Site with Pulumi: My IaC Journey
This is a submission for the Pulumi Deploy and Document Challenge: Fast Static Website Deployment What I Built I built a fast static website hosted on AWS S3 and served globally via CloudFront. It features two pages: a personal diary (index.html) and a tutorial page (tutorial.html) with interactive "Copy" buttons for code snippets. Using Pulumi, I automated the deployment of an S3 bucket, set it up as a public website, and added a CloudFront CDN for speed and security—all coded in Python. This project replaced my old, tedious AWS console workflow with Infrastructure as Code (IaC). Live Demo Link Diary: https://d33ejg1jsmvn6g.cloudfront.net/index.html Tutorial: https://d33ejg1jsmvn6g.cloudfront.net/tutorial.html Project Repo Check out my full code and a detailed README here: https://github.com/vec21/pulumi-s3-challenge My Journey Hey there! I’m Veríssimo, a beginner in IaC, and this is my story of escaping the AWS console chaos. I used to spend 15 minutes per EC2 instance in the console—selecting instance types, networks, SSH keys—repeating it all for every test. It was slow and frustrating. For this challenge, I dove into Pulumi to deploy a static website, and it was a game-changer! I started on Ubuntu (more on my Windows woes later). First, I installed Pulumi and AWS CLI: curl -fsSL https://get.pulumi.com | sh sudo apt install unzip curl -y curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install I configured AWS credentials with aws configure, using an IAM user with full access to EC2, S3, CloudFront, and IAM. Next, I tested Pulumi with the vm-aws-python template (pulumi new vm-aws-python). A quick pulumi up, a "yes," and my first EC2 instance was live in minutes! This hooked me, so I aimed bigger: a static website. Using pulumi new static-website-aws-python, I set out to host a diary and tutorial page. But my first pulumi up hit a snag: TypeError: BucketV2._internal_init() got an unexpected keyword argument 'website' The S3 V2 API had changed! After digging into Pulumi’s docs, I updated __main__.py: bucket = aws.s3.BucketV2("bucket") aws.s3.BucketWebsiteConfigurationV2("bucket-website", bucket=bucket.bucket, index_document={"suffix": "index.html"}) I added public permissions, and it worked! To make the site fast and secure, I added CloudFront. My final __main__.py synced my ./www folder (HTML, CSS, JS, images) to S3 and set up a CDN. Running pulumi up --refresh gave me: S3 URL: http://bucket-17bf36b.s3-website-us-west-2.amazonaws.com CloudFront URL: https://d33ejg1jsmvn6g.cloudfront.net Then came the Windows hiccup. My username "Veríssimo" (with an accent) broke Pulumi’s paths. Switching to "Verissimo" and rebooting locked me out—chaos! Thankfully, my Ubuntu dual-boot saved the day. Lessons learned: Avoid accents in Windows usernames—trust me! S3 V2 needs separate website config—check the docs. CloudFront is worth it for speed and HTTPS. Using Pulumi Pulumi turned a tedious task into a fun coding project. I used its Python SDK to define my infrastructure—first spinning up an EC2 instance with vm-aws-python, then building the static site with static-website-aws-python. In __main__.py, I configured an S3 bucket, website settings, and CloudFront distribution. It was beneficial because it saved me hours of console clicking, made my setup reproducible, and let me version-control it with Git. The Pulumi docs were key for fixing the S3 V2 issue. I didn’t use Pulumi Copilot, but splitting the bucket and website config was a critical manual tweak: bucket = aws.s3.BucketV2("bucket") aws.s3.BucketWebsiteConfigurationV2("bucket-website", bucket=bucket.bucket, index_document={"suffix": "index.html"}) Pulumi + Python = beginner-friendly power!

This is a submission for the Pulumi Deploy and Document Challenge: Fast Static Website Deployment
What I Built
I built a fast static website hosted on AWS S3 and served globally via CloudFront. It features two pages: a personal diary (index.html
) and a tutorial page (tutorial.html
) with interactive "Copy" buttons for code snippets. Using Pulumi, I automated the deployment of an S3 bucket, set it up as a public website, and added a CloudFront CDN for speed and security—all coded in Python. This project replaced my old, tedious AWS console workflow with Infrastructure as Code (IaC).
Live Demo Link
- Diary: https://d33ejg1jsmvn6g.cloudfront.net/index.html
- Tutorial: https://d33ejg1jsmvn6g.cloudfront.net/tutorial.html
Project Repo
Check out my full code and a detailed README here:
https://github.com/vec21/pulumi-s3-challenge
My Journey
Hey there! I’m Veríssimo, a beginner in IaC, and this is my story of escaping the AWS console chaos. I used to spend 15 minutes per EC2 instance in the console—selecting instance types, networks, SSH keys—repeating it all for every test. It was slow and frustrating. For this challenge, I dove into Pulumi to deploy a static website, and it was a game-changer!
I started on Ubuntu (more on my Windows woes later). First, I installed Pulumi and AWS CLI:
curl -fsSL https://get.pulumi.com | sh
sudo apt install unzip curl -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install
I configured AWS credentials with aws configure
, using an IAM user with full access to EC2, S3, CloudFront, and IAM.
Next, I tested Pulumi with the vm-aws-python
template (pulumi new vm-aws-python
). A quick pulumi up
, a "yes," and my first EC2 instance was live in minutes! This hooked me, so I aimed bigger: a static website. Using pulumi new static-website-aws-python
, I set out to host a diary and tutorial page. But my first pulumi up
hit a snag:
TypeError: BucketV2._internal_init() got an unexpected keyword argument 'website'
The S3 V2 API had changed! After digging into Pulumi’s docs, I updated __main__.py
:
bucket = aws.s3.BucketV2("bucket")
aws.s3.BucketWebsiteConfigurationV2("bucket-website", bucket=bucket.bucket, index_document={"suffix": "index.html"})
I added public permissions, and it worked!
To make the site fast and secure, I added CloudFront. My final __main__.py
synced my ./www
folder (HTML, CSS, JS, images) to S3 and set up a CDN. Running pulumi up --refresh
gave me:
- S3 URL: http://bucket-17bf36b.s3-website-us-west-2.amazonaws.com
- CloudFront URL: https://d33ejg1jsmvn6g.cloudfront.net
Then came the Windows hiccup. My username "Veríssimo" (with an accent) broke Pulumi’s paths. Switching to "Verissimo" and rebooting locked me out—chaos! Thankfully, my Ubuntu dual-boot saved the day.
Lessons learned:
- Avoid accents in Windows usernames—trust me!
- S3 V2 needs separate website config—check the docs.
- CloudFront is worth it for speed and HTTPS.
Using Pulumi
Pulumi turned a tedious task into a fun coding project. I used its Python SDK to define my infrastructure—first spinning up an EC2 instance with vm-aws-python
, then building the static site with static-website-aws-python
. In __main__.py
, I configured an S3 bucket, website settings, and CloudFront distribution. It was beneficial because it saved me hours of console clicking, made my setup reproducible, and let me version-control it with Git. The Pulumi docs were key for fixing the S3 V2 issue. I didn’t use Pulumi Copilot, but splitting the bucket and website config was a critical manual tweak:
bucket = aws.s3.BucketV2("bucket")
aws.s3.BucketWebsiteConfigurationV2("bucket-website", bucket=bucket.bucket, index_document={"suffix": "index.html"})
Pulumi + Python = beginner-friendly power!