Skip to main content

Custom CI/CD Toolkit

An AI-powered deployment toolkit for AWS ECS — deploy any Dockerized app with a single command, with Claude Code as your built-in DevOps assistant.


What's Inside

Component Purpose
deployagent CLI tool to deploy Dockerized apps to AWS ECS Fargate
deployagent-mcp Claude Code MCP plugin — AI validates, diagnoses, and deploys via natural language

Table of Contents


How It Works

Your project + deploy.yaml
        ↓
Say "deploy the project" to Claude Code
        ↓
Claude asks: container name? port? tag? replicas? env vars?
        ↓
1. Validates Dockerfile + K8s manifests (static analysis)
2. Builds Docker image + pushes to ECR
3. Creates / updates ALB + target group (fixed public DNS)
4. Registers new ECS task definition (with env vars injected)
5. Creates or rolling-updates ECS service
6. Waits for service stability
7. Runs health check
8. Saves deploy snapshot to SQLite (for rollback)
        ↓
App URL: http://<alb-dns-name>

If the health check fails, it automatically rolls back to the last known-good state.


Prerequisites

  • Python 3.11+
  • Docker Desktop (must be running during deploy)
  • AWS account with IAM credentials
  • Claude Code VSCode extension (for MCP plugin)

Installation

git clone https://github.com/chiman45/Custom-CICD.git
cd Custom-CICD

pip install -e .

# Verify
deployagent --help

AWS credentials

Create a .env file in the project root (gitignored):

AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-east-1

Claude Code MCP Plugin

The MCP plugin lets Claude Code deploy, validate, and diagnose your app using natural language — no Bash scripts needed.

Setup

The plugin is pre-configured in .mcp.json. Just open the project in VSCode with the Claude Code extension installed and reload the window (Ctrl+Shift+P → Developer: Reload Window). You should see deployagent-validator listed under /mcp.

Available tools

What you say Tool Claude uses
"deploy the project" prepare_deploy → ask questions → update_deploy_config → deploy
"what's the status?" get_deploy_logs
"show me the logs" get_service_logs
"deployment failed / health check failing" get_ecs_diagnostics
"check my Dockerfile" validate_dockerfile
"check all files before deploy" pre_deploy_check
"fix this file" (after user approves) apply_fix

Deploy flow

When you say "deploy the project", Claude will:

  1. Call prepare_deploy — reads deploy.yaml and checks AWS for existing resources
  2. Ask you to confirm or change:
    • Container name and port
    • Docker image tag
    • Number of replicas
    • Environment variables
  3. Warn you if the ECS service already exists (rolling update) or if the ALB is missing (needs service recreation)
  4. Call deploy and stream live logs every 10–15 seconds until done
  5. Print the public App URL at the end

Auto-diagnosis

If a deployment fails, say "fix the deployment error" and Claude will call get_ecs_diagnostics to pull:

  • ECS service events and rollout state
  • Stopped task exit codes and crash reasons
  • Last 60 lines from CloudWatch Logs
  • ECR image existence check

Claude reads all of it and diagnoses the root cause automatically.


Configuration — deploy.yaml

service: my-app                   # label used for deploy history
region: us-east-1
cluster: my-cluster

image:
  repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app
  tag: latest                     # use git SHA for unique deploys
  dockerfile: ./Dockerfile
  build_context: .

ecs:
  service_name: my-app-service
  task_family: my-app-task
  container_name: my-app
  container_port: 8080            # port your app listens on inside the container
  cpu: 256                        # 256 = 0.25 vCPU
  memory: 512                     # MB
  desired_count: 1
  environment:                    # injected as ECS container env vars
    NODE_ENV: production
    PORT: "8080"
    # DATABASE_URL: postgres://...
    # Add your app's env vars here

alb:
  name: my-app-alb                # ALB name (created automatically if it doesn't exist)
  target_group_name: my-app-tg
  vpc_id: vpc-xxxxxxxxxxxxxxxxx   # your VPC ID
  subnets:
    - subnet-xxxxxxxxxxxxxxxxx
    - subnet-xxxxxxxxxxxxxxxxx
  security_groups:
    - sg-xxxxxxxxxxxxxxxxx
  listener_port: 80

health:
  endpoint: /health
  timeout: 30
  retries: 5

# Optional — remove if not using CloudFormation
# cloudformation:
#   stack_name: my-app-infra
#   template_file: ./infra/template.yaml
#   parameters:
#     Environment: production

Tip: Use git commit SHA as the tag so every deploy is unique:

# Linux/macOS
sed -i "s/tag: .*/tag: $(git rev-parse --short HEAD)/" deploy.yaml

# Windows PowerShell
(Get-Content deploy.yaml) -replace 'tag: .*', "tag: $(git rev-parse --short HEAD)" | Set-Content deploy.yaml

AWS Setup

Required IAM permissions

