Initial commit: Spicy CDK automation framework
Jenkins shared library and CDK constructs for AWS infrastructure. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
279
resources/README.md
Normal file
279
resources/README.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user