From ff2a6b50f0f3cc58cd857105bb71031def13644a Mon Sep 17 00:00:00 2001 From: Dave Arnold Date: Tue, 21 Apr 2026 16:13:25 -0400 Subject: [PATCH] fix(lambda): make EKS fields required; remove is_eks_deployment dead branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Lambda is EKS-only by design — the is_eks_deployment false-branch only ever raised a ValueError with no alternative path. Remove it in favour of Pydantic required fields, which surface missing fields with precise error messages at validation time. Required fields (was Optional): cluster_name, environment, aws_region, account_name, aws_account_id, environment_abbr, vpc_name, vpc_domain_name. Also simplifies start_codebuild_build() — 'or ""' fallbacks on required fields are no longer needed. --- template_automation/app.py | 62 ++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/template_automation/app.py b/template_automation/app.py index 53495b6..83d7b5b 100644 --- a/template_automation/app.py +++ b/template_automation/app.py @@ -37,40 +37,36 @@ # --------------------------------------------------------------------------- class CloudFormationResourceInput(BaseModel): - """Input validation model for CloudFormation Custom Resource parameters.""" + """Input validation model for CloudFormation Custom Resource parameters. + Required fields are enforced by Pydantic — a missing field produces a + clear ValidationError naming exactly which field(s) are absent. + """ + + # Core repo parameters project_name: str = Field(..., description="Name for the new repository") owning_team: Optional[str] = Field(default="tf-module-admins") - creator_username: Optional[str] = Field(default=None) - # EKS-specific fields — all five must be present for is_eks_deployment == True - cluster_name: Optional[str] = Field(default=None) - environment: Optional[str] = Field(default=None) - aws_region: Optional[str] = Field(default=None) - account_name: Optional[str] = Field(default=None) - aws_account_id: Optional[str] = Field(default=None) - environment_abbr: Optional[str] = Field(default=None) - vpc_name: Optional[str] = Field(default=None) - vpc_domain_name: Optional[str] = Field(default=None) + # Required EKS cluster fields + cluster_name: str = Field(..., description="EKS cluster name") + environment: str = Field(..., description="Deployment environment (dev/test/prod)") + aws_region: str = Field(..., description="AWS region (e.g. us-gov-west-1)") + account_name: str = Field(..., description="AWS account name (e.g. csvd-dev-ew)") + aws_account_id: str = Field(..., description="12-digit AWS account ID") + environment_abbr: str = Field(..., description="Environment abbreviation (e.g. dev)") + vpc_name: str = Field(..., description="VPC name for the cluster") + vpc_domain_name: str = Field(..., description="VPC domain name") + + # Optional fields cluster_mailing_list: Optional[str] = Field(default=None) organization_path: Optional[str] = Field(default=None) finops_project_name: Optional[str] = Field(default=None) finops_project_number: Optional[str] = Field(default=None) + creator_username: Optional[str] = Field(default=None) class Config: extra = "allow" - @property - def is_eks_deployment(self) -> bool: - """True when all required EKS fields are present.""" - return bool( - self.cluster_name - and self.account_name - and self.aws_account_id - and self.vpc_name - and self.vpc_domain_name - ) - # --------------------------------------------------------------------------- # Helpers @@ -146,11 +142,11 @@ def start_codebuild_build( cb = boto3.client("codebuild", region_name=region) cluster_config_json = json.dumps({ - "account_name": cfn_input.account_name or "", - "aws_account_id": cfn_input.aws_account_id or "", - "environment_abbr": cfn_input.environment_abbr or (cfn_input.environment or "dev"), - "vpc_name": cfn_input.vpc_name or "", - "vpc_domain_name": cfn_input.vpc_domain_name or "", + "account_name": cfn_input.account_name, + "aws_account_id": cfn_input.aws_account_id, + "environment_abbr": cfn_input.environment_abbr, + "vpc_name": cfn_input.vpc_name, + "vpc_domain_name": cfn_input.vpc_domain_name, "cluster_mailing_list": cfn_input.cluster_mailing_list or "", "organization": cfn_input.organization_path or "census:ocio:csvd", }) @@ -173,8 +169,8 @@ def start_codebuild_build( projectName=project_name, environmentVariablesOverride=[ {"name": "TF_VAR_name", "value": cfn_input.project_name, "type": "PLAINTEXT"}, - {"name": "TF_VAR_environment", "value": cfn_input.environment or "dev", "type": "PLAINTEXT"}, - {"name": "TF_VAR_region", "value": cfn_input.aws_region or region, "type": "PLAINTEXT"}, + {"name": "TF_VAR_environment", "value": cfn_input.environment, "type": "PLAINTEXT"}, + {"name": "TF_VAR_region", "value": cfn_input.aws_region, "type": "PLAINTEXT"}, {"name": "TF_VAR_cluster_config", "value": cluster_config_json, "type": "PLAINTEXT"}, {"name": "TF_VAR_finops", "value": finops_json, "type": "PLAINTEXT"}, {"name": "GITHUB_TOKEN", "value": github_token, "type": "PLAINTEXT"}, @@ -284,15 +280,9 @@ def lambda_handler(event: dict, context) -> dict: cfn_input = CloudFormationResourceInput(**normalized) logger.info( f"[{request_id}] project={cfn_input.project_name}, " - f"is_eks={cfn_input.is_eks_deployment}" + f"cluster={cfn_input.cluster_name}, account={cfn_input.account_name}" ) - if not cfn_input.is_eks_deployment: - raise ValueError( - "Missing required EKS fields: cluster_name, account_name, aws_account_id, " - "vpc_name, and vpc_domain_name must all be provided." - ) - # Fetch the PAT used by CodeBuild / Terraform GitHub provider. # TF_GITHUB_TOKEN_SECRET_NAME holds a ghp_ PAT; the standard # GITHUB_TOKEN_SECRET_NAME may hold a ghs_ App token which cannot