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!

Apr 6, 2025 - 06:23
 0
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

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:

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!