# Spicy Automation AWS CDK infrastructure and Jenkins shared library for Spicy automation. This replaces the legacy Ansible/CloudFormation approach with type-safe TypeScript and integrated Jenkins pipelines. ## Quick Start ### Minimal VPC Deployment Create a `Jenkinsfile` in your VPC repository: ```groovy @Library(["spicy-automation@main"]) _ spicyVPC( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-vpc", ownerTag: "MyTeam", productTag: "myproduct", componentTag: "vpc", ) ``` ### Minimal ECS Cluster Deployment - Using CloudFormation Imports **Minimal props:** Only `vpcStackName` and `numberOfAzs` required. VPC info auto-imports from VPC stack exports. ```groovy @Library(["spicy-automation@main"]) _ spicyECSCluster( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-ecs-cluster", vpcStackName: "my-vpc", // Auto-imports VPC ID, CIDR, subnets, and AZs numberOfAzs: 3, ownerTag: "MyTeam", productTag: "myproduct", componentTag: "ecs-cluster", environment: "dev" ) ``` **Explicit IDs (backward compatible):** ```groovy spicyECSCluster( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-ecs-cluster", vpcId: "vpc-12345678", vpcCidrBlock: "10.0.0.0/16", availabilityZones: "ca-central-1a,ca-central-1b,ca-central-1c", privateSubnetIds: "subnet-aaa,subnet-bbb,subnet-ccc", ownerTag: "MyTeam", productTag: "myproduct", componentTag: "ecs-cluster", environment: "dev" ) ``` ### ECS Service with Mixed Capacity (EC2 + Fargate Burst) - Minimal Props **Minimal props:** Only `clusterName` required. VPC info auto-imports from CloudFormation exports. ```groovy @Library(["spicy-automation@main"]) _ spicyECSService( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-api-dev", serviceName: "my-api", clusterName: "my-ecs-cluster", // VPC stack name and VPC ID auto-import from cluster stack exports image: "nexus.kodeniks.com/docker-hosted/my-api:latest", containerPort: 3000, capacityProviderStrategy: [ [capacityProvider: "my-ecs-cluster-ec2", base: 2, weight: 3], [capacityProvider: "FARGATE_SPOT", weight: 1], ], ownerTag: "MyTeam", productTag: "myproduct", componentTag: "api", environment: "dev" ) ``` **Explicit IDs (backward compatible):** ```groovy spicyECSService( // ... other params ... clusterName: "my-ecs-cluster", vpcId: "vpc-12345678", vpcCidrBlock: "10.0.0.0/16", availabilityZones: "ca-central-1a,ca-central-1b,ca-central-1c", privateSubnetIds: "subnet-aaa,subnet-bbb,subnet-ccc", ) ``` ### Blue/Green Deployment with Instant Rollback ```groovy @Library(["spicy-automation@main"]) _ spicyECSService( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-api-prod", serviceName: "my-api", clusterName: "my-ecs-cluster-prod", vpcId: "vpc-12345678", vpcCidrBlock: "10.0.0.0/16", availabilityZones: "ca-central-1a,ca-central-1b", privateSubnetIds: "subnet-aaa,subnet-bbb", image: "nexus.kodeniks.com/docker-hosted/my-api:latest", containerPort: 3000, // Enable Blue/Green blueGreen: true, activeHostname: "api.example.com", inactiveHostname: "inactive-api.example.com", // ALB routing - listener ARN auto-imports from ${clusterName}-internet-facing-https-listener priority: 100, useExternalALB: true, // externalListenerArn auto-imports when useExternalALB=true // Test before swap blueGreenTest: { args, buildInfo -> sh "curl -f https://${buildInfo.inactiveHostname}/health" }, // Test after swap smokeTest: { args, buildInfo -> sh "curl -f https://${buildInfo.activeHostname}/health" }, ownerTag: "Platform", productTag: "myproduct", componentTag: "api", environment: "prod" ) ``` ### Instant Rollback (30 seconds) ```groovy @Library(["spicy-automation@main"]) _ spicyRollback( jenkinsAwsCredentialsId: "aws-credentials", region: "ca-central-1", stackName: "my-api-prod", serviceName: "my-api", // ... same params as deploy ... ) ``` ## Documentation | Document | Description | | ------------------------------------------------------ | ---------------------------------------------- | | [VPC Guide](docs/VPC.md) | Complete VPC deployment guide with all options | | [ECS Cluster Guide](docs/ECS_CLUSTER.md) | ECS cluster with Spot, Capacity Providers | | [ECS Service Guide](docs/ECS_SERVICE.md) | ECS service with mixed EC2/Fargate strategy | | [Persistent ALB](docs/PERSISTENT_ALB.md) | Persistent ALB pattern (1:1 with service) | | [Cost Optimization](docs/COST_OPTIMIZATION_TESTING.md) | Cost optimization for testing environments | | [CDK Synth Examples](docs/CDK_SYNTH_EXAMPLES.md) | Complete CDK synth command examples | | [Jenkins Utilities](docs/JENKINS_UTILITIES.md) | All available Jenkins utility functions | | [Accounts Configuration](docs/ACCOUNTS.md) | Multi-account setup guide | | [Local Development](docs/DEVELOPMENT.md) | Running CDK locally | | [NPM Example](docs/JENKINSFILE_EXAMPLE_NPM.md) | Example Jenkinsfile for NPM publishing | ## Features ### Infrastructure (CDK) - **SpicyVpc**: Multi-AZ VPC with public/private subnets, NAT gateways, NACLs, VPC endpoints - **SpicyEcsCluster**: ECS cluster with EC2 Capacity Providers, Mixed Instances Policy for Spot, ALBs - **SpicyEcsService**: ECS service with mixed capacity strategy, auto-scaling, circuit breaker ### Blue/Green Deployments - **Zero-downtime releases** with hostname-based routing - **Instant rollback** (~30 seconds) via hostname swap - **Test before swap** with `blueGreenTest` hook - **Rollback window** - old version kept for 2+ hours ### Pipeline Hooks - **buildCommand**: Custom build logic - **onPostBuild**: Unit tests, linting, coverage - **onPreDeploy**: Setup, test preparation - **blueGreenTest**: Integration tests on inactive stack - **onPostDeploy**: Cleanup, notifications - **smokeTest**: Post-deployment verification ### Jenkins Pipelines - **spicyVPC**: Deploy VPCs - **spicyECSCluster**: Deploy ECS clusters with Spot support - **spicyECSService**: Deploy ECS services with EC2 + Fargate burst, blue/green - **spicyRollback**: Instant rollback for blue/green deployments - **buildAndPushDockerImage**: Build and push Docker images to Nexus ## Jenkins Setup ### 1. Configure Global Library In Jenkins → **Manage Jenkins** → **Configure System** → **Global Pipeline Libraries**: | Setting | Value | | ------------------ | ------------------------------------------------ | | Name | `spicy-automation` | | Default version | `main` | | Retrieval method | Modern SCM → Git | | Project Repository | `git@git.kodeniks.com:CORP/spicy-automation.git` | | Library Path | `jenkins/` | ### 2. Configure Credentials | Credential ID | Type | Description | | --------------------------- | ----------------- | --------------------------------- | | `aws-credentials` | Username/Password | AWS Access Key ID / Secret | | `kodeniks-gitea-token` | Secret text | Gitea personal access token | | `kodeniks-nexus-repository` | Username/Password | Nexus Docker registry credentials | ## Project Structure ``` spicy-automation/ ├── bin/spicy-cdk.ts # CDK app entry point ├── lib/ │ ├── constructs/ # Reusable CDK constructs │ │ ├── spicy-vpc.ts # VPC construct │ │ ├── spicy-ecs-cluster.ts # ECS cluster construct │ │ └── spicy-ecs-service.ts # ECS service construct │ └── stacks/ # CDK stacks │ ├── spicy-vpc-stack.ts │ ├── spicy-ecs-cluster-stack.ts │ └── spicy-ecs-service-stack.ts ├── vars/ # Jenkins shared library │ ├── spicyVPC.groovy # VPC pipeline │ ├── spicyECSCluster.groovy # ECS cluster pipeline │ ├── spicyECSService.groovy # ECS service pipeline │ ├── buildAndPushDockerImage.groovy # Docker build pipeline │ ├── cdkUtils.groovy # CDK commands │ ├── dockerUtils.groovy # Docker/Nexus utilities │ ├── gitUtils.groovy # Git utilities │ ├── giteaUtils.groovy # Commit status updates │ └── accounts.groovy # Account configurations ├── docs/ # Documentation ├── test/ # Jest tests └── Dockerfile # Jenkins agent image ``` ## Useful Commands ```bash # No build step required - runs directly with ts-node! npx cdk synth -c stackType=vpc -c stackName=my-vpc ... # Or use pnpm scripts pnpm run test # Run Jest tests pnpm run build # Compile TypeScript (optional) ``` ## Migration from spicy-automation-legacy | Feature | spicy-automation-legacy | spicy-automation | | --------------- | ----------------------- | ---------------- | | Infrastructure | CloudFormation YAML | TypeScript CDK | | Provisioning | Ansible | CDK CLI | | Testing | None | Jest | | Type Safety | None | Full TypeScript | | Docker Registry | AWS ECR | Nexus | CloudFormation outputs are identical, so existing stacks referencing VPC exports continue to work.