How to declare conditional resource in serverless framework - serverless

I use typescript definition of serverless configuration (serverless.ts). How do I conditionally add resources using cloud formation templates ?
For example AWS cognito userpools, if I want to exclude these for offline mode, how can I specify it in serverless config file to not include them?

I solved it 2 ways. serverless-plugin-ifelse allowed me to exclude resources based on certain parameters.
Later I realized this may be problematic in the long run. So I created separate serverless config file for my offline use case to include all necessary resources. Prod/Staging environments used default serverless.ts file. Offline uses offline-serverless.ts file. Though there is some repetition of the resources config, this option ensures prod/staging config is not polluted with offline content. I could start offline using sls offline start --stage local --reloadHandler --config offline-serverless.ts
And the offline config reuses some code from main config. Sample offline-serverless.ts content is below:
import offlineplugins from "offlineplugins";
import pluginsconfig from "offlinepluginsconfig";
import plugins from "plugins";
const serverlessConfiguration: AWS = {
service: "my-offline-apis",
frameworkVersion: "3",
...pluginsconfig,
plugins: [...plugins, ...offlineplugins],
provider: {
name: "aws",
....
....

Related

How to service a Gatsby website with multiple domains and its contents?

I built a website using Gatsby, Contentful, and deployed on Netlify.
I am going to run this website with multiple domain aliases.
ex:
alias1.example.com
alias2.example.com
In that case, the aliases work well and the website have to show contents that belong to the own alias in Contentful.
For example, let's say the current alias is alias1, then the website have to fetch data only have alias1 entry from Contentful.
What I was trying is to add the codes to identify alias in gatsby-config.js using windows.location.href, and set siteUrl as dynamic, but it didn't work.
I am not sure it could be possible and how to implement it.
Thank you.
The best (and almost the only) approach to achieving this is to use an environment variables for each site/alias and configure the deploy command to trigger and use the variables for each site. In that way, each deploy will fetch the data from each Contentful environment.
In your gatsby-config.js (above the module exportation) add:
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
The next step is to create one environment file for each alias. In your project root:
.env.alias1
.env.alias2
Each file should contain your environment variables from Contentful:
CONTENTFUL_ACCESS_TOKEN:12345
CONTENTFUL_SPACE_ID:12345
Then, in your gatsby-config.js just replace your hardcoded variables for the ones in your environment files:
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
},
},
The last step is to configure the deploy scripts to trigger each desired alias. In your package.json:
"scripts": {
"clean": "gatsby clean",
"test": "jest",
"format": "prettier --write \"**/*.{js,jsx,json,md}\""
"develop-alias1": "gatsby develop GATSBY_ACTIVE_ENV=alias1"
"build-alias1": "gatsby build GATSBY_ACTIVE_ENV=alias1"
"develop-alias2": "gatsby develop GATSBY_ACTIVE_ENV=alias2"
"build-alias2": "gatsby build GATSBY_ACTIVE_ENV=alias2"
},
Note that you will replace the default gatsby develop and gatsby build for your aliased commands.
By adding this bunch of configuration, for each develop or build/deploy you are telling your Gatsby project to which environment file should look at (it will take your .env.alias* instead). Each file will contain the keys for each environment in Contentful with different content in it, allowing you to deploy aliased sites with different content using a unique CMS.
This might be the most critical problem of Gatsby, and almost people has hard time with it.
The core problem is the "browser environment" is not available when you "build" Gatsby project. And gatsby-config.js is used for NodeJS environment. In other words, everything sticked with window variable is not accessible.
You should read the offical docs about gatsby build process here:
https://www.gatsbyjs.com/docs/overview-of-the-gatsby-build-process/#build-time-vs-runtime.
Solution: you can define different "scripts" in package.json for each alias which you can provide environment variables for NodeJS environment. Then in gatsby-config.js, use dotenv package to read passed variables.
You can read more here about using environment variables: https://www.gatsbyjs.com/docs/environment-variables/#reach-skip-nav

Nuxt environment variables exposed in client when uploaded to Zeit/Now

I am deploying a Nuxt App with Zeit/Now. In the development phase I was using a .env file to store the secrets to my Contentful CMS, exposing the secrets to process.env with the nuxt-dotenv package. To do that, at the top of the nuxt.config I was calling require('dotenv').config().
I then stored the secrets with Zeit/Now and created a now.json to set them up for build and runtime like so:
{
"env": {
"DEMO_ID": "#demo_id"
},
"build": {
"env": {
"DEMO_ID": "#demo_id"
}
}
}
With that setup, the build was only working for the index page and all of the Javascript did not function. Only when I added the env-property to the nuxt.config.jsfile, the app started working properly on the Zeit-server.
require('dotenv').config()
export default {
...
env: {
DEMO_ID: process.env.DEMO_ID
},
...
modules: [
'#nuxtjs/dotenv'
],
...
}
BUT: When I then checked the uploaded Javascript files, my secrets were exposed, which I obviously don't want.
What am I doing wrong here? Thanks for your help.
You aren't necessarily doing anything wrong here, this is just how Nuxtjs works.
Variables declared in the env property are used to replace instances of process.env.MY_ENV, but because Nuxt is isomoorphic, this can be both on the server and client.
If you want these secrets accessible only on the server, then the easiest way to solve this is to use a serverMiddleware.
As serverMiddleware is decoupled from the main Nuxt build, env variables defined in nuxt.config.js are not available there.
This means your normal ENV variables should be accessible, since the server middleware are run on Node.
Obviously, this means these secrets won't be available client side, but this works if you have something like a Stripe secret key that you need to make backend requests with.
We had a similar problem in our project. Even, We created a nuxt project from scratch and checked to see if there was a situation we skipped. We noticed that, while nuxt building, it copies the .env variables into the utils.js in the nuxt folder. Through the document here, we changed the modules section in nuxt.config.js as follows,
modules: ['# nuxtjs / apollo', '# nuxtjs / axios', ['# nuxtjs / dotenv', { only: ['']}]],
Then we noticed that .env variables are not exposed.
I hope it helped.
Our nuxt version is "nuxt": "^ 2.13.0".
Also, some discussion over here.

