DEV Community

Sudhin Suresh
Sudhin Suresh

Posted on

🚀 Fast Static Website Deployment with Pulumi, EC2, and GitHub Actions

💡 What I Built
I created a fast, automated deployment pipeline for a static website using:

AWS EC2 to host the site,

Pulumi to provision infrastructure as code,

GitHub Actions for CI/CD,

And Astro as the static site framework (can easily be swapped for others like Hugo or Jekyll).

The entire process—from infrastructure provisioning to code deployment—is triggered on every push to the main branch. It’s a clean, serverless-free solution leveraging IaaS for simplicity and control.

🔗 Live Demo Link
👉 http://
(Replace this with your EC2 public IP or domain)

📦 Project Repo
🧰 GitHub Repository: github.com/yourusername/fast-static-deploy
(Be sure to include a README with steps, architecture, and how to replicate the deployment!)

✍️ My Journey
This project started as a way to explore how fast and repeatable static site deployments could be using IaaS rather than managed services like Netlify or Vercel.

Key Milestones:
Static Site Creation – I used Astro for its quick setup and zero-JS static rendering.

Pulumi Setup – Defined an EC2 instance, security group, and userData script to install and configure Nginx.

GitHub Actions – Integrated Pulumi into the CI/CD pipeline and added an SCP step to upload the built static files to the EC2 instance.

Secrets Management – Stored Pulumi token, AWS keys, and EC2 SSH key securely in GitHub Secrets.

Challenges I Faced:
EC2 AMI choice and default user (ec2-user for Amazon Linux).

Setting up Pulumi authentication properly in GitHub Actions.

SCP to EC2: Ensuring the SSH key had proper permissions and that Nginx was serving the right folder.

What I Learned:
Pulumi’s type-safe infrastructure-as-code approach is intuitive and powerful.

GitHub Actions make CI/CD effortless with great community actions (e.g., scp-action).

Full control over infrastructure helps you understand deployment deeply—great for learning and production-ready work.

⚙️ Using Pulumi
Pulumi was the backbone of this project’s infrastructure. Here's how I used it:

Provisioned EC2 Instance with Nginx and configured it via userData.

Created Security Group to allow HTTP traffic.

Defined Outputs for public IP, which was picked up in the GitHub Action.

Here’s a simplified Pulumi (TypeScript) snippet I used:

ts

const server = new aws.ec2.Instance("web-server", {
ami: "ami-0c02fb55956c7d316",
instanceType: "t2.micro",
securityGroups: [group.name],
userData:
#!/bin/bash
sudo yum install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx
,
});
GitHub Actions + Pulumi:
I used the Pulumi GitHub Action to run pulumi up on every push to main. After that, I added an SCP step to deploy the static files:

yaml

  • name: Deploy files to EC2 uses: appleboy/scp-action@master with: host: ${{ secrets.EC2_HOST }} username: ec2-user key: ${{ secrets.EC2_SSH_KEY }} source: "dist/" target: "/usr/share/nginx/html" Pulumi made the whole provisioning process more robust and transparent. Everything is in code. I could destroy or recreate the infrastructure in minutes.

🎉 Thanks Pulumi & DEV for this awesome challenge!

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Image of Timescale

PostgreSQL for Agentic AI — Build Autonomous Apps on One Stack ☝️

pgai turns PostgreSQL into an AI-native database for building RAG pipelines and intelligent agents. Run vector search, embeddings, and LLMs—all in SQL

Build Today

👋 Kindness is contagious

Delve into this thought-provoking piece, celebrated by the DEV Community. Coders from every walk are invited to share their insights and strengthen our collective intelligence.

A heartfelt “thank you” can transform someone’s day—leave yours in the comments!

On DEV, knowledge sharing paves our journey and forges strong connections. Found this helpful? A simple thanks to the author means so much.

Get Started