diff --git a/README.md b/README.md index 81489566..f26a8ca7 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,17 @@ To retrieve the variables for a stage that has been previously deployed, the sec | `VEDA_DB_PGSTAC_VERSION` | **REQUIRED** version of PgStac database, i.e. 0.7.6 | | `VEDA_DB_SCHEMA_VERSION` | **REQUIRED** The version of the custom veda-backend schema, i.e. 0.1.1 | | `VEDA_DB_SNAPSHOT_ID` | **Once used always REQUIRED** Optional RDS snapshot identifier to initialize RDS from a snapshot | -> **Note** See [Advanced Configuration](docs/advanced_configuration.md) for details about custom configuration options. + +### Advanced configuration +The constructs and applications in this project are configured using pydantic. The settings are defined in config.py files stored alongside the associated construct or application--for example the settings for the RDS PostgreSQL construct are defined in database/infrastructure/config.py. For custom configuration, use environment variables to override the pydantic defaults. + +| Construct | Env Prefix | Configuration | +| --- | --- | --- | +| Database | `VEDA_DB` | [database/infrastructure/config.py](database/infrastructure/config.py) | +| Domain | `VEDA_DOMAIN` | [domain/infrastructure/config.py](domain/infrastructure/config.py) | +| Network | `N/A` | [network/infrastructure/config.py](network/infrastructure/config.py) | +| Raster API (TiTiler) | `VEDA_RASTER` | [raster_api/infrastructure/config.py](raster_-_api/infrastructure/config.py) | +| STAC API | `VEDA_STAC` | [stac_api/infrastructure/config.py](stac_api/infrastructure/config.py) | ### Deploying to the cloud diff --git a/database/infrastructure/config.py b/database/infrastructure/config.py index dfc32085..b5d8255f 100644 --- a/database/infrastructure/config.py +++ b/database/infrastructure/config.py @@ -1,6 +1,7 @@ """Veda-backend database construct configuration.""" from typing import Optional +from aws_cdk import aws_ec2, aws_rds from pydantic import BaseSettings, Field @@ -57,6 +58,38 @@ class vedaDBSettings(BaseSettings): False, description="Boolean if the RDS should be accessed through a proxy", ) + rds_instance_class: Optional[str] = Field( + aws_ec2.InstanceClass.BURSTABLE3.value, + description=( + "The instance class of the RDS instance " + "https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_ec2/InstanceClass.html" + ), + ) + rds_instance_size: Optional[str] = Field( + aws_ec2.InstanceSize.SMALL.value, + description=( + "The size of the RDS instance " + "https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_ec2/InstanceSize.html" + ), + ) + rds_engine_full_version: Optional[str] = Field( + aws_rds.PostgresEngineVersion.VER_14.postgres_full_version, + description=( + "The version of the RDS Postgres engine " + "https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_rds/PostgresEngineVersion.html" + ), + ) + rds_engine_major_version: Optional[str] = Field( + aws_rds.PostgresEngineVersion.VER_14.postgres_major_version, + description=( + "The version of the RDS Postgres engine " + "https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_rds/PostgresEngineVersion.html" + ), + ) + rds_encryption: Optional[bool] = Field( + False, + description="Boolean if the RDS should be encrypted", + ) class Config: """model config.""" diff --git a/database/infrastructure/construct.py b/database/infrastructure/construct.py index d5c09cbf..ca2e4ba6 100644 --- a/database/infrastructure/construct.py +++ b/database/infrastructure/construct.py @@ -137,8 +137,19 @@ def __init__( # Custom parameter group engine = aws_rds.DatabaseInstanceEngine.postgres( - version=aws_rds.PostgresEngineVersion.VER_14 + version=aws_rds.PostgresEngineVersion.of( + veda_db_settings.rds_engine_full_version, + veda_db_settings.rds_engine_major_version, + ) + ) + + # RDS Instance Type + rds_instance_type = aws_ec2.InstanceType.of( + aws_ec2.InstanceClass[veda_db_settings.rds_instance_class], + aws_ec2.InstanceSize[veda_db_settings.rds_instance_size], ) + + # version=aws_rds.PostgresEngineVersion.postgres_major_version(veda_db_settings.rds_engine_version) parameter_group = aws_rds.ParameterGroup( self, "parameter-group", @@ -150,48 +161,39 @@ def __init__( }, ) + # Database Configurations + database_config = { + "id": "rds", + "instance_identifier": f"{stack_name}-postgres", + "vpc": vpc, + "engine": engine, + "instance_type": rds_instance_type, + "vpc_subnets": aws_ec2.SubnetSelection(subnet_type=subnet_type), + "deletion_protection": True, + "removal_policy": RemovalPolicy.RETAIN, + "publicly_accessible": veda_db_settings.publicly_accessible, + "parameter_group": parameter_group, + } + if veda_db_settings.rds_encryption: + database_config["storage_encrypted"] = veda_db_settings.rds_encryption + # Create a new database instance from snapshot if provided if veda_db_settings.snapshot_id: # For the database from snapshot we will need a new master secret - credentials = aws_rds.SnapshotCredentials.from_generated_secret( + snapshot_credentials = aws_rds.SnapshotCredentials.from_generated_secret( username=veda_db_settings.admin_user ) database = aws_rds.DatabaseInstanceFromSnapshot( self, - id="rds", snapshot_identifier=veda_db_settings.snapshot_id, - instance_identifier=f"{stack_name}-postgres", - vpc=vpc, - engine=engine, - instance_type=aws_ec2.InstanceType.of( - aws_ec2.InstanceClass.BURSTABLE3, aws_ec2.InstanceSize.SMALL - ), - vpc_subnets=aws_ec2.SubnetSelection(subnet_type=subnet_type), - deletion_protection=True, - removal_policy=RemovalPolicy.RETAIN, - publicly_accessible=veda_db_settings.publicly_accessible, - credentials=credentials, - parameter_group=parameter_group, + credentials=snapshot_credentials, + **database_config, ) # Or create/update RDS Resource else: - database = aws_rds.DatabaseInstance( - self, - id="rds", - instance_identifier=f"{stack_name}-postgres", - vpc=vpc, - engine=engine, - instance_type=aws_ec2.InstanceType.of( - aws_ec2.InstanceClass.BURSTABLE3, aws_ec2.InstanceSize.SMALL - ), - vpc_subnets=aws_ec2.SubnetSelection(subnet_type=subnet_type), - deletion_protection=True, - removal_policy=RemovalPolicy.RETAIN, - publicly_accessible=veda_db_settings.publicly_accessible, - parameter_group=parameter_group, - ) + database = aws_rds.DatabaseInstance(self, **database_config) hostname = database.instance_endpoint.hostname diff --git a/docs/advanced_configuration.md b/docs/advanced_configuration.md deleted file mode 100644 index de56fc70..00000000 --- a/docs/advanced_configuration.md +++ /dev/null @@ -1,25 +0,0 @@ -# Advanced Configuration -The constructs and applications in this project are configured using [pydantic](https://docs.pydantic.dev/usage/settings/). The settings are defined in config.py files stored alongside the associated construct or application--for example the settings for the RDS PostgreSQL construct are defined in [database/infrastructure/config.py](../database/infrastructure/config.py); the settings for the TiTiler API are defined in [raster_api/runtime/src/config.py](../raster_api/runtime/src/config.py). For custom configuration, use environment variables to override the pydantic defaults. - -## Selected configuration variables -Environment variables for specific VEDA backend components are prefixed, for example database configuration variables are prefixed `VEDA_DB`. See the config.py file in each construct for the appropriate prefix. -| Name | Explanation | -| --- | --- | -| `APP_NAME` | Optional app name used to name stack and resources, defaults to `veda` | -| `STAGE` | **REQUIRED** Deployment stage used to name stack and resources, i.e. `dev`, `staging`, `prod` | -| `VPC_ID` | Optional resource identifier of VPC, if none a new VPC with public and private subnets will be provisioned. | -| `PERMISSIONS_BOUNDARY_POLICY_NAME` | Optional name of IAM policy to define stack permissions boundary | -| `CDK_DEFAULT_ACCOUNT` | When deploying from a local machine the AWS account id is required to deploy to an exiting VPC | -| `CDK_DEFAULT_REGION` | When deploying from a local machine the AWS region id is required to deploy to an exiting VPC | -| `VEDA_DB_PGSTAC_VERSION` | **REQUIRED** version of PgStac database, i.e. 0.5 | -| `VEDA_DB_SCHEMA_VERSION` | **REQUIRED** The version of the custom veda-backend schema, i.e. 0.1.1 | -| `VEDA_DB_SNAPSHOT_ID` | **Once used always REQUIRED** Optional RDS snapshot identifier to initialize RDS from a snapshot | -| `VEDA_DB_PRIVATE_SUBNETS` | Optional boolean to deploy database to private subnet | -| `VEDA_DOMAIN_HOSTED_ZONE_ID` | Optional Route53 zone identifier if using a custom domain name | -| `VEDA_DOMAIN_HOSTED_ZONE_NAME` | Optional custom domain name, i.e. veda-backend.xyz | -| `VEDA_DOMAIN_ALT_HOSTED_ZONE_ID` | Optional second Route53 zone identifier if using a custom domain name | -| `VEDA_DOMAIN_ALT_HOSTED_ZONE_NAME` | Optional second custom domain name, i.e. alt-veda-backend.xyz | -| `VEDA_DOMAIN_API_PREFIX` | Optional domain prefix override supports using a custom prefix instead of the STAGE variabe (an alternate version of the stack can be deployed with a unique STAGE=altprod and after testing prod API traffic can be cut over to the alternate version of the stack by setting the prefix to prod) | -| `VEDA_RASTER_ENABLE_MOSAIC_SEARCH` | Optional deploy the raster API with the mosaic/list endpoint TRUE/FALSE | -| `VEDA_RASTER_DATA_ACCESS_ROLE_ARN` | Optional arn of IAM Role to be assumed by raster-api for S3 bucket data access, if not provided default role for the lambda construct is used | -| `VEDA_RASTER_AWS_REQUEST_PAYER` | Set this optional global parameter to 'requester' if the requester agrees to pay S3 transfer costs |