From e76058b8554e109c74d000e077fbae40e2d637c3 Mon Sep 17 00:00:00 2001 From: joneszc Date: Tue, 22 Oct 2024 14:42:56 -0400 Subject: [PATCH 1/9] Add config option (amazon_web_services.eks_kms_arn) to specify KMS-key ARN to encrypt EKS cluster secrets --- .../provider/cloud/amazon_web_services.py | 24 +++++++++++++ src/_nebari/stages/infrastructure/__init__.py | 34 +++++++++++++++++++ .../infrastructure/template/aws/main.tf | 1 + .../template/aws/modules/kubernetes/main.tf | 12 +++++++ .../template/aws/modules/kubernetes/policy.tf | 27 +++++++++++++++ .../aws/modules/kubernetes/variables.tf | 6 ++++ .../infrastructure/template/aws/variables.tf | 6 ++++ 7 files changed, 110 insertions(+) diff --git a/src/_nebari/provider/cloud/amazon_web_services.py b/src/_nebari/provider/cloud/amazon_web_services.py index 1123c07fe0..3a491c8b26 100644 --- a/src/_nebari/provider/cloud/amazon_web_services.py +++ b/src/_nebari/provider/cloud/amazon_web_services.py @@ -121,6 +121,30 @@ def instances(region: str) -> Dict[str, str]: return {t: t for t in instance_types} +@functools.lru_cache() +def kms_key_arns(region: str) -> Dict[str, dict]: + """Return dict of available/enabled KMS key IDs and associated KeyMetadata for the AWS region.""" + session = aws_session(region=region) + client = session.client("kms") + paginator = client.get_paginator("list_keys") + fields = [ + "Arn", + "KeyUsage", + "KeySpec", + # "KeyState", + # "Origin", + # "KeyManager", + # "EncryptionAlgorithms", + # "MultiRegion", + ] + kms_keys = [ + client.describe_key(KeyId=j["KeyId"]).get("KeyMetadata") + for i in paginator.paginate() + for j in i["Keys"] + ] + return {i["KeyId"]: {k: i[k] for k in fields} for i in kms_keys if i["Enabled"]} + + def aws_get_vpc_id(name: str, namespace: str, region: str) -> Optional[str]: """Return VPC ID for the EKS cluster namedd `{name}-{namespace}`.""" cluster_name = f"{name}-{namespace}" diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index 3e77f9bee8..d64fadcea0 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -182,6 +182,7 @@ class AWSInputVars(schema.Base): eks_endpoint_access: Optional[ Literal["private", "public", "public_and_private"] ] = "public" + eks_kms_arn: Optional[str] = None node_groups: List[AWSNodeGroupInputVars] availability_zones: List[str] vpc_cidr_block: str @@ -498,6 +499,7 @@ class AmazonWebServicesProvider(schema.Base): eks_endpoint_access: Optional[ Literal["private", "public", "public_and_private"] ] = "public" + eks_kms_arn: Optional[str] = None existing_subnet_ids: Optional[List[str]] = None existing_security_group_id: Optional[str] = None vpc_cidr_block: str = "10.10.0.0/16" @@ -554,6 +556,37 @@ def _check_input(cls, data: Any) -> Any: f"Amazon Web Services instance {node_group.instance} not one of available instance types={available_instances}" ) + # check if kms key is valid + available_kms_keys = amazon_web_services.kms_key_arns(data["region"]) + if "eks_kms_arn" in data and data["eks_kms_arn"] is not None: + key_id = [ + id for id in available_kms_keys.keys() if id in data["eks_kms_arn"] + ] + if ( + len(key_id) == 1 + and available_kms_keys[key_id[0]]["Arn"] == data["eks_kms_arn"] + ): + key_id = key_id[0] + # Symmetric KMS keys with Encrypt and decrypt key-usage have the SYMMETRIC_DEFAULT key-spec + # EKS cluster encryption requires a Symmetric key that is set to encrypt and decrypt data + if available_kms_keys[key_id]["KeySpec"] != "SYMMETRIC_DEFAULT": + if available_kms_keys[key_id]["KeyUsage"] == "GENERATE_VERIFY_MAC": + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} does not have KeyUsage set to 'Encrypt and decrypt' data" + ) + elif available_kms_keys[key_id]["KeyUsage"] != "ENCRYPT_DECRYPT": + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric, and KeyUsage not set to 'Encrypt and decrypt' data" + ) + else: + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric" + ) + else: + raise ValueError( + f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v['Arn'] for v in available_kms_keys.values()]}" + ) + return data @@ -843,6 +876,7 @@ def input_vars(self, stage_outputs: Dict[str, Dict[str, Any]]): name=self.config.escaped_project_name, environment=self.config.namespace, eks_endpoint_access=self.config.amazon_web_services.eks_endpoint_access, + eks_kms_arn=self.config.amazon_web_services.eks_kms_arn, existing_subnet_ids=self.config.amazon_web_services.existing_subnet_ids, existing_security_group_id=self.config.amazon_web_services.existing_security_group_id, region=self.config.amazon_web_services.region, diff --git a/src/_nebari/stages/infrastructure/template/aws/main.tf b/src/_nebari/stages/infrastructure/template/aws/main.tf index feffd35291..ec0cbb6606 100644 --- a/src/_nebari/stages/infrastructure/template/aws/main.tf +++ b/src/_nebari/stages/infrastructure/template/aws/main.tf @@ -99,6 +99,7 @@ module "kubernetes" { endpoint_public_access = var.eks_endpoint_access == "private" ? false : true endpoint_private_access = var.eks_endpoint_access == "public" ? false : true + eks_kms_arn = var.eks_kms_arn public_access_cidrs = var.eks_public_access_cidrs permissions_boundary = var.permissions_boundary } diff --git a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/main.tf b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/main.tf index 5b66201f83..1f3e688e68 100644 --- a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/main.tf +++ b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/main.tf @@ -14,8 +14,20 @@ resource "aws_eks_cluster" "main" { public_access_cidrs = var.public_access_cidrs } + # Only set encryption_config if eks_kms_arn is not null + dynamic "encryption_config" { + for_each = var.eks_kms_arn != null ? [1] : [] + content { + provider { + key_arn = var.eks_kms_arn + } + resources = ["secrets"] + } + } + depends_on = [ aws_iam_role_policy_attachment.cluster-policy, + aws_iam_role_policy_attachment.cluster_encryption, ] tags = merge({ Name = var.name }, var.tags) diff --git a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/policy.tf b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/policy.tf index 6916bc6532..d72b64edaa 100644 --- a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/policy.tf +++ b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/policy.tf @@ -32,6 +32,33 @@ resource "aws_iam_role_policy_attachment" "cluster-policy" { role = aws_iam_role.cluster.name } +data "aws_iam_policy_document" "cluster_encryption" { + count = var.eks_kms_arn != null ? 1 : 0 + statement { + actions = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ListGrants", + "kms:DescribeKey" + ] + resources = [var.eks_kms_arn] + } +} + +resource "aws_iam_policy" "cluster_encryption" { + count = var.eks_kms_arn != null ? 1 : 0 + name = "${var.name}-eks-encryption-policy" + description = "IAM policy for EKS cluster encryption" + policy = data.aws_iam_policy_document.cluster_encryption[count.index].json +} + +# Grant the EKS Cluster role KMS permissions if a key-arn is specified +resource "aws_iam_role_policy_attachment" "cluster_encryption" { + count = var.eks_kms_arn != null ? 1 : 0 + policy_arn = aws_iam_policy.cluster_encryption[count.index].arn + role = aws_iam_role.cluster.name +} + # ======================================================= # Kubernetes Node Group Policies # ======================================================= diff --git a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/variables.tf b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/variables.tf index 4d38d10a19..63558e550f 100644 --- a/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/variables.tf +++ b/src/_nebari/stages/infrastructure/template/aws/modules/kubernetes/variables.tf @@ -72,6 +72,12 @@ variable "endpoint_private_access" { default = false } +variable "eks_kms_arn" { + description = "kms key arn for EKS cluster encryption_config" + type = string + default = null +} + variable "public_access_cidrs" { type = list(string) default = ["0.0.0.0/0"] diff --git a/src/_nebari/stages/infrastructure/template/aws/variables.tf b/src/_nebari/stages/infrastructure/template/aws/variables.tf index a3f37b9eb9..a71df81d0f 100644 --- a/src/_nebari/stages/infrastructure/template/aws/variables.tf +++ b/src/_nebari/stages/infrastructure/template/aws/variables.tf @@ -69,6 +69,12 @@ variable "eks_endpoint_private_access" { default = false } +variable "eks_kms_arn" { + description = "kms key arn for EKS cluster encryption_config" + type = string + default = null +} + variable "eks_public_access_cidrs" { type = list(string) default = ["0.0.0.0/0"] From 36518be461c455fc2d1f17744b496e7762bd5c2c Mon Sep 17 00:00:00 2001 From: joneszc Date: Thu, 24 Oct 2024 09:50:54 -0400 Subject: [PATCH 2/9] add aws kms_key_arns mock values to the pytest fixture --- tests/tests_unit/conftest.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/tests_unit/conftest.py b/tests/tests_unit/conftest.py index ce60e44799..863993bb7b 100644 --- a/tests/tests_unit/conftest.py +++ b/tests/tests_unit/conftest.py @@ -56,6 +56,18 @@ def _mock_return_value(return_value): "m5.xlarge": "m5.xlarge", "m5.2xlarge": "m5.2xlarge", }, + "_nebari.provider.cloud.amazon_web_services.kms_key_arns": { + "xxxxxxxx-east-zzzz": { + "Arn": "arn:aws:kms:us-east-1:100000:key/xxxxxxxx-east-zzzz", + "KeyUsage": "ENCRYPT_DECRYPT", + "KeySpec": "SYMMETRIC_DEFAULT", + }, + "xxxxxxxx-west-zzzz": { + "Arn": "arn:aws:kms:us-west-2:100000:key/xxxxxxxx-west-zzzz", + "KeyUsage": "ENCRYPT_DECRYPT", + "KeySpec": "SYMMETRIC_DEFAULT", + }, + }, # Azure "_nebari.provider.cloud.azure_cloud.kubernetes_versions": [ "1.18", From 567a05d1808822a4a40a08bab6a0af24a1e51588 Mon Sep 17 00:00:00 2001 From: joneszc Date: Thu, 24 Oct 2024 11:56:10 -0400 Subject: [PATCH 3/9] add comments linking boto3 docs for kms_key_arns function --- src/_nebari/provider/cloud/amazon_web_services.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/_nebari/provider/cloud/amazon_web_services.py b/src/_nebari/provider/cloud/amazon_web_services.py index 3a491c8b26..a27825ba3d 100644 --- a/src/_nebari/provider/cloud/amazon_web_services.py +++ b/src/_nebari/provider/cloud/amazon_web_services.py @@ -126,16 +126,13 @@ def kms_key_arns(region: str) -> Dict[str, dict]: """Return dict of available/enabled KMS key IDs and associated KeyMetadata for the AWS region.""" session = aws_session(region=region) client = session.client("kms") + # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/list_keys.html paginator = client.get_paginator("list_keys") fields = [ "Arn", "KeyUsage", "KeySpec", - # "KeyState", - # "Origin", - # "KeyManager", - # "EncryptionAlgorithms", - # "MultiRegion", + # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/describe_key.html#:~:text=Response%20Structure ] kms_keys = [ client.describe_key(KeyId=j["KeyId"]).get("KeyMetadata") From a4d89cb4ca49031788005a568ce5e092012a7d06 Mon Sep 17 00:00:00 2001 From: joneszc Date: Fri, 25 Oct 2024 17:00:23 -0400 Subject: [PATCH 4/9] make kms_key_arns function more readable --- .../provider/cloud/amazon_web_services.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/_nebari/provider/cloud/amazon_web_services.py b/src/_nebari/provider/cloud/amazon_web_services.py index a27825ba3d..502b981e4f 100644 --- a/src/_nebari/provider/cloud/amazon_web_services.py +++ b/src/_nebari/provider/cloud/amazon_web_services.py @@ -126,20 +126,20 @@ def kms_key_arns(region: str) -> Dict[str, dict]: """Return dict of available/enabled KMS key IDs and associated KeyMetadata for the AWS region.""" session = aws_session(region=region) client = session.client("kms") + kms_keys = {} # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/list_keys.html - paginator = client.get_paginator("list_keys") - fields = [ - "Arn", - "KeyUsage", - "KeySpec", + for key in client.list_keys().get("Keys"): + key_id = key["KeyId"] # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/describe_key.html#:~:text=Response%20Structure - ] - kms_keys = [ - client.describe_key(KeyId=j["KeyId"]).get("KeyMetadata") - for i in paginator.paginate() - for j in i["Keys"] - ] - return {i["KeyId"]: {k: i[k] for k in fields} for i in kms_keys if i["Enabled"]} + key_data = client.describe_key(KeyId=key_id).get("KeyMetadata") + if key_data.get("Enabled"): + kms_keys[key_id] = { + "Arn": key_data.get("Arn"), + "KeyUsage": key_data.get("KeyUsage"), + "KeySpec": key_data.get("KeySpec"), + "KeyManager": key_data.get("KeyManager"), + } + return kms_keys def aws_get_vpc_id(name: str, namespace: str, region: str) -> Optional[str]: From c3cc413785137adf7b0472db9b3b82ed934278f0 Mon Sep 17 00:00:00 2001 From: joneszc Date: Mon, 28 Oct 2024 10:06:10 -0400 Subject: [PATCH 5/9] refactor validation conditionals of aws kms key for eks and add check for customer-managed key --- src/_nebari/stages/infrastructure/__init__.py | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index d64fadcea0..8866505a18 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -562,30 +562,35 @@ def _check_input(cls, data: Any) -> Any: key_id = [ id for id in available_kms_keys.keys() if id in data["eks_kms_arn"] ] + # Raise error if key_id is not found in available_kms_keys if ( - len(key_id) == 1 - and available_kms_keys[key_id[0]]["Arn"] == data["eks_kms_arn"] + len(key_id) != 1 + or available_kms_keys[key_id[0]]["Arn"] != data["eks_kms_arn"] ): - key_id = key_id[0] - # Symmetric KMS keys with Encrypt and decrypt key-usage have the SYMMETRIC_DEFAULT key-spec - # EKS cluster encryption requires a Symmetric key that is set to encrypt and decrypt data - if available_kms_keys[key_id]["KeySpec"] != "SYMMETRIC_DEFAULT": - if available_kms_keys[key_id]["KeyUsage"] == "GENERATE_VERIFY_MAC": - raise ValueError( - f"Amazon Web Services KMS Key with ID {key_id} does not have KeyUsage set to 'Encrypt and decrypt' data" - ) - elif available_kms_keys[key_id]["KeyUsage"] != "ENCRYPT_DECRYPT": - raise ValueError( - f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric, and KeyUsage not set to 'Encrypt and decrypt' data" - ) - else: - raise ValueError( - f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric" - ) - else: raise ValueError( f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v['Arn'] for v in available_kms_keys.values()]}" ) + key_id = key_id[0] + # Raise error if key is not a customer managed key + if available_kms_keys[key_id]["KeyManager"] != "CUSTOMER": + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} is not a customer managed key" + ) + # Symmetric KMS keys with Encrypt and decrypt key-usage have the SYMMETRIC_DEFAULT key-spec + # EKS cluster encryption requires a Symmetric key that is set to encrypt and decrypt data + if available_kms_keys[key_id]["KeySpec"] != "SYMMETRIC_DEFAULT": + if available_kms_keys[key_id]["KeyUsage"] == "GENERATE_VERIFY_MAC": + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} does not have KeyUsage set to 'Encrypt and decrypt' data" + ) + elif available_kms_keys[key_id]["KeyUsage"] != "ENCRYPT_DECRYPT": + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric, and KeyUsage not set to 'Encrypt and decrypt' data" + ) + else: + raise ValueError( + f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric" + ) return data From b204146e888db1508c5a07329d2f4945a96f35f5 Mon Sep 17 00:00:00 2001 From: joneszc Date: Mon, 28 Oct 2024 11:12:00 -0400 Subject: [PATCH 6/9] edit value error message on added check for customer-managed aws kms key --- src/_nebari/stages/infrastructure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index 8866505a18..d9cd8a4e80 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -568,7 +568,7 @@ def _check_input(cls, data: Any) -> Any: or available_kms_keys[key_id[0]]["Arn"] != data["eks_kms_arn"] ): raise ValueError( - f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v['Arn'] for v in available_kms_keys.values()]}" + f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v['Arn'] for v in available_kms_keys.values() if v['KeyManager']=='CUSTOMER']}" ) key_id = key_id[0] # Raise error if key is not a customer managed key From 8569dbe783ab2ae2f6055ed6402d32bd313c81d1 Mon Sep 17 00:00:00 2001 From: joneszc Date: Thu, 31 Oct 2024 14:28:45 -0400 Subject: [PATCH 7/9] replace dict with dataclass schema in aws kms_key_arns function --- .../provider/cloud/amazon_web_services.py | 22 +++++++++++++------ src/_nebari/stages/infrastructure/__init__.py | 12 +++++----- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/_nebari/provider/cloud/amazon_web_services.py b/src/_nebari/provider/cloud/amazon_web_services.py index 502b981e4f..8241d06840 100644 --- a/src/_nebari/provider/cloud/amazon_web_services.py +++ b/src/_nebari/provider/cloud/amazon_web_services.py @@ -3,6 +3,7 @@ import re import time from typing import Dict, List, Optional +from dataclasses import dataclass import boto3 from botocore.exceptions import ClientError, EndpointConnectionError @@ -121,8 +122,15 @@ def instances(region: str) -> Dict[str, str]: return {t: t for t in instance_types} +@dataclass +class Kms_Key_Info: + Arn: str + KeyUsage: str + KeySpec: str + KeyManager: str + @functools.lru_cache() -def kms_key_arns(region: str) -> Dict[str, dict]: +def kms_key_arns(region: str) -> Dict[str, Kms_Key_Info]: """Return dict of available/enabled KMS key IDs and associated KeyMetadata for the AWS region.""" session = aws_session(region=region) client = session.client("kms") @@ -133,12 +141,12 @@ def kms_key_arns(region: str) -> Dict[str, dict]: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/describe_key.html#:~:text=Response%20Structure key_data = client.describe_key(KeyId=key_id).get("KeyMetadata") if key_data.get("Enabled"): - kms_keys[key_id] = { - "Arn": key_data.get("Arn"), - "KeyUsage": key_data.get("KeyUsage"), - "KeySpec": key_data.get("KeySpec"), - "KeyManager": key_data.get("KeyManager"), - } + kms_keys[key_id] = Kms_Key_Info( + Arn=key_data.get("Arn"), + KeyUsage=key_data.get("KeyUsage"), + KeySpec=key_data.get("KeySpec"), + KeyManager=key_data.get("KeyManager"), + ) return kms_keys diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index d29ebcaac0..176d77e3ca 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -557,25 +557,25 @@ def _check_input(cls, data: Any) -> Any: # Raise error if key_id is not found in available_kms_keys if ( len(key_id) != 1 - or available_kms_keys[key_id[0]]["Arn"] != data["eks_kms_arn"] + or available_kms_keys[key_id[0]].Arn != data["eks_kms_arn"] ): raise ValueError( - f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v['Arn'] for v in available_kms_keys.values() if v['KeyManager']=='CUSTOMER']}" + f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v.Arn for v in available_kms_keys.values() if v.KeyManager=='CUSTOMER']}" ) key_id = key_id[0] # Raise error if key is not a customer managed key - if available_kms_keys[key_id]["KeyManager"] != "CUSTOMER": + if available_kms_keys[key_id].KeyManager != "CUSTOMER": raise ValueError( f"Amazon Web Services KMS Key with ID {key_id} is not a customer managed key" ) # Symmetric KMS keys with Encrypt and decrypt key-usage have the SYMMETRIC_DEFAULT key-spec # EKS cluster encryption requires a Symmetric key that is set to encrypt and decrypt data - if available_kms_keys[key_id]["KeySpec"] != "SYMMETRIC_DEFAULT": - if available_kms_keys[key_id]["KeyUsage"] == "GENERATE_VERIFY_MAC": + if available_kms_keys[key_id].KeySpec != "SYMMETRIC_DEFAULT": + if available_kms_keys[key_id].KeyUsage == "GENERATE_VERIFY_MAC": raise ValueError( f"Amazon Web Services KMS Key with ID {key_id} does not have KeyUsage set to 'Encrypt and decrypt' data" ) - elif available_kms_keys[key_id]["KeyUsage"] != "ENCRYPT_DECRYPT": + elif available_kms_keys[key_id].KeyUsage != "ENCRYPT_DECRYPT": raise ValueError( f"Amazon Web Services KMS Key with ID {key_id} is not of type Symmetric, and KeyUsage not set to 'Encrypt and decrypt' data" ) From 422f59db52c3f182fd77e587f71ff7302038f545 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:29:17 +0000 Subject: [PATCH 8/9] [pre-commit.ci] Apply automatic pre-commit fixes --- src/_nebari/provider/cloud/amazon_web_services.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_nebari/provider/cloud/amazon_web_services.py b/src/_nebari/provider/cloud/amazon_web_services.py index 8241d06840..68dfcb133c 100644 --- a/src/_nebari/provider/cloud/amazon_web_services.py +++ b/src/_nebari/provider/cloud/amazon_web_services.py @@ -2,8 +2,8 @@ import os import re import time -from typing import Dict, List, Optional from dataclasses import dataclass +from typing import Dict, List, Optional import boto3 from botocore.exceptions import ClientError, EndpointConnectionError @@ -129,6 +129,7 @@ class Kms_Key_Info: KeySpec: str KeyManager: str + @functools.lru_cache() def kms_key_arns(region: str) -> Dict[str, Kms_Key_Info]: """Return dict of available/enabled KMS key IDs and associated KeyMetadata for the AWS region.""" From 243e7643e626b7fded8fadea5f7b76c3122e109c Mon Sep 17 00:00:00 2001 From: joneszc Date: Thu, 31 Oct 2024 15:29:14 -0400 Subject: [PATCH 9/9] fix aws kms_key_arns validation --- src/_nebari/stages/infrastructure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_nebari/stages/infrastructure/__init__.py b/src/_nebari/stages/infrastructure/__init__.py index 176d77e3ca..b716bbd5d8 100644 --- a/src/_nebari/stages/infrastructure/__init__.py +++ b/src/_nebari/stages/infrastructure/__init__.py @@ -560,7 +560,7 @@ def _check_input(cls, data: Any) -> Any: or available_kms_keys[key_id[0]].Arn != data["eks_kms_arn"] ): raise ValueError( - f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v.Arn for v in available_kms_keys.values() if v.KeyManager=='CUSTOMER']}" + f"Amazon Web Services KMS Key with ARN {data['eks_kms_arn']} not one of available/enabled keys={[v.Arn for v in available_kms_keys.values() if v.KeyManager=='CUSTOMER' and v.KeySpec=='SYMMETRIC_DEFAULT']}" ) key_id = key_id[0] # Raise error if key is not a customer managed key