Pulumi + GitHub Actions: A CI/CD Pipeline for AWS S3 Deployment
This is a submission for the Pulumi Deploy and Document Challenge: Fast Static Website Deployment What I Built For the Pulumi challenge, I built a project that provisions an AWS S3 bucket and hosts a static mini-site using Pulumi and Python. Prompt 1: I created an S3 bucket with Pulumi and uploaded a simple website (HTML, CSS, JavaScript) that shares my journey learning Infrastructure as Code (IaC). I deployed it manually using pulumi up. Prompt 2: I automated the deployment process with GitHub Actions. The workflow in .github/workflows/deploy.yml runs pulumi up on every push to the main branch, updating the S3 bucket automatically. The site is live at: Before creating prompt2: After creating prompt2: https://d33ejg1jsmvn6g.cloudfront.net/index.html Live Demo Link Here’s a quick demo video showing my project in action, including the GitHub Actions workflow running and the S3 site updating: https://d33ejg1jsmvn6g.cloudfront.net/index.html Project Repo Check out the project repository on GitHub, which includes a detailed README with setup instructions: https://github.com/vec21/pulumi-prompt2-challenge My Journey This project was an exciting journey into Infrastructure as Code (IaC) and CI/CD, but it came with its share of challenges. Starting with Prompt 1 For Prompt 1, I learned how to use Pulumi to provision an S3 bucket on AWS. I chose Python because I’m comfortable with it, and the Pulumi documentation was super helpful. Writing the __main__.py to create the bucket and upload my mini-site (HTML, CSS, JavaScript) went smoothly. The biggest challenge here was figuring out the right AWS permissions for the S3 bucket to host a static site—I had to tweak IAM roles to allow public access, which took some trial and error. Once I got it working, seeing my site live on the S3 URL was a rewarding moment! Tackling Prompt 2 Prompt 2 was where things got trickier. Automating the deployment with GitHub Actions sounded straightforward, but I ran into several issues: Billing Issue with GitHub Actions: Initially, my workflow wouldn’t run because of a payment error in my GitHub account. Pulumi Login Errors: The biggest hurdle was authenticating Pulumi in the GitHub Actions workflow. My first attempt at pulumi login failed with an unknown flag: --token error because I used an incorrect command. After several tries, I learned that setting the PULUMI_ACCESS_TOKEN as an environment variable and running pulumi login without extra flags worked best. Separating the AWS and Pulumi credential steps in the workflow also helped make debugging easier. Iterating and Testing: I made small changes to my index.html file to test the CI/CD pipeline. Watching the GitHub Actions workflow run successfully and update the S3 bucket automatically was a huge win! Below is a screenshot of the workflow running smoothly after fixing the issues. I added this code to index.html Automatic Deployment with GitHub Actions - 06/04/2025 and Automatic Deployment with GitHub Actions - 06/04/2025 - Test2 git push origin main What I Learned This project taught me a lot about IaC and CI/CD: Pulumi is Powerful: Using Pulumi to manage infrastructure with code is much more intuitive than clicking through the AWS Console. CI/CD Saves Time: Automating deployments with GitHub Actions makes the process faster and less error-prone. Debugging is Key: I got better at reading logs and troubleshooting issues, like authentication errors and billing limits. Community Support: The Pulumi and GitHub Actions communities (and some AI assistance!) were invaluable in helping me overcome challenges. Overall, this challenge pushed me to grow as a developer and gave me practical skills I can apply to real-world projects. Using Pulumi Pulumi was the core tool for managing infrastructure in this project, and I used it in both Prompt 1 and Prompt 2. How I Used Pulumi Prompt 1: I wrote a Python script (__main__.py) to provision an AWS S3 bucket and configure it as a static website. Pulumi made it easy to define the bucket, set the index.html as the default document, and upload my mini-site files (HTML, CSS, JavaScript) with just a few lines of code. I ran pulumi up to deploy everything manually. Prompt 2: I reused the same Pulumi code in my GitHub Actions workflow (.github/workflows/deploy.yml). The workflow runs pulumi up automatically on every push to the main branch, updating the S3 bucket with any changes to my site. Pulumi handled the infrastructure updates seamlessly, ensuring consistency between manual and automated deploys. Why Pulumi Was Beneficial Pulumi brought several advantages to this project: Code-Based Infrastructure: Writing infrastructure as code in Python was much more intuitive than clicking through the AWS Console. I could version my infrastructure alongside my site code in Git. Reusability: The sam

