diff --git a/api-placeholder/Dockerfile b/api-placeholder/Dockerfile new file mode 100644 index 0000000..44329a9 --- /dev/null +++ b/api-placeholder/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3 + +ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PORT 8080 + +WORKDIR /app +COPY . /app + +ENTRYPOINT ["python", "app.py"] diff --git a/api-placeholder/app.py b/api-placeholder/app.py new file mode 100644 index 0000000..b65e8f5 --- /dev/null +++ b/api-placeholder/app.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +import os +import json +import logging +from http.server import BaseHTTPRequestHandler, HTTPServer + + +PORT = int(os.getenv('PORT', 8080)) + + +class JsonEcho(BaseHTTPRequestHandler): + def send_json_response(self, **data): + response = json.dumps(data).encode('utf-8') + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.send_header('Content-length', len(response)) + self.end_headers() + self.wfile.write(response) + + def do_GET(self): + logging.info(f'GET {self.path}') + self.send_json_response(path=self.path, headers=dict(self.headers.items())) + + +def run(server_class=HTTPServer, handler_class=JsonEcho, port=8080): + httpd = server_class(('', PORT), handler_class) + logging.info('Starting API placeholder...') + try: + httpd.serve_forever() + except KeyboardInterrupt: + pass + httpd.server_close() + logging.info('Stopping API placeholder...') + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + run() diff --git a/app.py b/app.py index 03c5d54..2926155 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,68 @@ #!/usr/bin/env python3 +import os + from aws_cdk import core +import aws_cdk.aws_ec2 as ec2 +import aws_cdk.aws_ecs as ecs +import aws_cdk.aws_ecs_patterns as ecs_patterns from karaokeme_cdk.karaokeme_cdk_stack import KaraokemeCdkStack -app = core.App() -KaraokemeCdkStack(app, "karaokeme-cdk") +class BaseResources(core.Stack): + def __init__(self, *args, **kwargs): + super(BaseResources, self).__init__(*args, **kwargs) + # Network + self.vpc = ec2.Vpc(self, 'karaoke-vpc') + + # ECS cluster + self.cluster = ecs.Cluster(self, 'karaoke-cluster', + vpc=self.vpc) + + +class HttpApi(core.Stack): + def __init__(self, scope, id, cluster: ecs.Cluster, **kwargs): + super().__init__(scope, id, **kwargs) + + api_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'api-placeholder')) + + self.api = ecs_patterns.ApplicationLoadBalancedFargateService(self, 'http-api-service', + cluster=cluster, + task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions( + image=ecs.ContainerImage.from_asset(directory=api_dir), + container_port=8080), + desired_count=2, + cpu=256, + memory_limit_mib=512) + + +class SeparatorWorker(core.Stack): + def __init__(self, scope, id, cluster: ecs.Cluster, **kwargs): + super().__init__(scope, id, **kwargs) + + worker_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'worker-placeholder')) + + self.service = ecs_patterns.QueueProcessingFargateService(self, 'separator-service', + cpu=256, + memory_limit_mib=512, + image=ecs.ContainerImage.from_asset(directory=worker_dir), + cluster=cluster) + + +class KaraokeApp(core.App): + def __init__(self, *args, **kwargs): + super(KaraokeApp, self).__init__(*args, **kwargs) + + self.base_resources = BaseResources(self, 'base-resources') + + self.http_api = HttpApi(self, 'http-api', + cluster=self.base_resources.cluster) + + self.separator_worker = SeparatorWorker(self, 'separator-worker', + cluster=self.base_resources.cluster) + + +app = KaraokeApp() app.synth() diff --git a/requirements.txt b/requirements.txt index d6e1198..c74f3f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,52 @@ -e . +astroid==2.3.3 +attrs==19.3.0 +aws-cdk.assets==1.32.2 +aws-cdk.aws-apigateway==1.32.2 +aws-cdk.aws-applicationautoscaling==1.32.2 +aws-cdk.aws-autoscaling==1.32.2 +aws-cdk.aws-autoscaling-common==1.32.2 +aws-cdk.aws-autoscaling-hooktargets==1.32.2 +aws-cdk.aws-certificatemanager==1.32.2 +aws-cdk.aws-cloudformation==1.32.2 +aws-cdk.aws-cloudfront==1.32.2 +aws-cdk.aws-cloudwatch==1.32.2 +aws-cdk.aws-ec2==1.32.2 +aws-cdk.aws-ecr==1.32.2 +aws-cdk.aws-ecr-assets==1.32.2 +aws-cdk.aws-ecs==1.32.2 +aws-cdk.aws-ecs_patterns==1.32.2 +aws-cdk.aws-elasticloadbalancing==1.32.2 +aws-cdk.aws-elasticloadbalancingv2==1.32.2 +aws-cdk.aws-events==1.32.2 +aws-cdk.aws-iam==1.32.2 +aws-cdk.aws-kms==1.32.2 +aws-cdk.aws-lambda==1.32.2 +aws-cdk.aws-logs==1.32.2 +aws-cdk.aws-route53==1.32.2 +aws-cdk.aws-route53-targets==1.32.2 +aws-cdk.aws-s3==1.32.2 +aws-cdk.aws-s3-assets==1.32.2 +aws-cdk.aws-sam==1.32.2 +aws-cdk.aws-secretsmanager==1.32.2 +aws-cdk.aws-servicediscovery==1.32.2 +aws-cdk.aws-sns==1.32.2 +aws-cdk.aws-sns-subscriptions==1.32.2 +aws-cdk.aws-sqs==1.32.2 +aws-cdk.aws-ssm==1.32.2 +aws-cdk.core==1.32.2 +aws-cdk.cx-api==1.32.2 +aws-cdk.region-info==1.32.2 +cattrs==1.0.0 +constructs==2.0.1 +isort==4.3.21 +jsii==1.1.0 +lazy-object-proxy==1.4.3 +mccabe==0.6.1 +publication==0.0.3 +pylint==2.4.4 +python-dateutil==2.8.1 +six==1.14.0 +typed-ast==1.4.1 +typing-extensions==3.7.4.2 +wrapt==1.11.2 diff --git a/worker-placeholder/Dockerfile b/worker-placeholder/Dockerfile new file mode 100644 index 0000000..3b2cf5e --- /dev/null +++ b/worker-placeholder/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3 + +ENV PYTHONUNBUFFERED=1 +ENV PYTHONDONTWRITEBYTECODE=1 + +WORKDIR /app +COPY . /app + +ENTRYPOINT ["python", "app.py"] diff --git a/worker-placeholder/app.py b/worker-placeholder/app.py new file mode 100644 index 0000000..243c767 --- /dev/null +++ b/worker-placeholder/app.py @@ -0,0 +1,15 @@ +import logging +import threading + + +logger = logging.getLogger('worker') + + +def fake_it(): + threading.Timer(5.0, fake_it).start() + logger.info('Checking for work') + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + fake_it()