This package handles the projects secrets and gets the secrets from either an .env file or from secrets manager in aws. It means that all projects should use this package in case any day it will be deployed on AWS.
- Install the package and follow conventions
- In setEnv import getSecrets function and give it your secret config object. (see example below). setEnv should be called from main.ts as earlier as posible.
- in project, secrets are retrieved from privateSecret object.
$ npm i @hilma/secrets-handler
For all projects we save all secrets in "AWS secrets manager" service. For each project there can be multiple types of secrets:
connectors: credentials for all type of databases (mysql, mongodb,...)
Singleton: used for secrets that are not related to dbs, like secret APIs (ie: Google API)
Preknowns: for secrets that are preknown, but should be in the privateSecret object (also supports functions that will get executed during the secrets retrieval)
pass019 : to get our common secret for all projects on sms 019 service
In nestjs, typeorm needs a number of variables related to the connection (host, port, credentials). These variables should be named in the .env file as follows:
XXX_HOST for hostname
XXX_PORT for port
XXX_PASSWORD for password
XXX_ENGINE for engine type (mysql, mongodb
XXX_USER for user name
XXX_SECRET_NAME for name of this secret in aws (ie: project_secret_mysql1)
Where XXX takes a value (ie: DB (for mysql primary db), MDB (for mongo), DW (for datawarehouse).
XXX value is the ALIAS value that will be decribed later in the document
SINGLETON_SECRET_NAME should be defined in your .env file (ie: Myproject_singleton) in production when using aws secrets manager.
On projects that do not use aws secrets manager or in development mode, .env file should contain all the secrets that are passed in the envNameArr variable, (.ie GOOGLE_TOKEN='...').
PASS019= path of file with pass019 password, should be defined in you.env file.
(Not necessary when using aws secrets manager.)
key/s | value/ typeof value | what for |
---|---|---|
name required |
string | the name refering to the object in the code. privateSecret[name] ie: name= mysql1 |
alias required |
string | short string that precedes env variables names. ex: DB_NAME and DB_SECRET_NAME - "DB" is the alias |
port, engine, host, dbname, username, pasword optional |
string / number | hard coded data for your db connection to override env. This is optional and unlikely to be used |
key/s | value/ typeof value | what for |
---|---|---|
name required |
string | the name refering to the object in the code. privateSecret[name] ie: name= globalsecrets |
envNameArr required |
string array | array containing names of the wanted variables from the .env file ie: [GOOGLE_MAP_KEY, GOOGLE_PHOTOS_KEY] |
key/s | value/ typeof value | what for |
---|---|---|
name required |
string | the name refering to the object in the code. privateSecret[name] |
alias required |
string | short string that precedes env variables names. ex: DB_NAME and DB_SECRET_NAME - "DB" is the alias |
value required |
object. key: string, value: any. | for secrets that do not have data in the env file. |
boolean (true, false)
import { connectorSecret, getSecretsParams } from "@hilma/secrets-handler";
import getSecrets from "@hilma/secrets-handler";
export let privateSecret: {
mysqlSecret?: connectorSecret;
DWSecret?: connectorSecret;
global?: {
GOOGLE_MAP_KEY: string;
GOOGLE_PHOTOS_KEY: string;
};
pass019?: string;
};
let param: getSecretsParams = {
connectors: [{
name: "mysqlSecret",
alias: 'DB'
}, {
name: "DWSecret",
alias: 'DW'
}],
singleton: {
name: "global",
envNameArr: ["GOOGLE_MAP_KEY", "GOOGLE_PHOTOS_KEY"]
},
pass019: true
}
export const setEnv = async () => {
privateSecret = await getSecrets(param);
};
DB_USER='root'
DB_HOST='localhost'
DB_NAME='dbname'
DB_PASSWORD='z10mz10m'
DW_USER='root'
DW_HOST='localhost'
DW_NAME='dwname'
DW_PASSWORD='z10mz10m'
GOOGLE_MAP_KEY='blabla'
GOOGLE_PHOTOS_KEY='true'
PASS019='./pass019.txt'
USE_AWS=true
AWS_REGION=eu-west-1
SINGELTON_SECRET_NAME='secret-name-in-aws'
DB_SECRET_NAME='production_db_mysql'
DW_SECRET_NAME='production_dw_mysql'
in app module change forRoot => forRootAsync example:
import { privateSecret } from "./setEnv";
....
@Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: async () => {
return {
type: "mysql",
host: privateSecret.mysqlSecret.dbname,
port: Number(privateSecret.mysqlSecret.port),
database: privateSecret.mysqlSecret.dbname,
username: privateSecret.mysqlSecret.username,
password: privateSecret.mysqlSecret.password,
ssl: process.env.DB_SSL === 'true' ? true : false,
synchronize: process.env.DB_SYNC === 'true' ? true : false,
// logging: true,
extra: {
charset: "utf8mb4_unicode_ci"
},
entities: [
"dist/**/*{.ts,.js}",
"node_modules/@hilma/auth-nest/dist/**/*.entity{.ts,.js}"
]
}
}
}),