From 9155f192aaaf85b1a8aa6d5918559db25cbe6b36 Mon Sep 17 00:00:00 2001 From: Michal Charemza Date: Thu, 14 Mar 2024 17:01:38 +0000 Subject: [PATCH] feat: allow logging of S3Sync/mobius3 metrics to CloudWatch This adds the permission for each user to log S3Sync metrics to Cloudwatch, specifically ones added in https://github.com/uktrade/mobius3/releases/tag/v0.0.42 It also tightens up permissions on the Cloudwatch VPC endpoints, making sure that only our AWS accounts can use them. --- infra/ecs_notebooks_jupyterlab_python.tf | 3 + infra/ecs_notebooks_notebook.tf | 109 ++++++++++++++++++ ...ebooks_notebook_container_definitions.json | 6 + infra/ecs_notebooks_remote_desktop.tf | 3 + infra/ecs_notebooks_superset.tf | 3 + infra/ecs_notebooks_theia.tf | 3 + infra/ecs_pgadmin.tf | 3 + infra/ecs_rstudio.tf | 3 + infra/ecs_rstudio_rv4.tf | 3 + infra/main.tf | 6 + 10 files changed, 142 insertions(+) diff --git a/infra/ecs_notebooks_jupyterlab_python.tf b/infra/ecs_notebooks_jupyterlab_python.tf index 502ecf4..dfe9277 100644 --- a/infra/ecs_notebooks_jupyterlab_python.tf +++ b/infra/ecs_notebooks_jupyterlab_python.tf @@ -14,6 +14,9 @@ resource "aws_ecs_task_definition" "jupyterlabpython" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:${data.external.jupyterlabpython_metrics_current_tag.result.tag}" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:${data.external.jupyterlabpython_s3sync_current_tag.result.tag}" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/jovyan" } ) diff --git a/infra/ecs_notebooks_notebook.tf b/infra/ecs_notebooks_notebook.tf index 8b359e8..d9a7e8f 100644 --- a/infra/ecs_notebooks_notebook.tf +++ b/infra/ecs_notebooks_notebook.tf @@ -14,6 +14,9 @@ resource "aws_ecs_task_definition" "notebook" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:${data.external.notebook_metrics_current_tag.result.tag}" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:${data.external.notebook_s3sync_current_tag.result.tag}" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/jovyan" } ) @@ -187,6 +190,32 @@ data "aws_iam_policy_document" "notebook_s3_access_template" { ] } + statement { + actions = [ + "cloudwatch:PutMetricData", + ] + + resources = [ + "*", + ] + + condition { + test = "StringEquals" + variable = "cloudwatch:namespace" + values = [ + "${var.cloudwatch_namespace}/S3Sync" + ] + } + + condition { + test = "StringEquals" + variable = "aws:PrincipalAccount" + values = [ + "${data.aws_caller_identity.aws_caller_identity.account_id}" + ] + } + } + statement { actions = [ "elasticfilesystem:ClientMount", @@ -355,6 +384,32 @@ data "aws_iam_policy_document" "jupyterhub_notebook_task_boundary" { ] } + statement { + actions = [ + "cloudwatch:PutMetricData", + ] + + resources = [ + "*", + ] + + condition { + test = "StringEquals" + variable = "cloudwatch:namespace" + values = [ + "${var.cloudwatch_namespace}/S3Sync" + ] + } + + condition { + test = "StringEquals" + variable = "aws:PrincipalAccount" + values = [ + "${data.aws_caller_identity.aws_caller_identity.account_id}" + ] + } + } + statement { actions = [ "elasticfilesystem:ClientMount", @@ -380,9 +435,36 @@ resource "aws_vpc_endpoint" "cloudwatch_logs" { security_group_ids = ["${aws_security_group.cloudwatch.id}"] subnet_ids = ["${aws_subnet.private_with_egress.*.id[0]}"] + policy = data.aws_iam_policy_document.aws_vpc_endpoint_cloudwatch_logs.json + private_dns_enabled = true } +data "aws_iam_policy_document" "aws_vpc_endpoint_cloudwatch_logs" { + statement { + principals { + type = "AWS" + identifiers = ["*"] + } + + actions = [ + "*", + ] + + resources = [ + "*", + ] + + condition { + test = "StringEquals" + variable = "aws:PrincipalAccount" + values = [ + "${data.aws_caller_identity.aws_caller_identity.account_id}" + ] + } + } +} + resource "aws_vpc_endpoint" "cloudwatch_monitoring" { vpc_id = aws_vpc.main.id service_name = "com.amazonaws.${data.aws_region.aws_region.name}.monitoring" @@ -391,5 +473,32 @@ resource "aws_vpc_endpoint" "cloudwatch_monitoring" { security_group_ids = ["${aws_security_group.cloudwatch.id}"] subnet_ids = ["${aws_subnet.private_with_egress.*.id[0]}"] + policy = data.aws_iam_policy_document.aws_vpc_endpoint_cloudwatch_monitoring.json + private_dns_enabled = true } + +data "aws_iam_policy_document" "aws_vpc_endpoint_cloudwatch_monitoring" { + statement { + principals { + type = "AWS" + identifiers = ["*"] + } + + actions = [ + "*", + ] + + resources = [ + "*", + ] + + condition { + test = "StringEquals" + variable = "aws:PrincipalAccount" + values = [ + "${data.aws_caller_identity.aws_caller_identity.account_id}" + ] + } + } +} diff --git a/infra/ecs_notebooks_notebook_container_definitions.json b/infra/ecs_notebooks_notebook_container_definitions.json index f4f714c..9caf143 100644 --- a/infra/ecs_notebooks_notebook_container_definitions.json +++ b/infra/ecs_notebooks_notebook_container_definitions.json @@ -67,6 +67,12 @@ },{ "name": "SENTRY_ENVIRONMENT", "value": "${sentry_environment}" + }, { + "name": "CLOUDWATCH_MONITORING_NAMESPACE", + "value": "${cloudwatch_namespace}/S3Sync" + }, { + "name": "CLOUDWATCH_MONITORING_REGION", + "value": "${cloudwatch_region}" }] } ] diff --git a/infra/ecs_notebooks_remote_desktop.tf b/infra/ecs_notebooks_remote_desktop.tf index ed0114a..eb6aaa8 100644 --- a/infra/ecs_notebooks_remote_desktop.tf +++ b/infra/ecs_notebooks_remote_desktop.tf @@ -14,6 +14,9 @@ resource "aws_ecs_task_definition" "remotedesktop" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:${data.external.remotedesktop_current_tag.result.tag}" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:${data.external.remotedesktop_current_tag.result.tag}" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/dw" } ) diff --git a/infra/ecs_notebooks_superset.tf b/infra/ecs_notebooks_superset.tf index 6c6c6f6..51dfae8 100644 --- a/infra/ecs_notebooks_superset.tf +++ b/infra/ecs_notebooks_superset.tf @@ -14,6 +14,9 @@ resource "aws_ecs_task_definition" "superset" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:master" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:master" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/superset" } ) diff --git a/infra/ecs_notebooks_theia.tf b/infra/ecs_notebooks_theia.tf index 29bc964..0b7647e 100644 --- a/infra/ecs_notebooks_theia.tf +++ b/infra/ecs_notebooks_theia.tf @@ -14,6 +14,9 @@ resource "aws_ecs_task_definition" "theia" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:master" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:master" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/theia" } ) diff --git a/infra/ecs_pgadmin.tf b/infra/ecs_pgadmin.tf index 4a3bb3b..153c2bb 100644 --- a/infra/ecs_pgadmin.tf +++ b/infra/ecs_pgadmin.tf @@ -16,6 +16,9 @@ resource "aws_ecs_task_definition" "pgadmin" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:${data.external.pgadmin_metrics_current_tag.result.tag}" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:${data.external.pgadmin_s3sync_current_tag.result.tag}" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/pgadmin" } ) diff --git a/infra/ecs_rstudio.tf b/infra/ecs_rstudio.tf index 9be5f61..bfca867 100644 --- a/infra/ecs_rstudio.tf +++ b/infra/ecs_rstudio.tf @@ -16,6 +16,9 @@ resource "aws_ecs_task_definition" "rstudio" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:${data.external.rstudio_metrics_current_tag.result.tag}" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:${data.external.rstudio_s3sync_current_tag.result.tag}" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/rstudio" } ) diff --git a/infra/ecs_rstudio_rv4.tf b/infra/ecs_rstudio_rv4.tf index bafe308..69265c7 100644 --- a/infra/ecs_rstudio_rv4.tf +++ b/infra/ecs_rstudio_rv4.tf @@ -16,6 +16,9 @@ resource "aws_ecs_task_definition" "rstudio_rv4" { metrics_container_image = "${aws_ecr_repository.metrics.repository_url}:master" s3sync_container_image = "${aws_ecr_repository.s3sync.repository_url}:master" + cloudwatch_namespace = "${var.cloudwatch_namespace}" + cloudwatch_region = "${var.cloudwatch_region}" + home_directory = "/home/rstudio" } ) diff --git a/infra/main.tf b/infra/main.tf index b9290e9..8283cd7 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -23,6 +23,12 @@ variable "ip_whitelist" { variable "prefix" {} variable "prefix_short" {} variable "prefix_underscore" {} +variable "cloudwatch_namespace" { + default = "DataWorkspace" +} +variable "cloudwatch_region" { + default = "eu-west-2" +} variable "vpc_cidr" {} variable "subnets_num_bits" {}