Skip to content

Commit

Permalink
feat: EKS config rendering pipeline + Service Catalog template update
Browse files Browse the repository at this point in the history
- Add eks_config.py with Pydantic models mirroring terraform-eks-deployment
- Add 8 Jinja2 templates (root.hcl, account.hcl, region.hcl, vpc.hcl,
  cluster.hcl, common-variables.hcl, default-versions.hcl, README.md)
- Add write_files_atomic() to github_provider.py using Git tree API
  for single-commit multi-file writes
- Update app.py with EKS detection (is_eks_deployment) and dual-path
  handler: EKS renders all 8 Terragrunt files atomically; legacy path
  writes single config.json
- Fix PascalCase→snake_case normalizer to handle acronyms (AWS, VPC)
  and compound words (FinOps) correctly
- Update product-template.yaml with all EKS parameters (ClusterName,
  AccountName, AWSAccountId, VpcName, VpcDomainName, etc.)
- Fix Pydantic v1 compatibility (class Config, .dict() instead of v2)"
  • Loading branch information
Your Name committed Feb 20, 2026
1 parent a4410a0 commit 2d595ca
Show file tree
Hide file tree
Showing 13 changed files with 1,150 additions and 37 deletions.
143 changes: 123 additions & 20 deletions service-catalog/product-template.yaml
Original file line number Diff line number Diff line change
@@ -1,36 +1,66 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Service Catalog Product: Create GitHub Repository from Template'
Description: 'Service Catalog Product: Create EKS Cluster GitHub Repository from Template'

Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Repository Configuration"
default: "Cluster Configuration"
Parameters:
- ProjectName
- OwningTeam
- Label:
default: "Environment Settings"
Parameters:
- ClusterName
- Environment
- AwsRegion
- Label:
default: "Optional Metadata"
default: "Account Configuration"
Parameters:
- AccountName
- AWSAccountId
- EnvironmentAbbr
- Label:
default: "VPC Configuration"
Parameters:
- VpcName
- VpcDomainName
- Label:
default: "Contact & Organization"
Parameters:
- OwningTeam
- ClusterMailingList
- OrganizationPath
- Label:
default: "FinOps"
Parameters:
- FinOpsProjectName
- FinOpsProjectNumber
- Label:
default: "Optional Metadata"
Parameters:
- AdditionalTags

ParameterLabels:
ProjectName:
default: "Repository Name"
ClusterName:
default: "EKS Cluster Name"
OwningTeam:
default: "Owning Team"
Environment:
default: "Environment"
AwsRegion:
default: "AWS Region"
AccountName:
default: "AWS Account Name"
AWSAccountId:
default: "AWS Account ID"
EnvironmentAbbr:
default: "Environment Abbreviation"
VpcName:
default: "VPC Name"
VpcDomainName:
default: "VPC Domain Name"
ClusterMailingList:
default: "Cluster Mailing List"
OrganizationPath:
default: "Organization Path"
FinOpsProjectName:
Expand All @@ -43,12 +73,21 @@ Metadata:
Parameters:
ProjectName:
Type: String
Description: Name of the GitHub repository to create (lowercase, hyphens only)
Description: >-
Name of the GitHub repository to create (lowercase, hyphens only).
If ClusterName is left blank this also becomes the EKS cluster name.
AllowedPattern: '^[a-z0-9][a-z0-9-]*[a-z0-9]$'
ConstraintDescription: Must be lowercase letters, numbers, and hyphens only
MinLength: 3
MaxLength: 100

ClusterName:
Type: String
Description: >-
EKS cluster name. Defaults to ProjectName if left blank.
Default: ""
MaxLength: 63

OwningTeam:
Type: String
Description: GitHub team that should have admin access to the repository
Expand All @@ -57,29 +96,63 @@ Parameters:

Environment:
Type: String
Description: Environment for this repository/project
Default: development
Description: Deployment environment
Default: dev
AllowedValues:
- development
- staging
- production
- sandbox
- dev
- test
- prod

AwsRegion:
Type: String
Description: Primary AWS region for this project
Description: Primary AWS region for this EKS cluster
Default: us-gov-west-1
AllowedValues:
- us-gov-west-1
- us-gov-east-1
- us-east-1
- us-west-2

