Source code for rootski_backend_cdk.database.lightsail.stacks.lightsail_instance

"""Stack containing a lightsail instance and a static IP address."""

from enum import Enum
from pathlib import Path

import aws_cdk as cdk
from aws_cdk import aws_lightsail as lightsail
from constructs import Construct
from jinja2 import Template
from rootski_backend_cdk.common.constants import TAGS

THIS_DIR = Path(__file__).parent
RESOURCES_DIR = THIS_DIR / "resources"
USER_DATA_TEMPLATE_FPATH = RESOURCES_DIR / "user-data.template.sh"


[docs]class StackOutputs(str, Enum): """Output keys for the lightsail stack.""" # pylint: disable=invalid-name static_ip = "StaticIp" ssh_key_pair_name = "SshKeyPairName" lightsail_admin_username = "LightsailAdminUsername"
[docs]class ContextVars(str, Enum): """Context vars for the lightsail stack that must be passed in as CLI arguments.""" # pylint: disable=invalid-name iam_access_key_id = "iam_access_key_id" iam_access_key = "iam_access_key"
[docs]def render_user_data_script(iam_access_key_id: str, iam_access_key: str) -> str: """ Render the user-data.template.sh script inserting the IAM credentials for the Lightsail instance. :param iam_access_key_id: key_id with programmatic access that will be present in the user-data.sh script :param iam_access_key: same as above but the actual key """ user_data_template = Template(USER_DATA_TEMPLATE_FPATH.read_text()) return user_data_template.render( { "AWS_ACCESS_KEY_ID": iam_access_key_id, "AWS_SECRET_ACCESS_KEY": iam_access_key, } )
[docs]class LightsailInstanceStack(cdk.Stack): """A Lightsail instance with a static IP used to host the backend database.""" def __init__( self, scope: Construct, construct_id: str, iam_access_key_id: str, iam_access_key: str, **kwargs, ): """ Instantiate a LightsailInstanceStack. :param iam_access_key_id: key_id with programmatic access that will be present in the user-data.sh script :param iam_access_key: same as above but the actual key The IAM key and key id are used to access the S3 bucket where database backups are kept. """ super().__init__(scope, construct_id, **kwargs) instance = lightsail.CfnInstance( self, id="Rootski-DB-Lightsail-Instance", # specifying the instance name prevents CDK from being able to destroy this resource # if we update the stack (for example, if we want to change the instance size # which would require destroying the existing instance and creating a new one). # However, this is a required parameter :( instance_name="Rootski-DB-Lightsail-Instance", key_pair_name="rootski.id_rsa", availability_zone="us-west-2a", tags=TAGS, networking=lightsail.CfnInstance.NetworkingProperty( ports=[ lightsail.CfnInstance.PortProperty( access_direction="inbound", cidrs=["172.0.0.0/8"], common_name="SSH", from_port=22, protocol="tcp", to_port=22, ), lightsail.CfnInstance.PortProperty( access_direction="inbound", cidrs=["172.0.0.0/8"], common_name="Postgres", from_port=8000, protocol="tcp", to_port=8000, ), # traefik lightsail.CfnInstance.PortProperty( access_direction="inbound", cidrs=["172.0.0.0/8"], common_name="Postgres", from_port=80, protocol="tcp", to_port=80, ), lightsail.CfnInstance.PortProperty( access_direction="inbound", # cidrs=["172.0.0.0/8"], cidrs=["0.0.0.0/0"], common_name="Postgres", from_port=5432, protocol="tcp", to_port=5432, ), lightsail.CfnInstance.PortProperty( access_direction="inbound", cidrs=["172.0.0.0/8"], common_name="Postgres", from_port=3333, protocol="tcp", to_port=3333, ), lightsail.CfnInstance.PortProperty( access_direction="outbound", cidrs=["0.0.0.0/0"], common_name="All Outbound Traffic", from_port=0, protocol="all", to_port=65535, ), ] ), # found using 'aws lightsail get-blueprints --profile rootski' blueprint_id="amazon_linux_2", # found using 'aws lightsail get-bundles --profile rootski' bundle_id="micro_2_0", user_data=render_user_data_script( iam_access_key_id=iam_access_key_id, iam_access_key=iam_access_key ), ) # free as long as the instance is running self.static_ip = lightsail.CfnStaticIp( self, id="Rootski-DB-Lightsail-StaticIp", static_ip_name="Rootski-DB-Lightsail-StaticIp", attached_to=instance.ref, ) cdk.CfnOutput( scope=self, id=StackOutputs.static_ip.value, value=self.static_ip.attr_ip_address, description="IP address of the rootski db Lightsail instance", export_name=StackOutputs.static_ip.value, ) cdk.CfnOutput( scope=self, id=StackOutputs.ssh_key_pair_name.value, value=instance.attr_ssh_key_name, description="RSA key pair used to SSH into the db instance.", export_name=StackOutputs.ssh_key_pair_name.value, ) cdk.CfnOutput( scope=self, id=StackOutputs.lightsail_admin_username.value, value=instance.attr_user_name, description="Admin username of the rootski db Lightsail instance", export_name=StackOutputs.lightsail_admin_username.value, )