diff --git a/API.md b/API.md
index 9e6ec47..d1061c1 100644
--- a/API.md
+++ b/API.md
@@ -1147,47 +1147,47 @@ public readonly repositoryVersion: string;
## Enums
-### TagsKey
+### TagsKey
#### Members
| **Name** | **Description** |
| --- | --- |
-| ENVIRONMENT
| *No description.* |
-| TIMESTAMP_DEPLOY_CDK
| *No description.* |
-| BUSINESS_UNIT
| *No description.* |
-| DOMAIN
| *No description.* |
-| REPOSITORY_NAME
| *No description.* |
-| REPOSITORY_VERSION
| *No description.* |
+| ENVIRONMENT
| *No description.* |
+| TIMESTAMP_DEPLOY_CDK
| *No description.* |
+| BUSINESS_UNIT
| *No description.* |
+| DOMAIN
| *No description.* |
+| REPOSITORY_NAME
| *No description.* |
+| REPOSITORY_VERSION
| *No description.* |
---
-##### `ENVIRONMENT`
+##### `ENVIRONMENT`
---
-##### `TIMESTAMP_DEPLOY_CDK`
+##### `TIMESTAMP_DEPLOY_CDK`
---
-##### `BUSINESS_UNIT`
+##### `BUSINESS_UNIT`
---
-##### `DOMAIN`
+##### `DOMAIN`
---
-##### `REPOSITORY_NAME`
+##### `REPOSITORY_NAME`
---
-##### `REPOSITORY_VERSION`
+##### `REPOSITORY_VERSION`
---
diff --git a/src/common/env.ts b/src/common/env.ts
index a75194e..0e9276a 100644
--- a/src/common/env.ts
+++ b/src/common/env.ts
@@ -1,4 +1,6 @@
/* eslint-disable @typescript-eslint/no-shadow */
+export const CDK_REGION = process.env.CDK_DEFAULT_REGION ?? '';
+export const CDK_ACCOUNT_ID = process.env.CDK_DEFAULT_ACCOUNT ?? '';
export const ENVIRONMENT = process.env.ENVIRONMENT ?? '';
export const BUSINESS_UNIT = process.env.BUSINESS_UNIT ?? '';
export const DOMAIN = process.env.DOMAIN ?? '';
@@ -6,13 +8,4 @@ export const REPOSITORY_NAME = process.env.REPOSITORY_NAME ?? '';
export const REPOSITORY_VERSION = process.env.REPOSITORY_VERSION ?? '';
let timestamp = new Date();
-export const TIMESTAMP_DEPLOY_CDK = `${timestamp.getFullYear().toString()}/${timestamp.getMonth().toString()}/${timestamp.getDay().toString()} H:${timestamp.getHours().toString()}`;
-
-export enum TagsKey {
- ENVIRONMENT='Environment',
- TIMESTAMP_DEPLOY_CDK='TimestampDeployCDK',
- BUSINESS_UNIT='BusinessUnit', // Indicates which business unit competes for the service released on aws
- DOMAIN='Domain', // Indicates the domain in which the service operates
- REPOSITORY_NAME='RepositoryName', // Indicates in which repository the released code is contained
- REPOSITORY_VERSION='RepositoryVersion', // Indicates which version of the code was released (can be a tag or a commit hash)
-}
\ No newline at end of file
+export const TIMESTAMP_DEPLOY_CDK = `${timestamp.getFullYear().toString()}/${timestamp.getMonth().toString()}/${timestamp.getDay().toString()} H:${timestamp.getHours().toString()}`;
\ No newline at end of file
diff --git a/src/common/utils.ts b/src/common/utils.ts
index 6ccbbfa..1c4910f 100644
--- a/src/common/utils.ts
+++ b/src/common/utils.ts
@@ -8,27 +8,36 @@ export interface BaseTagProps {
readonly repositoryVersion?: string;
}
+export enum TagsKey {
+ ENVIRONMENT='Environment',
+ TIMESTAMP_DEPLOY_CDK='TimestampDeployCDK',
+ BUSINESS_UNIT='BusinessUnit', // Indicates which business unit competes for the service released on aws
+ DOMAIN='Domain', // Indicates the domain in which the service operates
+ REPOSITORY_NAME='RepositoryName', // Indicates in which repository the released code is contained
+ REPOSITORY_VERSION='RepositoryVersion', // Indicates which version of the code was released (can be a tag or a commit hash)
+}
+
export function addBaseTags(module: any, props?: BaseTagProps) {
- Tags.of(module).add(env.TagsKey.ENVIRONMENT, env.ENVIRONMENT);
- Tags.of(module).add(env.TagsKey.TIMESTAMP_DEPLOY_CDK, env.TIMESTAMP_DEPLOY_CDK);
+ Tags.of(module).add(TagsKey.ENVIRONMENT, env.ENVIRONMENT);
+ Tags.of(module).add(TagsKey.TIMESTAMP_DEPLOY_CDK, env.TIMESTAMP_DEPLOY_CDK);
let businessUnit = props?.businessUnit ?? env.BUSINESS_UNIT;
if (businessUnit) {
- Tags.of(module).add(env.TagsKey.BUSINESS_UNIT, businessUnit);
+ Tags.of(module).add(TagsKey.BUSINESS_UNIT, businessUnit);
}
let domain = props?.domain ?? env.DOMAIN;
if (domain) {
- Tags.of(module).add(env.TagsKey.DOMAIN, domain);
+ Tags.of(module).add(TagsKey.DOMAIN, domain);
}
let repositoryName = props?.repositoryName ?? env.REPOSITORY_NAME;
if (repositoryName) {
- Tags.of(module).add(env.TagsKey.REPOSITORY_NAME, repositoryName);
+ Tags.of(module).add(TagsKey.REPOSITORY_NAME, repositoryName);
}
let repositoryVersion = props?.repositoryVersion ?? env.REPOSITORY_VERSION;
if (repositoryVersion) {
- Tags.of(module).add(env.TagsKey.REPOSITORY_VERSION, repositoryVersion);
+ Tags.of(module).add(TagsKey.REPOSITORY_VERSION, repositoryVersion);
}
}
diff --git a/src/constructs/aws-lambda/index.ts b/src/constructs/aws-lambda/index.ts
new file mode 100644
index 0000000..b8bcdf4
--- /dev/null
+++ b/src/constructs/aws-lambda/index.ts
@@ -0,0 +1,109 @@
+import * as iam from 'aws-cdk-lib/aws-iam';
+import * as lambda from 'aws-cdk-lib/aws-lambda';
+import { Construct } from 'constructs';
+import { CDK_ACCOUNT_ID, CDK_REGION } from '../../common/env';
+import * as env from '../../common/env';
+import { addBaseTags } from '../../common/utils';
+
+export const NEW_RELIC_LAYERS_ACCOUNT_ID = '451483290750'; // AWS account id of NewRelic where exposed layers https://layers.newrelic-external.com/
+
+export interface FunctionProps extends lambda.FunctionProps {
+ readonly stage: string;
+}
+
+export interface FunctionNewRelicProps extends FunctionProps {
+ readonly newRelicLayerName: string;
+ readonly newRelicLayerVersion: number;
+ readonly newRelicAccountId: string;
+ readonly newRelicwithExtensionSendLogs?: boolean;
+}
+
+function getConstructId(id: string, stage: string) {
+ return id + '-construct-' + stage;
+}
+
+abstract class BaseFunction extends Construct {
+ public readonly stage: string;
+ public readonly function: lambda.Function;
+
+ constructor(scope: Construct, id: string, props: FunctionProps) {
+ super(scope, getConstructId(id, props.stage));
+ this.stage = props.stage;
+ this.function = this.createFunction(scope, id, props);
+
+ this.addEnvironment({
+ ENVIRONMENT: this.stage,
+ TIMESTAMP_DEPLOY_CDK: env.TIMESTAMP_DEPLOY_CDK,
+ BUSINESS_UNIT: env.BUSINESS_UNIT,
+ DOMAIN: env.DOMAIN,
+ REPOSITORY_NAME: env.REPOSITORY_NAME,
+ REPOSITORY_VERSION: env.REPOSITORY_VERSION,
+ });
+
+ addBaseTags(this.function);
+ }
+
+ abstract createFunction(scope: Construct, id: string, props: FunctionProps): lambda.Function;
+
+ addEnvironment(props: { [key: string]: string }) {
+ let keys = Object.keys(props);
+ for (let index = 0; index < keys.length; index++) {
+ let key = keys[index];
+ this.function.addEnvironment(key.toUpperCase(), props[key]);
+ }
+ }
+}
+export class Function extends BaseFunction {
+ constructor(scope: Construct, id: string, props: FunctionProps) {
+ super(scope, id, props);
+ }
+
+ createFunction(scope: Construct, id: string, props: FunctionNewRelicProps) {
+ return new lambda.Function(scope, id, props);
+ }
+}
+
+export class FunctionNewRelic extends BaseFunction {
+ constructor(scope: Construct, id: string, props: FunctionNewRelicProps) {
+ super(scope, id, props);
+ }
+
+ createFunction(scope: Construct, id: string, props: FunctionNewRelicProps) {
+ let handler = 'newrelic_lambda_wrapper.handler';
+ let app_handler = props.handler;
+
+ let lambdaFunction = new lambda.Function(scope, id, { ...props, handler });
+
+ lambdaFunction.addToRolePolicy(
+ new iam.PolicyStatement({
+ actions: ['secretsmanager:GetSecretValue'],
+ resources: [`arn:aws:secretsmanager:eu-west-1:${CDK_ACCOUNT_ID}:secret:NEW_RELIC_LICENSE_KEY-??????`],
+ }),
+ );
+
+ lambdaFunction.addEnvironment('NEW_RELIC_ACCOUNT_ID', props.newRelicAccountId);
+ lambdaFunction.addEnvironment('NEW_RELIC_LAMBDA_HANDLER', app_handler);
+ lambdaFunction.addEnvironment('NEW_RELIC_LAMBDA_EXTENSION_ENABLED', 'true');
+ if (props.newRelicwithExtensionSendLogs) {
+ lambdaFunction.addEnvironment('NEW_RELIC_EXTENSION_SEND_FUNCTION_LOGS', 'true');
+ }
+
+ lambdaFunction.addLayers(this.getNewRelicLayer(
+ scope,
+ lambdaFunction.functionName,
+ props.newRelicLayerName,
+ props.newRelicLayerVersion,
+ CDK_REGION,
+ ));
+
+ return lambdaFunction;
+ }
+
+ getNewRelicLayer(scope: Construct, functionName:string, layerName: string, layerVersion: number, region: string) {
+ return lambda.LayerVersion.fromLayerVersionArn(
+ scope,
+ `new-relic-layer-${functionName}`,
+ `arn:aws:lambda:${region}:${NEW_RELIC_LAYERS_ACCOUNT_ID}:layer:${layerName}:${layerVersion}`,
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/constructs/index.ts b/src/constructs/index.ts
new file mode 100644
index 0000000..0ea9679
--- /dev/null
+++ b/src/constructs/index.ts
@@ -0,0 +1 @@
+export * as aws_lambda from './aws-lambda';
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index 67bbba5..714d08d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,4 @@
export * as stacks from './stacks';
+export * as constructs from './constructs';
export * as env from './common/env';
export * as utils from './common/utils';