This is a submission for the Pulumi Deploy and Document Challenge: Fast Static Website Deployment
What I Built
For the Pulumi challenge, I built a project that provisions an AWS S3 bucket and hosts a static mini-site using Pulumi and Python.
-
Prompt 1: I created an S3 bucket with Pulumi and uploaded a simple website (HTML, CSS, JavaScript) that shares my journey learning Infrastructure as Code (IaC). I deployed it manually using
pulumi up
. -
Prompt 2: I automated the deployment process with GitHub Actions. The workflow in
.github/workflows/deploy.yml
runspulumi up
on everypush
to themain
branch, updating the S3 bucket automatically.
The site is live at:
-
Before creating prompt2:
- After creating prompt2: https://d33ejg1jsmvn6g.cloudfront.net/index.html
Live Demo Link
Here’s a quick demo video showing my project in action, including the GitHub Actions workflow running and the S3 site updating:
https://d33ejg1jsmvn6g.cloudfront.net/index.html
Project Repo
Check out the project repository on GitHub, which includes a detailed README with setup instructions:
https://github.com/vec21/pulumi-prompt2-challenge
My Journey
This project was an exciting journey into Infrastructure as Code (IaC) and CI/CD, but it came with its share of challenges.
Starting with Prompt 1
For Prompt 1, I learned how to use Pulumi to provision an S3 bucket on AWS. I chose Python because I’m comfortable with it, and the Pulumi documentation was super helpful. Writing the __main__.py
to create the bucket and upload my mini-site (HTML, CSS, JavaScript) went smoothly. The biggest challenge here was figuring out the right AWS permissions for the S3 bucket to host a static site—I had to tweak IAM roles to allow public access, which took some trial and error. Once I got it working, seeing my site live on the S3 URL was a rewarding moment!
Tackling Prompt 2
Prompt 2 was where things got trickier. Automating the deployment with GitHub Actions sounded straightforward, but I ran into several issues:
Billing Issue with GitHub Actions: Initially, my workflow wouldn’t run because of a payment error in my GitHub account.
Pulumi Login Errors: The biggest hurdle was authenticating Pulumi in the GitHub Actions workflow. My first attempt at
pulumi login
failed with anunknown flag: --token
error because I used an incorrect command. After several tries, I learned that setting thePULUMI_ACCESS_TOKEN
as an environment variable and runningpulumi login
without extra flags worked best. Separating the AWS and Pulumi credential steps in the workflow also helped make debugging easier.
-
Iterating and Testing: I made small changes to my
index.html
file to test the CI/CD pipeline. Watching the GitHub Actions workflow run successfully and update the S3 bucket automatically was a huge win! Below is a screenshot of the workflow running smoothly after fixing the issues.
I added this code to index.html Automatic Deployment with GitHub Actions - 06/04/2025 Automatic Deployment with GitHub Actions - 06/04/2025 - Test2
and
git push origin main
What I Learned
This project taught me a lot about IaC and CI/CD:
- Pulumi is Powerful: Using Pulumi to manage infrastructure with code is much more intuitive than clicking through the AWS Console.
- CI/CD Saves Time: Automating deployments with GitHub Actions makes the process faster and less error-prone.
- Debugging is Key: I got better at reading logs and troubleshooting issues, like authentication errors and billing limits.
- Community Support: The Pulumi and GitHub Actions communities (and some AI assistance!) were invaluable in helping me overcome challenges.
Overall, this challenge pushed me to grow as a developer and gave me practical skills I can apply to real-world projects.
Using Pulumi
Pulumi was the core tool for managing infrastructure in this project, and I used it in both Prompt 1 and Prompt 2.
How I Used Pulumi
-
Prompt 1: I wrote a Python script (
__main__.py
) to provision an AWS S3 bucket and configure it as a static website. Pulumi made it easy to define the bucket, set theindex.html
as the default document, and upload my mini-site files (HTML, CSS, JavaScript) with just a few lines of code. I ranpulumi up
to deploy everything manually. -
Prompt 2: I reused the same Pulumi code in my GitHub Actions workflow (
.github/workflows/deploy.yml
). The workflow runspulumi up
automatically on everypush
to themain
branch, updating the S3 bucket with any changes to my site. Pulumi handled the infrastructure updates seamlessly, ensuring consistency between manual and automated deploys.
Why Pulumi Was Beneficial
Pulumi brought several advantages to this project:
- Code-Based Infrastructure: Writing infrastructure as code in Python was much more intuitive than clicking through the AWS Console. I could version my infrastructure alongside my site code in Git.
- Reusability: The same Pulumi script worked for both manual and automated deploys, saving me time and reducing errors.
-
Clear Feedback: Pulumi’s CLI gave detailed output during
pulumi up
, making it easy to understand what changes were being applied to my S3 bucket.
Assistance with GitHub Copilot
While I didn’t use Pulumi Copilot, I did rely on GitHub Copilot to help with some parts of the project. One key prompt I used was tweaking the GitHub Actions workflow to fix a pulumi login
issue. Copilot suggested simplifying the authentication step by removing unnecessary flags, which helped me move forward after several failed attempts. This assistance was crucial in debugging and getting the CI/CD pipeline to work smoothly.