VueJS & Webpack: ENV var unaccessible from built project

I'm working on an app with vuejs frontend and nodejs backend. My frontend makes API https requests to the backend. I've started my projet with vue-cli and webpack.
I need to get the backend API url from env variable (BACKEND_URL).
Since i'm using webpack, I added this line to config/prod.env.js :
module.exports = {
NODE_ENV: '"production"',
-> BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
It works flawlessly in dev mode using webpack-dev-server. I pass the env var throught docker-compose file:
environment:
- BACKEND_URL=https://whatever:3000
But when I run build, I use nginx to serve the static files (but the problem is the same using visual studio code live server extension). I send BACKEND_URL env var the same way as before. The thing is now the process.env.BACKEND_URL is undefined in the app (but defined in the container)!! So I cant make backend http calls :(
I'm struggling finding the problem, please don't be rude with the responses. Thank you
They aren not "translated" during build time, this is what is happening with you. On a node environment, when you ask for process.env it will show all environment variables available in the system, that is true. But a web application does not have access to process.env when it is executing. You need a way to translate them during build time.
To achieve that you have to use DefinePlugin. It translates anything during build time and writes a magical string where this other thing was.
Using you own example:
module.exports = {
NODE_ENV: '"production"',
BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
If you do this during build time, without DefinePlugin, webpack won't know what to do with it, and it is going to be a simple string.
If you use DefinePlugin:
new webpack.DefinePlugin({
"process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL)
});
By doing this, you are allowing webpack to translate this during build time.
Give this a shot: https://www.brandonbarnett.io/blog/2018/05/accessing-environment-variables-from-a-webpack-bundle-in-a-docker-container/
If I'm understanding your problem correctly, you're serving a webpack bundle using nginx, and trying to access an environment variable from that bundle.
Unfortunately, it doesn't quite work that way. Your JS file has no access to the environment since it's a resource that has been delivered to the client. I've proposed a solution that also delivers those env variables alongside the bundle in a separate JS file that gets created on container start.
From VueJS Docs: https://cli.vuejs.org/guide/mode-and-env.html
Using Env Variables in Client-side Code
Only variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. You can access them in your application code:
console.log(process.env.VUE_APP_SECRET)
During build, process.env.VUE_APP_SECRET will be replaced by the corresponding value. In the case of VUE_APP_SECRET=secret, it will be replaced by "secret".
So in your case, the following should do the trick. I had the same problem once in my project, which I started with vue/cli and vue create project ...
VUE_APP_BACKEND_URL=https://whatever:3000

How to read in other config information into a dropwizard service

I am building a dropwizard service which will connect to multiple data sources including mySQL and Elasticsearch. All the mySQL settings can be defined in the yaml config file which gets read in after running from the commandline.
But what about other settings that I need to read in for other data sources that I will connect with myself, for example Elasticsearch? Where can I define those settings?
I thought I could add another commandline Command - which I tried, but I can only run a single command (from the commandline) at a time - so I can't seem to run both the 'server' command as well as my custom command, 'custom' which is followed by the my own config file for elasticsearch.
How can I introduce settings either individually or from a file - which are defined at run time (not hard coded)?
Thanks
Anton
Check out the Dropwizard Core documentation on adding custom configuration.
You'd create an ElasticSearchFactory class similar to the MessageQueueFactory in the example, reference this in your Configuration (that's in turn referenced in your Application), and then the options you need can be added to your main yaml configuration.

Grails 3 plugins configuration

New to Grails 3- starting to port.
Have tried placing config values in application.groovy and application.yml within plugin conf dir to no avail - trying to read values from within plugin service fails. Adding values to the main application's application.groovy works.
What is the secret here? Previously I could load specific conf files via config.locations simply by naming them which was nice and simple. I've seen some resolutions that include needing to setup env vars with paths to config files which I'd like to avoid. Then they set up file URIs for dev and classpath URIs for other envs that will be war packaged - don't really want to do any of this.
Do we no longer have the ability to place config within a plugin and have that automatically merged with the applications config?
The plugin may provide config settings in grails-app/conf/plugin.yml.

Resources