From 9f8832f1dedf0c890222dc888470ca006ad3f4fa Mon Sep 17 00:00:00 2001 From: Gerald Iakobinyi-Pich Date: Fri, 24 Nov 2023 16:25:19 +0200 Subject: [PATCH] fix(infra): lambda functions load information from secrets manager --- api/aws_lambdas/Readme.md | 5 ----- api/aws_lambdas/utils.py | 40 +++++++++++++++++++++++++++++++++++++ api/scorer/settings/base.py | 2 +- infra/lib/scorer/service.ts | 26 ++++++++++++++++++++++++ infra/prod/index.ts | 4 ++++ infra/staging/index.ts | 4 ++++ 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/api/aws_lambdas/Readme.md b/api/aws_lambdas/Readme.md index 924b8e403..cf1b29f01 100644 --- a/api/aws_lambdas/Readme.md +++ b/api/aws_lambdas/Readme.md @@ -40,8 +40,3 @@ curl -X 'POST' \ "isBase64Encoded": false }' ``` -```` - -``` - -``` diff --git a/api/aws_lambdas/utils.py b/api/aws_lambdas/utils.py index 7b2fffad4..5af4a1fcf 100644 --- a/api/aws_lambdas/utils.py +++ b/api/aws_lambdas/utils.py @@ -5,6 +5,7 @@ import json import os from functools import wraps +from traceback import print_exc from typing import Any, Dict, Tuple from aws_lambdas.exceptions import InvalidRequest @@ -13,6 +14,45 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "scorer.settings") os.environ.setdefault("CERAMIC_CACHE_SCORER_ID", "1") +########################################################### +# Loading secrets from secrets manager +# https://aws.amazon.com/developer/language/python/ +# For a list of exceptions thrown, see +# https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html +# https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html +########################################################### + +import boto3 +from botocore.exceptions import ClientError + + +def load_secrets(): + ssm_srn = os.environ["SCORER_SERVER_SSM_ARN"] + + # Create a Secrets Manager client + session = boto3.session.Session() + client = session.client(service_name="secretsmanager") + + try: + get_secret_value_response = client.get_secret_value(SecretId=ssm_srn) + except ClientError as e: + print(f"Error occurred while loading secret value: {e}") + print_exc() + raise e + + # Decrypts secret using the associated KMS key. + # Load secrets and store them in env variables + secrets = json.loads(get_secret_value_response["SecretString"]) + os.environ["SECRET_KEY"] = secrets["SECRET_KEY"] + + +load_secrets() + +########################################################### +# END: Loading secrets from secrets manager +########################################################### + + # pylint: disable=wrong-import-position import django diff --git a/api/scorer/settings/base.py b/api/scorer/settings/base.py index 654bc73bb..8a6d4ca99 100644 --- a/api/scorer/settings/base.py +++ b/api/scorer/settings/base.py @@ -20,7 +20,7 @@ # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = env("SECRET_KEY", default="some-secret-value") +SECRET_KEY = env("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! DEBUG = env("DEBUG", default=True) diff --git a/infra/lib/scorer/service.ts b/infra/lib/scorer/service.ts index ffd3094da..ce8322b1d 100644 --- a/infra/lib/scorer/service.ts +++ b/infra/lib/scorer/service.ts @@ -749,6 +749,16 @@ export const createSharedLambdaResources = () => { ], }); + const lambdaSecretsManagerPolicyDocument = aws.iam.getPolicyDocument({ + statements: [ + { + effect: "Allow", + actions: ["secretsmanager:GetSecretValue"], + resources: ["arn:aws:secretsmanager:*:*:*"], + }, + ], + }); + const lambdaLoggingPolicy = new aws.iam.Policy("lambdaLoggingPolicy", { path: "/", description: "IAM policy for logging from a lambda", @@ -765,6 +775,15 @@ export const createSharedLambdaResources = () => { ), }); + const lambdaSecretsManagerPolicy = new aws.iam.Policy("lambdaSecretManagerPolicy", { + path: "/", + description: "IAM policy for interfacing with EC2 network", + policy: lambdaSecretsManagerPolicyDocument.then( + (lambdaSecretsManagerPolicyDocument) => + lambdaSecretsManagerPolicyDocument.json + ), + }); + const assumeRole = aws.iam.getPolicyDocument({ statements: [ { @@ -800,10 +819,17 @@ export const createSharedLambdaResources = () => { } ); + const lambdaSecretsManagerPolicyAttachement = + new aws.iam.RolePolicyAttachment("lambdaSecretManagerRoleAttachment", { + role: lambdaRole.name, + policyArn: lambdaSecretsManagerPolicy.arn, + }); + return { lambdaRole, lambdaLogRoleAttachment, lambdaEc2RoleAttachment, + lambdaSecretsManagerPolicyAttachement, }; }; diff --git a/infra/prod/index.ts b/infra/prod/index.ts index 67a71dfcb..96de4f941 100644 --- a/infra/prod/index.ts +++ b/infra/prod/index.ts @@ -1252,6 +1252,10 @@ const lambdaSettings = { name: "CERAMIC_CACHE_SCORER_ID", value: "335", }, + { + name: "SCORER_SERVER_SSM_ARN", + value: SCORER_SERVER_SSM_ARN, + }, ], ...sharedLambdaResources, }; diff --git a/infra/staging/index.ts b/infra/staging/index.ts index 76182d26b..9fde10d48 100644 --- a/infra/staging/index.ts +++ b/infra/staging/index.ts @@ -571,6 +571,10 @@ const lambdaSettings = { name: "CERAMIC_CACHE_SCORER_ID", value: "14", }, + { + name: "SCORER_SERVER_SSM_ARN", + value: SCORER_SERVER_SSM_ARN, + }, ], ...sharedLambdaResources, };