Presenting PageMyCV - Resume Website in one Click (using Pulumi ESC)
This is a submission for the Pulumi Deploy and Document Challenge: Shhh, It's a Secret! Managing secrets like API Keys and Configuration in any application is not just crucial from security point of view but also essential for boosting maintainability of the application. These secrets can grow to a huge number as your application extend. This is the reason you need a reliable Secret Management Service like Pulumi ESC. In this article you will learn the importance of managing application secrets and I will introduce you to my project PageMyCV which uses Pulumi ESC to store and retrieve API Keys and Configurations. Project Repo vivekthedev / pagemycv PageMyCV PageMyCV is a Flask-based web application that transforms a PDF resume into a professional-looking online portfolio page. Users can upload their resume, and the app automatically extracts key details using Google GenAI and hosts the final webpage via AWS S3 and CloudFront. Features Upload a PDF resume via the web interface Extract structured information using Google GenAI Generate a clean HTML portfolio using Jinja templates Automatically host the portfolio using AWS S3 and CloudFront Uses Pulumi ESC for managing secure environment variables Tech Stack Python + Flask – Web server and routing Fitz (PyMuPDF) – PDF text extraction Google GenAI – Resume data extraction Pulumi ESC SDK – Environment configuration AWS S3 + CloudFront – Static site hosting Boto3 – AWS SDK for Python Prerequisites Python 3.8 or higher Google GenAI API Key AWS Account with: S3 Bucket CloudFront distribution Pulumi ESC configured with the required environment values Setting… View on GitHub Live Link Try for yourself Working Demo My Journey The idea of making this application struck me when I was creating my own Developer site using Pelican. I noticed I am copying and pasting a lot of stuff from my Resume which felt repetitive and inefficient and decided to build an application which takes my resume, extract all the key details and renders a HTML page which I can host on Github Pages or any other static web page hosting service. And that’s how PageMyCV was born. I’ve tried to make this as simple as possible. All the user needs is a resume, regardless of the industry. The app picks up on the common details that are usually present across most fields and builds the page from there. How it Works When a user visits the web interface, they are prompted to upload their resume in PDF format. Once submitted, the app reads the file using fitz (PyMuPDF), a lightweight and efficient library for parsing PDF documents. This step extracts all textual content from the uploaded resume. The raw text is then passed to Google’s GenAI API. We use a structured function calling mechanism to instruct the model on exactly what data we want extracted—such as the user's name, email, education, work history, technical skills, project details, and notable achievements. The model returns this data in a structured JSON format, which the app then uses to populate a pre-designed HTML template. After the HTML page is rendered, it's uploaded to an AWS S3 bucket. We use the boto3 library to handle this interaction programmatically. Once the file is successfully stored in S3, it is served to the public via a CloudFront distribution. The user is then redirected to their unique CloudFront URL where their new online portfolio is instantly available. Earlier, the project used Pydotenv to manage secrets, which made it so much inefficient. What if I want to rotate API_KEYs? Change Bucket Name or Use to different CloudFront Domain? Pain Points of Traditional Approach Managing configuration manually quickly becomes cumbersome. Storing sensitive values like API keys in plain text opens the door to accidental leaks. The developer might accidently commit .env files and your Configuration are publically exposed. Using Pulumi ESC Tools like Pulumi ESC are built to solve these exact problems. They allow you to securely manage secrets. A user can easily manage several configurtion in the same application just by switching environment which removes the need to manually changing model names to check the response when building AI applications. To begin, you’ll need to install the ESC CLI on your machine. This CLI allows you to create, view, and update your environments with ease. Once installed, authentication is handled through a single environment variable: PULUMI_ACCESS_TOKEN. This token gives your CLI access to your Pulumi organization and its managed environments. What used to be a clutter of 4–5 separate environment variables that had to be manually exported or managed in .env files, is now reduced to just one. Resources https://www.pulumi.com/docs/esc/download-install/ https://www.pulumi.com/do
This is a submission for the Pulumi Deploy and Document Challenge: Shhh, It's a Secret!
Managing secrets like API Keys and Configuration in any application is not just crucial from security point of view but also essential for boosting maintainability of the application. These secrets can grow to a huge number as your application extend. This is the reason you need a reliable Secret Management Service like Pulumi ESC.
In this article you will learn the importance of managing application secrets and I will introduce you to my project PageMyCV which uses Pulumi ESC to store and retrieve API Keys and Configurations.
Project Repo
PageMyCV
PageMyCV is a Flask-based web application that transforms a PDF resume into a professional-looking online portfolio page. Users can upload their resume, and the app automatically extracts key details using Google GenAI and hosts the final webpage via AWS S3 and CloudFront.
Features
- Upload a PDF resume via the web interface
- Extract structured information using Google GenAI
- Generate a clean HTML portfolio using Jinja templates
- Automatically host the portfolio using AWS S3 and CloudFront
- Uses Pulumi ESC for managing secure environment variables
Tech Stack
- Python + Flask – Web server and routing
- Fitz (PyMuPDF) – PDF text extraction
- Google GenAI – Resume data extraction
- Pulumi ESC SDK – Environment configuration
- AWS S3 + CloudFront – Static site hosting
- Boto3 – AWS SDK for Python
Prerequisites
- Python 3.8 or higher
- Google GenAI API Key
- AWS Account with:
- S3 Bucket
- CloudFront distribution
- Pulumi ESC configured with the required environment values
Setting
…Live Link
Working Demo
My Journey
The idea of making this application struck me when I was creating my own Developer site using Pelican. I noticed I am copying and pasting a lot of stuff from my Resume which felt repetitive and inefficient and decided to build an application which takes my resume, extract all the key details and renders a HTML page which I can host on Github Pages or any other static web page hosting service. And that’s how PageMyCV was born.
I’ve tried to make this as simple as possible. All the user needs is a resume, regardless of the industry. The app picks up on the common details that are usually present across most fields and builds the page from there.
How it Works
When a user visits the web interface, they are prompted to upload their resume in PDF format. Once submitted, the app reads the file using fitz (PyMuPDF), a lightweight and efficient library for parsing PDF documents. This step extracts all textual content from the uploaded resume.
The raw text is then passed to Google’s GenAI API. We use a structured function calling mechanism to instruct the model on exactly what data we want extracted—such as the user's name, email, education, work history, technical skills, project details, and notable achievements. The model returns this data in a structured JSON format, which the app then uses to populate a pre-designed HTML template.
After the HTML page is rendered, it's uploaded to an AWS S3 bucket. We use the boto3 library to handle this interaction programmatically. Once the file is successfully stored in S3, it is served to the public via a CloudFront distribution. The user is then redirected to their unique CloudFront URL where their new online portfolio is instantly available.
Earlier, the project used Pydotenv to manage secrets, which made it so much inefficient. What if I want to rotate API_KEYs? Change Bucket Name or Use to different CloudFront Domain?
Pain Points of Traditional Approach
Managing configuration manually quickly becomes cumbersome. Storing sensitive values like API keys in plain text opens the door to accidental leaks. The developer might accidently commit .env files and your Configuration are publically exposed.
Using Pulumi ESC
Tools like Pulumi ESC are built to solve these exact problems. They allow you to securely manage secrets. A user can easily manage several configurtion in the same application just by switching environment which removes the need to manually changing model names to check the response when building AI applications.
To begin, you’ll need to install the ESC CLI on your machine. This CLI allows you to create, view, and update your environments with ease. Once installed, authentication is handled through a single environment variable: PULUMI_ACCESS_TOKEN. This token gives your CLI access to your Pulumi organization and its managed environments.
What used to be a clutter of 4–5 separate environment variables that had to be manually exported or managed in .env files, is now reduced to just one.
Resources
- https://www.pulumi.com/docs/esc/download-install/
- https://www.pulumi.com/docs/pulumi-cloud/access-management/access-tokens/#creating-personal-access-tokens
In Pulumi ESC all the magic happens in esc environments. Each environment holds a separate set of variables required by your application.
To create a new environment run the following in terminal:
esc env init default/myapp
This will create a new environment named myapp
in default namespace. Since you can manage multiple environment you can type the below command to list all the environments:
> esc env ls
default/myapp
In order to create a new variable in this enviroment run the following command:
> esc env set default/myapp varNmae varValue
Note that the above command would only set the variable but to make it available you need to edit the conf file using:
esc env edit default/myapp
Running the above command would open a YAML file. Add the following text at the end of values
block to make your variables accessible in the applicaiton.
environmentVariables:
varName: ${varName}
To test this you can run the following command:
> esc env run default/myapp -- python -c "import os; print(os.getenv('varName'))"
varValue
In the above command you ran the python code with myapp environment. esc handled all the environment variables set up for you. In the above output you can see "varValue" was returned by our Python code.
This is how Pulumi ESC made my environment management part easy. In my application I have stored MODEL, API_KEY, BUCKET, AND CLOUDFRONT configuration which was easily managed by Pulumi ESC.
Takeaway
Using Pulumi ESC helped me move away from scattered .env files to a cleaner, safer setup. With one access token, I could securely manage secrets across multiple environments.