diff --git a/README.md b/README.md index 8ecc2a5a..47036371 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,14 @@ The DB can be dumped to a file using the following: _NOTE: These commands must be run from the ``/app/`` directory on the server. +### AWS: + +The above management commands (and others) can be run in production from an EC2 instance correctly configured. To +aid in shell setup, the following script can be executed: + * ``source repo/biospecdb/scripts/prd/ec2_init.sh`` + +_NOTE: ``scripts/prd/ec2_init.sh`` will export all AWS secrets as shell environment variables. + # Usage ### URL Paths: diff --git a/biospecdb/util.py b/biospecdb/util.py index 20d66053..425d36ce 100644 --- a/biospecdb/util.py +++ b/biospecdb/util.py @@ -3,7 +3,9 @@ import os from pathlib import Path from uuid import UUID +import yaml +import boto3 from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ import numpy as np @@ -117,3 +119,31 @@ def get_object_or_raise_validation(obj, **kwargs): def get_field_value(series, obj, field, default=None): return series.get(getattr(obj, field).field.verbose_name.lower(), default=default) + + +def get_aws_secret(arn, region): + session = boto3.session.Session() + client = session.client(service_name='secretsmanager', region_name=region) + return client.get_secret_value(SecretId=arn)['SecretString'] + + +def parse_secure_secrets_from_apprunner(apprunner_yaml_file=find_repo_location() / "apprunner.yaml"): + with open(apprunner_yaml_file) as fp: + config = yaml.safe_load(fp) + return {list(d.values())[0]: list(d.values())[1] for d in config["run"]["secrets"]} + + +def get_aws_secrets(apprunner_yaml_file=find_repo_location() / "apprunner.yaml", region="eu-west-2", export=False): + secure_secrets = parse_secure_secrets_from_apprunner(apprunner_yaml_file) + unsecure_secrets = {k: get_aws_secret(v, region=region) for k, v in secure_secrets.items()} + + if export: + for k, v in unsecure_secrets: + os.environ[k] = v + + return unsecure_secrets + + +def print_aws_secrets(apprunner_yaml_file=find_repo_location() / "apprunner.yaml", region="eu-west-2"): + for k, v in get_aws_secrets(apprunner_yaml_file, region).items(): + print(f"{k}={v}") diff --git a/pyproject.toml b/pyproject.toml index 0937f83e..fc06a16c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ license = {file = "LICENSE"} requires-python = ">=3.11" dependencies = [ + "boto3", "django", "django-crontab", "django-decorator-include", @@ -23,6 +24,7 @@ dependencies = [ "pandas", "plotly", "psycopg[binary,pool]", + "pyyaml", "whitenoise", "xlsxwriter" ] diff --git a/requirements/prd.txt b/requirements/prd.txt index 749035f9..d26332e5 100644 --- a/requirements/prd.txt +++ b/requirements/prd.txt @@ -1,3 +1,4 @@ +boto3==1.34.62 django==4.2.11 django-crontab==0.7.1 django-decorator-include==3.0 @@ -11,5 +12,6 @@ openpyxl==3.1.2 pandas==2.2.1 plotly==5.19.0 psycopg[binary,pool]==3.1.18 +pyyaml==6.0.1 xlsxwriter==3.2.0 whitenoise==6.6.0 diff --git a/scripts/prd/ec2_init.sh b/scripts/prd/ec2_init.sh new file mode 100755 index 00000000..7223a19d --- /dev/null +++ b/scripts/prd/ec2_init.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +conda activate biospecdb + +cd repo/biospecdb +git fetch +git checkout origin/main -f + +export DB_VENDOR=postgresql +export DJANGO_SETTINGS_MODULE=biospecdb.settings.aws + +export $(python -c "from biospecdb.util import print_aws_secrets;print_aws_secrets()")