Your IAM user needs these permissions (AWS Console → IAM → Users → your user → Add inline policy):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecs:DescribeServices", "ecs:DescribeTaskDefinition", "ecs:ListTasks",
        "ecs:DescribeTasks", "ecs:RegisterTaskDefinition", "ecs:UpdateService",
        "ecs:CreateService", "ecs:DeleteService",
        "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability",
        "ecr:PutImage", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload", "ecr:DescribeImages", "ecr:DescribeRepositories",
        "elasticloadbalancing:DescribeLoadBalancers", "elasticloadbalancing:CreateLoadBalancer",
        "elasticloadbalancing:DescribeTargetGroups", "elasticloadbalancing:CreateTargetGroup",
        "elasticloadbalancing:DescribeListeners", "elasticloadbalancing:CreateListener",
        "elasticloadbalancing:ModifyListener",
        "logs:DescribeLogStreams", "logs:GetLogEvents", "logs:FilterLogEvents",
        "cloudformation:DescribeStacks", "cloudformation:CreateChangeSet",
        "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet",
        "iam:PassRole"
      ],
      "Resource": "*"
    }
  ]
}

One-time AWS resource creation

# Get your account ID
aws sts get-caller-identity --query Account --output text

# Create ECR repository
aws ecr create-repository --repository-name my-app --region us-east-1

# Create ECS cluster
aws ecs create-cluster --cluster-name my-cluster --region us-east-1

# Create ECS task execution role
aws iam create-role \
  --role-name ecsTaskExecutionRole \
  --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}'

aws iam attach-role-policy \
  --role-name ecsTaskExecutionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

# Create CloudWatch log group
aws logs create-log-group --log-group-name /ecs/my-app-task --region us-east-1

# Look up your VPC, subnet, and security group
aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query "Vpcs[0].VpcId" --output text
aws ec2 describe-subnets --filters Name=vpc-id,Values=<VPC_ID> --query "Subnets[*].SubnetId" --output text
aws ec2 describe-security-groups --filters Name=vpc-id,Values=<VPC_ID> Name=group-name,Values=default --query "SecurityGroups[0].GroupId" --output text

Paste those values into deploy.yaml under alb.vpc_id, alb.subnets, and alb.security_groups.


CLI Commands

You can also use the CLI directly (without Claude Code):

# Dry run — shows what will change, no AWS mutations
deployagent plan deploy.yaml

# Deploy (asks for confirmation)
deployagent apply deploy.yaml

# Deploy without prompt (CI/CD pipelines)
deployagent apply deploy.yaml --yes

# Live health check
deployagent status deploy.yaml

# View full deploy history
deployagent status deploy.yaml --history

# Roll back one deploy
deployagent rollback deploy.yaml

# Roll back two deploys
deployagent rollback deploy.yaml --steps 2

Troubleshooting

Error Fix
docker: error during connect Start Docker Desktop
LoadBalancerNotFound during plan ALB doesn't exist yet — it will be created on first deploy
AccessDeniedException on CloudWatch Add logs:DescribeLogStreams and logs:GetLogEvents to your IAM policy
Nothing to deploy Change the image tag — same tag = no change detected
MCP server not showing in /mcp Ctrl+Shift+P → Developer: Reload Window
Health check failing after deploy Say "fix the deployment error" — Claude will run diagnostics automatically
Task keeps crashing (exit=1) Check CloudWatch logs — say "show me the logs"
Service has no public URL ALB was not attached — delete the ECS service and redeploy

Credits

Built by chiman45


MIT License — chiman24100@iiitnr.edu.in

Metadata

Release files for chims-deployment 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chims-deployment 1.0.0
File Size Uploaded Provenance Actions
chims_deployment-1.0.0.tar.gz 47.7 kB Without provenance Details for chims_deployment-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chims-deployment 1.0.0
File Interpreter ABI Platform Actions
chims_deployment-1.0.0-py3-none-any.whl Python 3 none any Details for chims_deployment-1.0.0-py3-none-any.whl

Total release size: 99.4 kB

Release files / chims_deployment-1.0.0.tar.gz

Download URL chims_deployment-1.0.0.tar.gz
Size 47.7 kB
Tags Source
SHA-256 checksum
How to use checksums
0ea5a009257092ea9a2ade15660d967f7f7dbe5d891801c692595c33de853928
BLAKE2b-256 checksum
How to use checksums
3839d1c0874f8beef00a77029172bc6fa0c75ecf6fc52d8709c1dc7d13765288
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / chims_deployment-1.0.0-py3-none-any.whl

Download URL chims_deployment-1.0.0-py3-none-any.whl
Size 51.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
538092ec9d5c34b014c1622ac3336a5c22da841dba8a0980e28f8cc8871a5892
BLAKE2b-256 checksum
How to use checksums
078a6f4a7a65fc32375c649d9844028f1b96e29f47c74f5ab9c326b7a227e9ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Security for chims-deployment 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page