I'm facing an issue with using environment variables in a static Vue Quasar app hosted on S3 and CloudFront.
While I do understand that static websites shouldn't include environment variables, I'm required to keep hosting with S3 and Cloudfront and I still need some keys (like the API base URL
, etc.) in the source code.
Although I've successfully removed sensitive keys (e.g., secret and access keys) and found proper workarounds to handle them, I'm still looking for a robust solution to manage key values, like the API base URL, that works conveniently across different environments.
If you have ever had similar problems, I hope to receive your help.
I'm facing an issue with using environment variables in a static Vue Quasar app hosted on S3 and CloudFront.
While I do understand that static websites shouldn't include environment variables, I'm required to keep hosting with S3 and Cloudfront and I still need some keys (like the API base URL
, etc.) in the source code.
Although I've successfully removed sensitive keys (e.g., secret and access keys) and found proper workarounds to handle them, I'm still looking for a robust solution to manage key values, like the API base URL, that works conveniently across different environments.
If you have ever had similar problems, I hope to receive your help.
Share Improve this question asked Feb 3 at 10:15 Nguyen Quoc BaoNguyen Quoc Bao 578 bronze badges 2 |1 Answer
Reset to default 1There would be a way to inject environment variables dynamically in a web app to keep the same build across environments, and that is the cleanest approach I found so far. It's a bit complex but if you're motivated, the following solution is using CloudFront Functions with CloudFront KeyValueStore (KVS) and secured session cookie.
Create a new CloudFront function
- Name
myEnvVariablesFunction
- Select cloudfront-js-2.0 to be able to access to KVS.
- Name
On the next page, you can click on Create new KeyValueStore
- Name
myEnvVariablesKVS
- You don't need to store in a
S3
bucket, you can click onCreate
button directly
- Name
Once
myEnvVariablesKVS
is created, you can add following examples by clicking onAdd key value pairs
and thenAdd pair
:- Key: d123.cloudfront - Value: { "env": "test", "backend": "https://test-mybackend", "videos": "https://test-third-party-videos" }
Note: Don't fet to click on the little check button or press "Enter" before going to the next field. Then you can
Edit
and add another example:- Key: dmycloudfrontprodid.cloudfront - Value: { "env": "prod", "backend": "https://prod-mybackend", "videos": "https://prod-third-party-videos" }
Note: Update
Key
with your distribution domain, otherwise you will end up with a503
error page.Click on Go to functions and open
myEnvVariablesFunction
functionClick on
Associate existing KeyValueStore
and selectmyEnvVariablesKVS
Below on the
Build
/Development
tab you can paste following code:import cf from 'cloudfront'; async function handler(event) { const kvsHandle = cf.kvs(); const domain = event.context.distributionDomainName; var response = event.response; var cookies = response.cookies; let dataEnv; try { const value = await kvsHandle.get(domain); dataEnv = JSON.parse(value); } catch (err) { const errorMessage = `Error reading ${domain}: ${err}`; console.log(errorMessage); return { statusCode: 500, statusDescription: 'Error', body: { encoding: 'text', message: errorMessage } }; } if (!cookies) { cookies = []; } const keys = Object.keys(dataEnv); for (var i = 0; i < keys.length; i++) { cookies[`${keys[i]}`] = { "value": `${dataEnv[keys[i]]}`, "attributes": "Secure; Path=/" } } return response; }
On the
Test
tab, you can- Select
Viewer response
in theEvent type
dropdown - Click on
Test function
- Validate on the
Execution result
on the bottom that the test ran successfully
- Select
Go on
Publish
tab- Click on the
Publish function
button - Click on the
Add association
button- Distribution: Select your distribution
- Event type: Select
Viewer response
- Cache behavior: Select the
Default (*)
one Note: This setting is the same as going directly in your distribution configuration /Behaviors
/ Edit default behavior / and on theViewer response
in the bottom selectmyEnvVariablesFunction
- Click on the
Add assocation
button
- Click on the
One you're done, you should be able to load your site with cookies containing your Frontend environment variables, here backend
, env
and videos
.
On the Frontend side, you can get your cookies values from anywhere in your application with some parsing like:
document.cookie.split('; ').find((row) => row.startsWith('backend='))?.split('=')[1];
If you want to update any values in KVS, you can do the update, save and you should be able to have your changes available in a minute or so without any cache clearing.
Some documentation:
- Official Amazon CloudFront KeyValueStore documentation
- CloudFront KeyValueStore introduction in December 12, 2023 with a demo of URL redirection
- Another demo for a URL shortener
access key, secret key, bucket name
to push a file (image, video) directly to S3 bucket.A wysiwwyg editor API key
, and some base Urls. I have developed some endpoints to replace the direct file push, using another editor instead of the editor that needs API key. However now I still need to figure out how to handle the keys related to Base url. – Nguyen Quoc Bao Commented Feb 4 at 1:43