OrganizationPath:
AccountName:
Type: String
Description: "AWS account name (e.g., csvd-dev-ew)"
AllowedPattern: '^[a-z0-9-]+$'
ConstraintDescription: Must contain only lowercase letters, numbers, and hyphens

AWSAccountId:
Type: String
Description: "AWS Account ID (12 digits)"
AllowedPattern: '^\d{12}$'
ConstraintDescription: Must be a valid 12-digit AWS Account ID

EnvironmentAbbr:
Type: String
Description: "Environment abbreviation (e.g., dev, prod)"
AllowedPattern: '^[a-z]+$'
MaxLength: 10

VpcName:
Type: String
Description: "Name of the VPC for the cluster"
AllowedPattern: '^[a-z0-9-]+$'
ConstraintDescription: Must contain only lowercase letters, numbers, and hyphens

VpcDomainName:
Type: String
Description: "VPC domain name (e.g., dev.inf.csp1.census.gov)"
AllowedPattern: '^[a-z0-9.-]+$'
ConstraintDescription: Must be a valid domain name

ClusterMailingList:
Type: String
Description: Organization path (e.g., dept:team:subteam)
Description: Email address for cluster notifications
Default: ""

OrganizationPath:
Type: String
Description: "Organization path (e.g., census:ocio:csvd)"
Default: "census:ocio:csvd"

FinOpsProjectName:
Type: String
Description: FinOps project name for cost allocation
Expand All @@ -92,7 +165,7 @@ Parameters:

AdditionalTags:
Type: String
Description: Additional tags as JSON object (e.g., {"key1":"value1","key2":"value2"})
Description: 'Additional tags as JSON object (e.g., {"key1":"value1"})'
Default: "{}"

# Hidden parameter - the Lambda ARN is passed in from the Service Catalog product definition
Expand All @@ -101,17 +174,38 @@ Parameters:
Description: ARN of the Lambda function that creates repositories
Default: "arn:aws-us-gov:lambda:us-gov-west-1:229685449397:function:service-catalog-repo-gen-template-automation"

Conditions:
ClusterNameProvided: !Not
- !Equals
- !Ref ClusterName
- ""

Resources:
# Custom Resource that invokes the Lambda function
# NOTE: Property names use snake_case to match Pydantic model field names.
# The Lambda normalizer converts PascalCase→snake_case but mishandles
# acronyms (e.g. AWSAccountId → a_w_s_account_id), so we pass snake_case
# directly to avoid ambiguity.
RepositoryCreator:
Type: Custom::GitHubRepository
Properties:
ServiceToken: !Ref LambdaFunctionArn
# These properties are passed to the Lambda function
# Core repo parameters
project_name: !Ref ProjectName
owning_team: !Ref OwningTeam
# EKS-specific parameters – these trigger the EKS rendering path in the Lambda
cluster_name: !If
- ClusterNameProvided
- !Ref ClusterName
- !Ref ProjectName
environment: !Ref Environment
aws_region: !Ref AwsRegion
account_name: !Ref AccountName
aws_account_id: !Ref AWSAccountId
environment_abbr: !Ref EnvironmentAbbr
vpc_name: !Ref VpcName
vpc_domain_name: !Ref VpcDomainName
cluster_mailing_list: !Ref ClusterMailingList
organization_path: !Ref OrganizationPath
finops_project_name: !Ref FinOpsProjectName
finops_project_number: !Ref FinOpsProjectNumber
Expand Down Expand Up @@ -142,6 +236,15 @@ Outputs:
Export:
Name: !Sub '${AWS::StackName}-ConfigBranch'

ClusterName:
Description: EKS cluster name
Value: !If
- ClusterNameProvided
- !Ref ClusterName
- !Ref ProjectName

Message:
Description: Status message
Value: !Sub 'Successfully created repository ${ProjectName} and opened configuration pull request. Review and merge the PR to complete setup.'
Value: !Sub >-
Successfully created repository ${ProjectName} with EKS cluster
configuration. Review and merge the PR to complete setup.
Loading

0 comments on commit 2d595ca

Please sign in to comment.