From adb6bb363790b1787e53381e94ee33375d4ed17a Mon Sep 17 00:00:00 2001 From: Chris Northwood Date: Fri, 11 Oct 2024 14:45:41 +0100 Subject: [PATCH 1/2] create an ingress to expose the legacy v0 API for Episerver --- cdk/app.py | 6 ++++++ cdk/app/chart.py | 31 ++++++++++++++++++++++++------ cdk/app/local_office_search_api.py | 2 ++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/cdk/app.py b/cdk/app.py index d9e497b..38caf17 100644 --- a/cdk/app.py +++ b/cdk/app.py @@ -24,6 +24,11 @@ "prod": ("prod-onsgeodata-buckete75ea64c-phllx3dqnkmx", "geo_postcodes_prod.csv"), } +API_V0_HOSTNAMES = { + "dev": "bureaudetails.qa.citizensadvice.org.uk", + "prod": "bureaudetails.prod.content.citizensadvice.org.uk", +} + STAGES = [ Stage(app, "dev", env=Environment(account=ACCOUNT_IDS["devops"], region="eu-west-1")), Stage(app, "prod", env=Environment(account=ACCOUNT_IDS["prod2"], region="eu-west-1")), @@ -40,6 +45,7 @@ lss_bucket_name=LSS_FILES[stage.stage_name], geo_data_bucket_name=GEO_DATA_FILES[stage.stage_name][0], geo_data_postcode_file=GEO_DATA_FILES[stage.stage_name][1], + api_v0_host=API_V0_HOSTNAMES[stage.stage_name], ) for child in app.node.children: diff --git a/cdk/app/chart.py b/cdk/app/chart.py index d9034d6..ce3ecee 100644 --- a/cdk/app/chart.py +++ b/cdk/app/chart.py @@ -32,7 +32,12 @@ MetricTarget, EnvFieldPaths, NetworkPolicyIpBlock, - Secret, ServiceAccount, + Secret, + ServiceAccount, + ServiceType, + Service, + Ingress, + IngressBackend, ) from constructs import Construct @@ -58,6 +63,7 @@ def __init__( service_account_name: str, rds_secret_name: str, app_secret_name: str, + api_v0_host: str, ): self._labels = { "app": self._APP_NAME, @@ -93,7 +99,8 @@ def __init__( self._geo_data_postcode_file = geo_data_postcode_file deployment = self._create_deployment() - self._expose_services(deployment) + app_service = self._expose_services(deployment) + self._expose_v0_api(api_v0_host, app_service) self._create_scheduled_import() self._configure_autoscaler(deployment) @@ -170,7 +177,9 @@ def _create_scheduled_import(self): self._add_labels(scheduled_job.metadata) self._add_labels(scheduled_job.pod_metadata) - scheduled_job.pod_metadata.add_label("component", "local-office-search-api-scheduled-import") + scheduled_job.pod_metadata.add_label( + "component", "local-office-search-api-scheduled-import" + ) scheduled_job.metadata.add_annotation( "ad.datadoghq.com/local-office-search-api-scheduled-import.logs", @@ -209,7 +218,9 @@ def _server_container_props(self, name: str, command_line: typing.List[str]): cpu=CpuResources(request=Cpu.millis(400), limit=Cpu.millis(800)), memory=MemoryResources(request=Size.mebibytes(512), limit=Size.gibibytes(1)), ), - security_context=ContainerSecurityContextProps(user=1000, read_only_root_filesystem=False), + security_context=ContainerSecurityContextProps( + user=1000, read_only_root_filesystem=False + ), ) def _app_env_vars(self): @@ -251,8 +262,10 @@ def _app_env_vars(self): } def _expose_services(self, deployment: Deployment): - deployment.expose_via_service( - name=self._APP_NAME, ports=[ServicePort(name="http", port=self._HTTP_PORT)] + service = deployment.expose_via_service( + name=self._APP_NAME, + ports=[ServicePort(name="http", port=self._HTTP_PORT)], + service_type=ServiceType.NODE_PORT, ) metrics_service = deployment.expose_via_service( @@ -261,6 +274,12 @@ def _expose_services(self, deployment: Deployment): ) metrics_service.metadata.add_label("custom-metrics-enabled", "true") + return service + + def _expose_v0_api(self, host: str, app_service: Service): + ingress = Ingress(self, "LocalOfficeSearchApiV0Ingress", class_name="alb") + ingress.add_host_rule(host, "/api/v0/", IngressBackend.from_service(app_service)) + def _configure_autoscaler(self, deployment: Deployment): HorizontalPodAutoscaler( self, diff --git a/cdk/app/local_office_search_api.py b/cdk/app/local_office_search_api.py index 4125e20..224033e 100644 --- a/cdk/app/local_office_search_api.py +++ b/cdk/app/local_office_search_api.py @@ -28,6 +28,7 @@ def __init__( lss_bucket_name: str, geo_data_bucket_name: str, geo_data_postcode_file: str, + api_v0_host: str, **kwargs, ) -> None: super().__init__(scope, construct_id, **kwargs) @@ -142,5 +143,6 @@ def __init__( service_account_name=self._service_account.service_account_name, rds_secret_name=rds_secret_source.k8s_secret_name, app_secret_name=app_secret_source.k8s_secret_name, + api_v0_host=api_v0_host, ), ) From 2add0a86034f63addcb5e4f50a931b5ae84eb8fe Mon Sep 17 00:00:00 2001 From: Chris Northwood Date: Fri, 11 Oct 2024 15:01:32 +0100 Subject: [PATCH 2/2] add annotation to configure ALB ingress --- cdk/app/chart.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/cdk/app/chart.py b/cdk/app/chart.py index ce3ecee..9a5ef9e 100644 --- a/cdk/app/chart.py +++ b/cdk/app/chart.py @@ -280,6 +280,39 @@ def _expose_v0_api(self, host: str, app_service: Service): ingress = Ingress(self, "LocalOfficeSearchApiV0Ingress", class_name="alb") ingress.add_host_rule(host, "/api/v0/", IngressBackend.from_service(app_service)) + ingress.metadata.add_annotation("alb.ingress.kubernetes.io/scheme", "internet-facing") + ingress.metadata.add_annotation( + "alb.ingress.kubernetes.io/healthcheck-path", "/status" + ) + ingress.metadata.add_annotation( + "alb.ingress.kubernetes.io/actions.ssl-redirect", + json.dumps( + { + "Type": "redirect", + "RedirectConfig": { + "Protocol": "HTTPS", + "Port": "443", + "StatusCode": "HTTP_301", + }, + } + ), + ) + ingress.metadata.add_annotation( + "alb.ingress.kubernetes.io/ssl-policy", "ELBSecurityPolicy-TLS-1-2-2017-01" + ) + ingress.metadata.add_annotation( + "alb.ingress.kubernetes.io/tags", + ",".join( + f"{key}={value}" + for key, value in { + "Environment": self._labels["env"], + "Product": "corporate_site", + "Component": "local_office_search_api", + "TechnicalOwner": "contentplatform@citizensadvice.org.uk", + }.items() + ), + ) + def _configure_autoscaler(self, deployment: Deployment): HorizontalPodAutoscaler( self,