Where to put "useDotenv: true" in serverless.yml file? - serverless-framework

I was using serverless templates and all worked fine until suddenly all my deployments started ignoring .env files.
I searched through the documentation and it says that if I want to use the environment variables from .env files I now have to add useDotenv: true in my serverless.yml file. So I did:
app: xxx
org: xxx
useDotenv: true
There was no effect.
My serverless.yml file contained nothing else before but the app and org variables.
Where do I need to add the seDotenv: true in order to make it read my .env variables?

You should put it at the root of your serverless.yml file.
I have mine just after the service attribute :
service: lb-courses
useDotenv: true
plugins:
- serverless-offline
...

Related

Why is runtimeConfig doesn't see environment variables in Nuxt 3?

I do yarn build without the .env file
Add the .env file to the project
I do yarn start.
Print the useRuntimeConfig().public.baseURL to the console and get undefined.
Why is runtime not tracking my environment variables?
.env
NUXT_PUBLIC_BASE_URL=https://example.com/api/v1
nuxt.config.js
export default defineNuxtConfig({
runtimeConfig: {
public: {
baseUrl: ''
}
},
plugins/app.js
export default defineNuxtPlugin(() => {
console.log('baseURL', useRuntimeConfig().public.baseURL
})
From the documentation page:
However, after your server is built, you are responsible for setting environment variables when you run the server. Your .env file will not be read at this point. How you do this is different for every environment. On a Linux server, you could pass the environment variables as arguments using the terminal DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs. Or you could source your env file using source .env && node .output/server/index.mjs.
Note that for a purely static site, it is not possible to set runtime configuration config after your project is prerendered.
So, source .env && yarn start should do it.
You might check the version of nuxt.
If it's the bridge version, runtimeConfig cannot work.
Cause I use #nuxt/bridge, not work.
and then it worked on the 3.0.0-rc.3 version. I've tried.
baseUrl: process.env.NUXT_PUBLIC_BASE_URL
try it that way. what you do is setting it explicitly to a empty string.

Spread all dotenv keys and values to process.env without having to define it one by one in serverless.yml

I am using node & expressjs as an app. I have problem in deploying it to serverless with dotenv (without using any dotenv plugin).
My serverless.yml is this:
functions:
server:
handler: index.server
events:
- http: ANY /
- http: "ANY /{proxy+}"
environment:
ENV_VAR1: ${env:ENV_VAR1}
and my .env.staging is this:
ENV_VAR1='ENV_VAR1 using .env.staging'
ENV_VAR2='ENV_VAR2 using .env.staging'
I use AWS Lambda and deploy it using sls deploy --stage staging. So far I can read the ENV_VAR1from .env.staging by calling process.env.ENV_VAR1 because I explicitly define it in the serverless.yml file. But that's not the case with ENV_VAR2.
My question is, how to load all the .env.{stage} file without defining the key one by one?
I hope to load it similar to something like this:
environment: ${file(.env.${self:stage})}
Thank you in advance.
As I know, there is no way, you'll have to do it one by one (you have to have an object with key-value pairs inside environment, but you are trying to give it a string - even if it is going to be interpreted as a file containing something, it is still a string when you are referencing it).
I'm not an expert, so there still might be some tricks.

VueJS place multiple .env in folder

Hello I'm using VueJS 2 and I have multiple .env in my project.
My app have .env for each company to select the company configuration (skin color / files...)
Actually I have all my .env in the root folder:
.env.company1-dev
.env.company1-staging
.env.company1-prod
.env.company2-dev
.env.company2-staging
.env.company2-prod
.env.company3-dev
.env.company3-staging
.env.company3-prod
So when I'll get 20 companies it will be confused on my root folder so it is possible to create a folder where I can place all my .env ?
The idea :
/environments/company1/
.env.dev
.env.staging
.env.prod
/environments/company2/
.env.dev
.env.staging
.env.prod
/environments/company3/
.env.dev
.env.staging
.env.prod
On your vue.config.js file you can add:
const dotenv = require("dotenv");
const path = require("path");
let envfile = ".env";
if (process.env.NODE_ENV) {
envfile += "." + process.env.NODE_ENV;
}
const result = dotenv.config({
path: path.resolve(`environments/${process.env.VUE_APP_COMPANY}`, envfile)
});
// optional: check for errors
if (result.error) {
throw result.error;
}
the before run you can set VUE_APP_COMPANY to a company name and run your app,
Note: It's important to put this code on vue.config.js and not in main.js because dotenv will use fs to read files.
References
https://github.com/motdotla/dotenv#path
https://github.com/vuejs/vue-cli/issues/787
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
The accepted answer we have also used in the past. But I found a better solution to handle different environments. Using the npm package dotenv-flow allows not only the use of different environments but has some more benefits like:
local overwriting of variables by using .env.local or .env.staging.local and so on
definition of defaults using .env.defaults
In combination we have set up our projects with this configuration:
.env
.env.defaults
.env.development
.env.production
.env.staging
.env.test
And the only thing you have to do in your vue.config.js, nuxt.config.js or other entry points is
require('dotenv-flow').config()
Reference: https://www.npmjs.com/package/dotenv-flow
The powershell solution
I was handling exactly the same problem. Accepted solution is kind of ok, but it did not solve all differences between companies. Also, if you are using npm, your scripts can look nasty. So if you have powershell, here is what I suggest - get rid of the .env files :)
You can keep your structure like you want in the question. Just convert the env files to ps1.
/build/company1/
build-dev.ps1
build-stage.ps1
build-prod.ps1
/build/company2/
build-dev.ps1
build-stage.ps1
build-prod.ps1
Inside each of those, you can fully customize all env variables, run build process and apply some advanced post-build logic (like careful auto-deploy, publishing, merging with api project, ..).
So for example company1\build-stage.ps1 can look like this:
# You can pass some arguments to the script
param (
[string]$appName = "company1"
)
# Set environment variables for vue pipeline
$env:VUE_APP_ENVIRONMENT = "company1-stage";
$env:NODE_ENV="development";
$env:VUE_APP_NAME=$appName;
$env:VUE_APP_API_BASE_URL="https://company1.stage.mycompany.com"
# Run the vue pipeline build
vue-cli-service build;
# Any additional logic e.g.
# Copy-Item -Path "./dist" -Destination "my-server/my-app" -Recurse¨
Last part is easy - just call it (manualy or from integration service like TeamCity). Or, you can put it inside package.json.
...
"scripts": {
"build-company1-stage": "#powershell -Command ./build/company1/build-stage.ps1 -appName Company-One",
}
...
The you can call whole build process just by calling
npm run build-company1-stage
Similary, you can create localhost, dev, prod, test and any other environment. Let the javascript handle the part of building the app itself. For other advanced work, use poweshell. I think that this solution gives you much more flexibility for configuration and build process.
P.S.
I know that this way I'm merging configuration and build process, but you can always extract the configuration outside the file if it gets bigger.

Serverless: Importing file to custom + other variables

I have a serverless.common.yml, with properties that should be shared by all the services, with that:
service: ixxxx
custom:
stage: ${opt:stage, self:provider.stage}
resourcesStages:
prod: prod
dev: dev
resourcesStage: ${self:custom.resourcesStages.${self:custom.stage}, self:custom.resourcesStages.dev}
lambdaPolicyXRay:
Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource: "*"
And, another serverless.yml inside a services folder, which uses properties on the common file:
...
custom: ${file(../../serverless.common.yml):custom}
...
environment:
stage: ${self:custom.stage}
...
In that way, I can access the custom variables (from the common file) without a problem.
Now, I want to continue to import this file to custom, but adding new variables, related to this service, to it, so I tried that:
custom:
common: ${file(../../serverless.common.yml):custom}
wsgi:
app: app.app
packRequirements: false
pythonRequirements:
dockerizePip: non-linux
And it seems it's possible to access, for example:
environment:
stage: ${self:custom.common.stage}
But now, I'm receiving the error:
Serverless Warning --------------------------------------
A valid service attribute to satisfy the declaration 'self:custom.stage' could not be found.
Serverless Warning --------------------------------------
A valid service attribute to satisfy the declaration 'self:custom.stage' could not be found.
Serverless Error ---------------------------------------
Trying to populate non string value into a string for variable ${self:custom.stage}. Please make sure the value of the property is a strin
What am I doing wrong?
In your serverless.common.yml you must reference as if it were serverless.yml. In this case ${self:custom.stage} does not exist, but ${self:custom.common.stage} does exist.
service: ixxxx
custom:
stage: ${opt:stage, self:provider.stage}
resourcesStages:
prod: prod
dev: dev
resourcesStage: ${self:custom.common.resourcesStages.${self:custom.common.stage}, self:custom.resourcesStages.dev}
lambdaPolicyXRay:
Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource: "*"

set rails fog gem application.yml keys for development environment

I'm using paperclip, fog, figaro gems to upload images to amazon S3. In production works fine as I introduced the env variables in heroku by hand.
But in development, it is suposed to use the env from the aplication.yml file (added to .gitignore). It is not using this file, as in development the ENV[] placed in application.yml do not exist.
I followed several tutorial for this, and in all of them I understand that the ENV[] introduced in applicaction.yml should be used. Am I wrong? Am I missing something? Do I need something else? I read that I can introduce the ENV[] by hand typing export, but I need to know if it is not enough to write them down at application.yml
#config/application.yml
MAPS_API_KEY: 1234googlemapapikey56788
SECRET_KEY_BASE: ab1234567longkeyy2979127401411124
AWS_ACCES_KEY_ID: ACCESSKEYID1234567
AWS_SECRET_ACCESS_KEY: SECRETKEY123456788/jaa\12345
AWS_REGION: eu-west-1
S3_HOST_NAME: s3-eu-west-1.amazonaws.com
development:
FOG_DIRECTORY: example-dev
S3_BUCKET_NAME: example-dev
production:
FOG_DIRECTORY: example-production
S3_BUCKET_NAME: example-production
in development and production I use the same code:
#config/environments/development.rb && config/environments/production.rb
config.paperclip_defaults = {
storage: :s3,
s3_credentials: {
bucket: ENV.fetch('S3_BUCKET_NAME'),
access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
s3_region: ENV.fetch('AWS_REGION'),
}
}
In production works fine, and in development I get errors like:
development.rb:54:in `fetch': key not found: "AWS_ACCESS_KEY_ID" (KeyError)
# config/initializers/paperclip.rb
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
The config/application.yml you list above has a typo.
The key you want is AWS_ACCESS_KEY_ID, but the copied file uses AWS_ACCES_KEY_ID (where access is missing the second s).
I suspect that should get things working for you again.